mxm_wifiex: update to mxm5x17391.p3 release

Corresponding firmware version:
SDIO-UART W8987 Firmware version 16.92.21.p76.5
PCIE-UART W8997 Firmware version 16.92.21.p84.4
SDIO-UART W8997 Firmware version 16.92.21.p84.4
SDIO-UART IW416 Firmware version 16.92.21.p84.3
SDIO_UART IW612 Firmware version 18.99.1.p154.40
SDIO-UART W8801 Firmware version 14.92.36.p181
SDIO-UART W9098 Firmware version 17.92.1.p136.24
PCIE-UART W9098 Firmware version 17.92.1.p136.24

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
This commit is contained in:
Sherry Sun 2023-05-25 21:42:02 +08:00
parent a206d37a93
commit e0bf3a1310
36 changed files with 1756 additions and 50 deletions

View file

@ -52,9 +52,12 @@ CONFIG_PCIE9097=n
CONFIG_SD9098=y
CONFIG_USB9098=n
CONFIG_PCIE9098=y
CONFIG_SDNW62X=n
CONFIG_PCIENW62X=n
CONFIG_USBNW62X=n
CONFIG_SDIW62X=n
CONFIG_SDAW693=n
CONFIG_PCIEIW62X=n
CONFIG_USBIW62X=n
CONFIG_PCIEAW693=n
# Debug Option
@ -273,9 +276,13 @@ ifeq ($(CONFIG_SD9097),y)
CONFIG_SDIO=y
ccflags-y += -DSD9097
endif
ifeq ($(CONFIG_SDNW62X),y)
ifeq ($(CONFIG_SDIW62X),y)
CONFIG_SDIO=y
ccflags-y += -DSDNW62X
ccflags-y += -DSDIW62X
endif
ifeq ($(CONFIG_SDAW693),y)
CONFIG_SDIO=y
ccflags-y += -DSDAW693
endif
ifeq ($(CONFIG_SD9177),y)
CONFIG_SDIO=y
@ -309,9 +316,9 @@ ifeq ($(CONFIG_USB9097),y)
CONFIG_MUSB=y
ccflags-y += -DUSB9097
endif
ifeq ($(CONFIG_USBNW62X),y)
ifeq ($(CONFIG_USBIW62X),y)
CONFIG_MUSB=y
ccflags-y += -DUSBNW62X
ccflags-y += -DUSBIW62X
endif
ifeq ($(CONFIG_USB9098),y)
CONFIG_MUSB=y
@ -333,10 +340,16 @@ ifeq ($(CONFIG_PCIE9098),y)
CONFIG_PCIE=y
ccflags-y += -DPCIE9098
endif
ifeq ($(CONFIG_PCIENW62X),y)
ifeq ($(CONFIG_PCIEIW62X),y)
CONFIG_PCIE=y
ccflags-y += -DPCIENW62X
ccflags-y += -DPCIEIW62X
endif
#ifdef PCIEAW693_OPT
ifeq ($(CONFIG_PCIEAW693),y)
CONFIG_PCIE=y
ccflags-y += -DPCIEAW693
endif
#endif
ifeq ($(CONFIG_SDIO),y)
ccflags-y += -DSDIO
ccflags-y += -DSDIO_MMC

View file

@ -9,25 +9,57 @@
Goto source code directory wlan_src/.
make [clean] build
The driver and utility binaries can be found in ../bin_xxxx directory.
The driver code supports Linux kernel from 2.6.32 to 6.1.1
The driver code supports Linux kernel from 2.6.32 to 6.0.0.
2) FOR DRIVER INSTALL
#ifdef MULTI_CHIP
a) Copy firmware image to /lib/firmware/nxp/, copy wifi_mod_para.conf to /lib/firmware/nxp/.
b) Install WLAN driver
There are drv_mode, max_sta_bss, max_uap_bss etc. module parameters.
The bit settings of drv_mode are,
Bit 0 : STA
Bit 1 : uAP
#ifdef WIFI_DIRECT_SUPPORT
Bit 2 : WIFIDIRECT
#endif
#ifdef MPL_SUPPORT
Bit 3 : MPL
#endif
#ifdef NAN_SUPPORT
Bit 4 : NAN
#endif
#ifdef ADHOC_OVER_IP
max_sta_bss: Maximum number of STA BSS (default 1, max 18)
#else
#ifdef STA_MBSS_SUPPORT
max_sta_bss: Maximum number of STA BSS (default 1, max 2)
#else
max_sta_bss: Maximum number of STA BSS (default 1, max 1)
#endif
#endif
sta_name: Name of the STA interface (default: "mlan")
#ifdef UAP_MBSS_SUPPORT
max_uap_bss: Maximum number of uAP BSS (default 1, max 2)
#else
max_uap_bss: Maximum number of uAP BSS (default 1, max 1)
#endif
uap_name: Name of the uAP interface (default: "uap")
#ifdef WIFI_DIRECT_SUPPORT
max_wfd_bss: Maximum number of WIFIDIRECT BSS (default 1, max 1)
wfd_name: Name of the WIFIDIRECT interface (default: "wfd")
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
max_vir_bss: Number of Virtual interfaces (default 0)
#endif
#endif
#ifdef MPL_SUPPORT
max_mpl_bss: Number of MPL interfaces (defaut 1, max 1)
#endif
#ifdef NAN_SUPPORT
nan_name: Name of the NAN interface (default: "nan")
max_nan_bss: Number of NAN interfaces (default 1)
#endif
uap_oper_ctrl: uAP operation control when in-STA disconnect with ext-AP
0: default do nothing, 2: uAP stops and restarts automatically
For example, to install multi-chip driver,
@ -40,67 +72,493 @@
ifconfig uapX down
rmmod moal
rmmod mlan
#else
#ifdef USB // Section 1 USB
#ifdef UAP_STA_SUPPORT
#ifdef ORION
a) Copy firmware image usb8786_uapsta.bin | ... to /usr/lib/hotplug/firmware/nxp/
directory, create the directory if it doesn't exist.
#else
a) Copy firmware image usb8766_uapsta.bin | ... to /lib/firmware/nxp/ directory,
create the directory if it doesn't exist.
#endif
b) Install WLAN driver
There are drv_mode, max_sta_bss, max_uap_bss etc. module parameters.
The bit settings of drv_mode are,
Bit 0 : STA
Bit 1 : uAP
#ifdef WIFI_DIRECT_SUPPORT
Bit 2 : WIFIDIRECT
#endif
#ifdef MPL_SUPPORT
Bit 3 : MPL
#endif
#ifdef NAN_SUPPORT
Bit 4 : NAN
#endif
#ifdef ADHOC_OVER_IP
max_sta_bss: Maximum number of STA BSS (default 1, max 18)
#else
#ifdef STA_MBSS_SUPPORT
max_sta_bss: Maximum number of STA BSS (default 1, max 2)
#else
max_sta_bss: Maximum number of STA BSS (default 1, max 1)
#endif
#endif
sta_name: Name of the STA interface (default: "mlan")
#ifdef UAP_MBSS_SUPPORT
max_uap_bss: Maximum number of uAP BSS (default 1, max 2)
#else
max_uap_bss: Maximum number of uAP BSS (default 1, max 1)
#endif
uap_name: Name of the uAP interface (default: "uap")
#ifdef WIFI_DIRECT_SUPPORT
max_wfd_bss: Maximum number of WIFIDIRECT BSS (default 1, max 1)
wfd_name: Name of the WIFIDIRECT interface (default: "wfd")
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
max_vir_bss: Number of Virtual interfaces (default 0)
#endif
#endif
#ifdef MPL_SUPPORT
max_mpl_bss: Number of MPL interfaces (defaut 1, max 1)
#endif
#ifdef NAN_SUPPORT
nan_name: Name of the NAN interface (default: "nan")
max_nan_bss: Number of NAN interfaces (default 1)
#endif
uap_oper_ctrl: uAP operation control when in-STA disconnect with ext-AP
0: default do nothing, 2: uAP stops and restarts automatically
#ifdef USBXXX
For example, to install USB multi-chip driver,
insmod mlan.ko
insmod usbxxx.ko mod_para=nxp/wifi_mod_para.conf [drvdbg=0x7]
wifi_mod_para.conf is used to support multi-chips which has different load module parameters. It contains
the module parameters for different chips.
#else
For example, to install USB8766 driver,
insmod mlan.ko
insmod usb8766.ko [drv_mode=3] [fw_name=nxp/usb8766_uapsta.bin]
To load driver in STA only mode,
insmod mlan.ko
insmod usb8766.ko drv_mode=1 [fw_name=nxp/usb8766_uapsta.bin]
To load driver in uAP only mode,
insmod mlan.ko
insmod usb8766.ko drv_mode=2 [fw_name=nxp/usb8766_uapsta.bin]
#ifdef USB_FW_DNLD_ENH
To load driver with wifi downloader firmware support.
insmod mlan.ko
insmod usb8997.ko usb_fw_option=1 cal_data_cfg=...
#endif
#endif // USBXXX
To switch mode between STA only, uAP only and uAPSTA in run time,
echo drv_mode=1 > /proc/mwlan/adapterX/config // STA mode
echo drv_mode=2 > /proc/mwlan/adapterX/config // uAP mode
echo drv_mode=3 > /proc/mwlan/adapterX/config // uAPSTA mode
c) Uninstall WLAN driver,
ifconfig mlanX down
ifconfig uapX down
rmmod usbxxx
rmmod mlan
#else
#ifdef ORION
a) Copy firmware image usb8786.bin | ... to /usr/lib/hotplug/firmware/nxp/
directory, create the directory if it doesn't exist.
#else
a) Copy firmware image usb8766.bin | ... to /lib/firmware/nxp/ directory,
create the directory if it doesn't exist.
#endif
b) Install WLAN driver,
#ifdef USBXXX
For example, to install multi-chip driver,
insmod mlan.ko
insmod usbxxx.ko mod_para=nxp/wifi_mod_para.conf [drvdbg=0x7]
wifi_mod_para.conf is used to support multi chips which has different module parameters. It contains
the module parameters for different chips.
#else
For example, to install USB8766 driver,
insmod mlan.ko
insmod usb8766.ko [fw_name=nxp/usb8766.bin]
#endif //USBXXX
c) Uninstall WLAN driver,
ifconfig mlan0 down
rmmod usbxxx
rmmod mlan
#endif // UAP_STA_SUPPORT
#endif // End of section 1 USB
#ifdef SDIO // Section 2 SDIO
#ifdef UAP_STA_SUPPORT
#ifdef PXA9XX
a) Copy firmware image sd8787_uapsta.bin | sd8797_uapsta.bin | ... to
/system/etc/firmware/nxp/ directory, create the directory if it doesn't exist.
#else
a) Copy firmware image sd8787_uapsta.bin | sd8797_uapsta.bin | ... to
/lib/firmware/nxp/ directory, create the directory if it doesn't exist.
#endif
#ifdef SYSKT_MULTI
b) Install SDIO bus driver and WLAN driver,
./load sd8787 | sd8797 | ...
Update load script to specify drv_mode, max_sta_bss, max_uap_bss etc. parameters.
#else
b) Install WLAN driver,
There are drv_mode, max_sta_bss, max_uap_bss etc. module parameters.
#endif
The bit settings of drv_mode are,
Bit 0 : STA
Bit 1 : uAP
#ifdef WIFI_DIRECT_SUPPORT
Bit 2 : WIFIDIRECT
The default drv_mode is 7.
#else
The default drv_mode is 3.
#endif
#ifdef MPL_SUPPORT
Bit 3 : MPL
#endif
#ifdef NAN_SUPPORT
Bit 4 : NAN
#endif
#ifdef ADHOC_OVER_IP
max_sta_bss: Maximum number of STA BSS (default 1, max 18)
#else
#ifdef STA_MBSS_SUPPORT
max_sta_bss: Maximum number of STA BSS (default 1, max 2)
#else
max_sta_bss: Maximum number of STA BSS (default 1, max 1)
#endif
#endif
sta_name: Name of the STA interface (default: "mlan")
#ifdef UAP_MBSS_SUPPORT
max_uap_bss: Maximum number of uAP BSS (default 1, max 2)
#else
max_uap_bss: Maximum number of uAP BSS (default 1, max 1)
#endif
uap_name: Name of the uAP interface (default: "uap")
#ifdef WIFI_DIRECT_SUPPORT
max_wfd_bss: Maximum number of WIFIDIRECT BSS (default 1, max 1)
wfd_name: Name of the WIFIDIRECT interface (default: "wfd")
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
max_vir_bss: Number of Virtual interfaces (default 0)
#endif
#endif
#ifdef MPL_SUPPORT
max_mpl_bss: Number of MPL interfaces (defaut 1, max 1)
#endif
#ifdef NAN_SUPPORT
nan_name: Name of the NAN interface (default: "nan")
max_nan_bss: Number of NAN interfaces (default 1)
#endif
#ifdef SDIOXXX
For example, to install multi-chip driver,
insmod mlan.ko
insmod sdxxx.ko mod_para=nxp/wifi_mod_para.conf [drvdbg=0x7]
wifi_mod_para.conf is used to support multi chips which has different module parameters. It contains
the module parameters for different chips.
#else
#ifdef SYSKT_MULTI
For example, load driver in STA only mode,
...
insmod $1.ko drv_mode=1 [fw_name=nxp/sd8887_uapsta.bin]
#else
For example, to install SD8887 driver,
insmod mlan.ko
insmod sd8887.ko [drv_mode=3] [fw_name=nxp/sd8887_uapsta.bin]
To load driver in STA only mode,
insmod mlan.ko
insmod sd8887.ko drv_mode=1 [fw_name=nxp/sd8887_uapsta.bin]
To load driver in uAP only mode,
insmod mlan.ko
insmod sd8887.ko drv_mode=2 [fw_name=nxp/sd8887_uapsta.bin]
#endif
#endif //SDIOXXX
To switch mode between STA only, uAP only and uAPSTA etc. in run time,
echo drv_mode=1 > /proc/mwlan/adapterX/config // STA mode
echo drv_mode=2 > /proc/mwlan/adapterX/config // uAP mode
echo drv_mode=3 > /proc/mwlan/adapterX/config // STA+uAP mode
#ifdef WIFI_DIRECT_SUPPORT
echo drv_mode=7 > /proc/mwlan/adapterX/config // STA+uAP+WIFIDIRECT mode
#endif
#ifdef SYSKT_MULTI
c) Uninstall WLAN driver and SDIO bus driver,
./unload
#else
c) Uninstall WLAN driver,
ifconfig mlanX down
ifconfig uapX down
rmmod sdxxx
rmmod mlan
#endif
#else
a) Copy sd8787.bin | ... to /lib/firmware/nxp/ directory,
create the directory if it doesn't exist.
#ifdef SDIOXXX
b) Install SDIO bus driver and WLAN driver,
For example, to install multi-chip driver,
insmod mlan.ko
insmod sdxxx.ko mod_para=nxp/wifi_mod_para.conf [drvdbg=0x7]
wifi_mod_para.conf is used to support multi chips which has different module parameters. It contains
the module parameters for different chips.
c) Uninstall WLAN driver,
ifconfig mlanX down
rmmod sdxxx
rmmod mlan
#else
#ifdef SYSKT_MULTI
b) Install SDIO bus driver and WLAN driver,
./load sd8787 | ...
c) Uninstall WLAN driver and SDIO bus driver,
./unload
#else
#ifdef ENT_BUILD
b) Install WLAN driver,
insmod mlan_ent.ko
insmod sdxxx_ent.ko [fw_name=nxp/sd8xxx.bin]
c) Uninstall WLAN driver,
ifconfig mlanX down
rmmod sdxxx_ent
rmmod mlan_ent
#else
b) Install WLAN driver,
insmod mlan.ko
insmod sdxxx.ko [fw_name=nxp/sd8xxx.bin]
c) Uninstall WLAN driver,
ifconfig mlanX down
rmmod sdxxx
rmmod mlan
#endif // ENT_BUILD
#endif // SYSKT_MULTI
#endif // SDIOXXX
#endif // UAP_STA_SUPPORT
#endif // End of section 2 SDIO
#ifdef PCIE // Section 4 PCIe
#ifdef UAP_STA_SUPPORT
a) Copy firmware image pcie8897_uapsta.bin | ... to /lib/firmware/nxp/ directory,
create the directory if it doesn't exist.
b) Install WLAN driver
There are drv_mode, max_sta_bss, max_uap_bss etc. module parameters.
The bit settings of drv_mode are,
Bit 0 : STA
Bit 1 : uAP
#ifdef WIFI_DIRECT_SUPPORT
Bit 2 : WIFIDIRECT
#endif
#ifdef MPL_SUPPORT
Bit 3 : MPL
#endif
#ifdef NAN_SUPPORT
Bit 4 : NAN
#endif
#ifdef ADHOC_OVER_IP
max_sta_bss: Maximum number of STA BSS (default 1, max 18)
#else
#ifdef STA_MBSS_SUPPORT
max_sta_bss: Maximum number of STA BSS (default 1, max 2)
#else
max_sta_bss: Maximum number of STA BSS (default 1, max 1)
#endif
#endif
sta_name: Name of the STA interface (default: "mlan")
#ifdef UAP_MBSS_SUPPORT
max_uap_bss: Maximum number of uAP BSS (default 1, max 2)
#else
max_uap_bss: Maximum number of uAP BSS (default 1, max 1)
#endif
uap_name: Name of the uAP interface (default: "uap")
#ifdef WIFI_DIRECT_SUPPORT
max_wfd_bss: Maximum number of WIFIDIRECT BSS (default 1, max 1)
wfd_name: Name of the WIFIDIRECT interface (default: "wfd")
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
max_vir_bss: Number of Virtual interfaces (default 0)
#endif
#endif
#ifdef MPL_SUPPORT
max_mpl_bss: Number of MPL interfaces (defaut 1, max 1)
#endif
#ifdef NAN_SUPPORT
nan_name: Name of the NAN interface (default: "nan")
max_nan_bss: Number of NAN interfaces (default 1)
#endif
#ifdef PCIEXXX
For example, to install multi-chip driver,
insmod mlan.ko
insmod pciexxx.ko mod_para=nxp/wifi_mod_para.conf [drvdbg=0x7]
wifi_mod_para.conf is used to support multi chips which has different module parameters. It contains
the module parameters for different chips.
#else
For example, to install PCIE8897 driver,
insmod mlan.ko
insmod pcie8897.ko [drv_mode=3] [fw_name=nxp/pcie8897_uapsta.bin]
To load driver in STA only mode,
insmod mlan.ko
insmod pcie8897.ko drv_mode=1 [fw_name=nxp/pcie8897_uapsta.bin]
To load driver in uAP only mode,
insmod mlan.ko
insmod pcie8897.ko drv_mode=2 [fw_name=nxp/pcie8897_uapsta.bin]
#endif // PCIEXXX
To switch mode between STA only, uAP only and uAPSTA in run time,
echo drv_mode=1 > /proc/mwlan/adapterX/config // STA mode
echo drv_mode=2 > /proc/mwlan/adapterX/config // uAP mode
echo drv_mode=3 > /proc/mwlan/adapterX/config // uAPSTA mode
c) Uninstall WLAN driver,
ifconfig mlanX down
ifconfig uapX down
rmmod pciexxx
rmmod mlan
#endif // UAP_STA_SUPPORT
#endif // End of section 4 PCIe
#endif // MULTI_CHIP
#ifdef MFG_CMD_SUPPORT
To load driver with MFG firmware file, use mfg_mode=1 when insmod WLAN driver and
specify MFG firmware name if needed.
#endif
#ifdef RF_TEST_MODE
To load driver with rf_test firmware file, use rf_test_mode=1 when insmod WLAN driver.
This parameter only used for 9177(FC)
#endif
There are some other parameters for debugging purpose etc. Use modinfo to check details.
#ifdef DEBUG_LEVEL1
drvdbg=<bit mask of driver debug message control>
#ifdef DEBUG_LOG
logctrl=<Bit mask of driver log message control>
sh_mem_size=<Shared memory length (default 8192 bytes)>
#endif
#endif
dev_cap_mask=<Bit mask of the device capability>
mac_addr=xx:xx:xx:xx:xx:xx <override the MAC address (in hex)>
#if defined(OPTIMIZED_PS) && defined(DEEP_SLEEP)
auto_ds=0|1|2 <use MLAN default | enable auto deepsleep | disable auto deepsleep>
#endif
#if defined(EXT_SCAN_SUPPORT) && defined(EXT_SCAN_ENH)
ext_scan=0|1|2 <use MLAN default | Enable Extended Scan| Enable Enhanced Extended Scan>
#endif
net_rx=0|1 <use netif_rx_ni in rx | use netif_receive_skb in rx>
amsdu_deaggr=0|1 <default | Try avoid buf copy in amsud deaggregation>
#ifdef ENABLE_802_11P
max_11p_bss = <Max number of 802_11P interfaces (default 1)>
#endif
ps_mode=0|1|2 <use MLAN default | enable IEEE PS mode | disable IEEE PS mode>
sched_scan=0|1 <disable sched_scan | enable sched_scan default>
max_tx_buf=2048|4096|8192 <maximum AMSDU Tx buffer size>
#ifdef SDIO_SUSPEND_RESUME
pm_keep_power=1|0 <PM keep power in suspend (default) | PM no power in suspend>
shutdown_hs=1|0 <Enable HS when shutdown | No HS when shutdown (default)>
#endif
#ifdef ENABLE_802_11D
cfg_11d=0|1|2 <use MLAN default | enable 11d | disable 11d>
#endif
#ifdef CONFIG_OF
dts_enable=0|1 <Disable DTS | Enable DTS (default)>
#endif
#ifdef FW_DNLD_NEEDED
fw_name = <FW file name>
e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin
#endif
hw_name = <hardware name>
reg_work=0|1 <Disable register work queue| Enable register work queue>
hw_test=0|1 <Disable hardware test (default) | Enable hardware test>
fw_serial=0|1 <support parallel download FW | support serial download FW (default)>
req_fw_nowait=0|1 <use request_firmware API (default) | use request_firmware_nowait API>
#if !defined(MLANUTL_LITE)
#ifdef DFS_SUPPORT
dfs53cfg=0|1|2 <use Fw Default | New W53 | Old W53>
#endif
mcs32=0|1 <disable HT MCS32 support | enable HT MCS32 (default)>
#ifdef SDIOXXX
SD8887: antcfg=0|1|2|0xffff <default | Tx/Rx antenna 1 | Tx/Rx antenna 2 | enable antenna diversity>
SD8897/SD8997: antcfg=0x11|0x13|0x33 <Bit0:Rx Path A, Bit1:Rx Path B, Bit 4:Tx Path A, Bit 5:Tx Path B>
#else
#ifdef SD8887
antcfg=0|1|2|0xffff <default | Tx/Rx antenna 1 | Tx/Rx antenna 2 | enable antenna diversity>
#else
#if defined(SD8897) || defined(SD8997)||defined(SD9098) ||defined(SD9097)||defined(SDIW624)
antcfg=0x11|0x13|0x33 <Bit0:Rx Path A, Bit1:Rx Path B, Bit 4:Tx Path A, Bit 5:Tx Path B>
#endif
#endif
#endif
#endif /* !defined(MLANUTL_LITE) */
#ifdef SDIO
slew_rate: Slew Rate Control value = 0|1|2|3 (0 is the slowest slew rate and 03 has the highest slew rate (default))
#endif
#ifdef NO_EEPROM_SUPPORT
init_cfg=<init config (MAC addresses, registers etc.) file name>
e.g. copy init_cfg.conf to firmware directory, init_cfg=nxp/init_cfg.conf
cal_data_cfg=<CAL data config file name>
e.g. copy cal_data.conf to firmware directory, cal_data_cfg=nxp/cal_data.conf
#if defined(SDIOXXX) || defined(SD8887)
Note: Loading driver with 8887 must include correct cal_data_cfg parameter.
#endif
#endif
#ifdef NO_EEPROM_SUPPORT
dpd_data_cfg=<DPD data config file name>
e.g. copy dpd_data.conf to firmware directory, dpd_data_cfg=nxp/dpd_data.conf
#endif
#ifdef TX_POWERCFG
txpwrlimit_cfg=<Tx power limit config file name>
e.g. copy txpwrlimit_cfg_set.conf to firmware directory, txpwrlimit_cfg=nxp/txpwrlimit_cfg_set.conf
#ifdef OTP_CHANINFO
cntry_txpwr=0|1|2
#else
cntry_txpwr=0|1
#endif
0: Disable setting tx power table of country (default)
1: Enable setting tx power table of country
#ifdef OTP_CHANINFO
2: Enable setting rgpower table of country
#endif
#endif
#ifdef HOSTCMD_CFG
init_hostcmd_cfg=<init hostcmd config file name>
e.g. copy init_hostcmd_cfg.conf to firmware directory, init_hostcmd_cfg=nxp/init_hostcmd_cfg.conf
band_steer_cfg=<band steer config file name>
e.g. generate bscfg.conf by band_steer_cfg.conf, then copy bscfg.conf to firmware directory, band_steer_cfg=nxp/bscfg.conf
#endif
#if defined(SYSKT_MULTI) && defined(OOB_WAKEUP)
oob_mode=0|1 <disable OOB wakeup mode (default) | enable OOB wakeup mode>
#endif
#ifdef SUSPEND_SDIO_PULL_DOWN
sdio_pd=0|1 <disable suspend with sdio pull down feature (default) | enable suspend with sdio pull down feature>
#endif
#ifdef SDIO_SP_RX_AGGR
sdio_rx_aggr=1|0 <Enable SDIO rx aggr (default) | Disable SDIO rx aggr>
#endif
#ifdef T3T
#ifdef SDIO
minicard_pwrup=1|0 <power up/down on driver load/unload (default) | don't power up/down>
#endif
#endif
#ifdef SIMU_CFG80211_WEXT
cfg80211_wext=<bit mask of CFG80211 and WEXT control>
#ifdef STA_WEXT
Bit 0: STA WEXT
#endif
#ifdef UAP_WEXT
Bit 1: uAP WEXT
#endif
#ifdef STA_CFG80211
Bit 2: STA CFG80211
#endif
#ifdef UAP_CFG80211
Bit 3: uAP CFG80211
#endif
#endif
#ifdef MULTI_CHAN_SUPPORT
cfg80211_drcs=1|0 <Enable DRCS support (default) | Disable DRCS support>
#endif
reg_alpha2=<Regulatory alpha2 (default NULL)>
#ifdef USB_NEW_FW_DNLD
skip_fwdnld=0|1 <enable FW download support (default) | disable FW download support>
#endif
#ifdef WORK_QUEUE
wq_sched_prio: Priority for work queue
wq_sched_policy: Scheduling policy for work queue
(0: SCHED_NORMAL, 1: SCHED_FIFO, 2: SCHED_RR, 3: SCHED_BATCH, 5: SCHED_IDLE)
@ -108,40 +566,108 @@
as module parameters. If wq_sched_policy is (0, 3 or 5), then wq_sched_prio
must be 0. wq_sched_prio should be 1 to 99 otherwise.
rx_work=0|1|2 <default | Enable rx_work_queue | Disable rx_work_queue>
#endif
#ifdef PCIE
#if defined(PCIE) && defined(PCIE_MSIX)
pcie_int_mode=0|1|2 <Legacy mode, MSI mode (default), MSI-X mode>
#elif defined(PCIE_MSI)
pcie_int_mode=0|1 <Legacy mode, MSI mode (default)>
#else
pcie_int_mode=0 <Legacy mode(default)>
#endif
#if defined(PCIE9098) ||defined(PCIE9097)||defined(PCIEIW624)
ring_size=32|64|128|256|512 <adma ring size for 9097/9098>
#endif
#endif
#if !defined(MLANUTL_LITE)
#ifdef AGGR_CTRL
aggrctrl=1|0 <enable Tx aggr | disable Tx aggr>
#endif
#endif /* !defined(MLANUTL_LITE) */
#if defined(USB_TX_AGGR) || defined(USB_RX_DEAGGR)
usb_aggr=0|1|2 <use MLAN default (disabled) | enable USB aggr | disable USB aggr>
#endif
#if defined WLAN_LOW_POWER_ENABLE
low_power_mode_enable=0|1 <disable low power mode (default)| enable low power mode>
When low power mode is enabled, the output power will be clipped at ~+10dBm and the
expected PA current is expected to be in the 80-90 mA range for b/g/n modes
#endif
#if defined(ANDROID_KERNEL)
#ifdef T50
wakelock_timeout=<set wakelock_timeout value (ms),default 3000ms>
#else
wakelock_timeout=<set wakelock_timeout value (ms)>
#endif
#endif
#ifdef V16_FW_API
pmic=0|1 <No pmic configure cmd sent to firmware | Send pmic configure cmd to firmware>
#endif
#ifdef HS_SUPPORT
indication_gpio=0xXY <GPIO to indicate wakeup source and its level; high four bits X:
level(0/1) for normal wakeup; low four bits Y: GPIO pin number. This parameter
only works with specific board and firmware.>
hs_wake_interval=<Host sleep wakeup interval,it will round to nearest multiple dtim*beacon_period in fw>
disconnect_on_suspend=0|1 <Disable disconnect wifi on suspend (default) | Enable disconnect wifi on suspend>
#ifdef HS_MIMO_SWITCH
hs_mimo_switch=0|1 <Disable dynamic MIMO-SISO switch during host sleep (default) | Enable dynamic MIMO-SISO switch during host sleep>
#endif
#endif
#if defined(HS_SUPPORT) || defined(UAP_HS_SUPPORT)
hs_auto_arp=0|1 <disable hs_auto_arp (default) | enable hs_auto_arp>
#endif
#ifdef GTK_REKEY_OFFLOAD
gtk_rekey_offload=0|1|2 <disable gtk_rekey_offload|enable gtk_rekey_offload (default) | enable gtk_rekey_offload in suspend mode only>
#endif
#ifdef NAPI_SUPPORT
napi=0|1 <disable napi | enable napi>
#endif
fixed_beacon_buffer=0|1 <allocate default buffer size (default) | allocate max buffer size>
#ifdef WIFI_DIRECT_SUPPORT
GoAgeoutTime=0|x <use default ageout time (default) | set Go age out time xTU(TU 100ms)>
#endif
multi_dtim=0|x <use default DTIM interval(default) | set x*beacon_period as DTIM interval>
inact_tmo=0|x <use default IEEE ps inactivity timout value (default) | use IEEE ps inactivity timeout value x ms>
#ifdef MULTI_CHAN_SUPPORT
drcs_chantime_mode=0|x <channel time and mode for DRCS, use default value (default) | use setting value>
Bit31~Bit24:Channel time for channel index0;
Bit23~Bit16:mode for channel index0; 0|1 <PM1 | Null2Self>
Bit15~Bit8:Channel time for channel index1;
Bit7~Bit0:mode for channel index1; 0|1 <PM1 | Null2Self>
#endif
#ifdef FW_ROAMING
roamoffload_in_hs=0|1 <always enable fw roaming (default) | enable fw roaming only when host suspend>
#endif
#ifdef MAX_STA_SIXTY_FOUR
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64)
#else
#ifdef MAX_STA_THIRTY_TWO
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 32)
#else
#ifdef MAX_STA_TWENTY
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 20)
#else
#ifdef MAX_STA_TEN
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 10)
#else
#ifdef MAX_STA_FIVE
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 5)
#else
uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 8)
#endif
#endif
#endif
#endif
#endif
#ifdef HOST_MLME
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
host_mlme=0|1 <Operate in non-host_mlme mode | Operate in host_mlme mode (default)>
for supplicant/authenticator running on host side, WPA3 support is available only in host_mlme mode
#endif
#endif
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
country_ie_ignore=0|1 <Follow countryIE from AP and beacon hint enable (default) | Ignore countryIE from AP and beacon hint disable>
beacon_hints=0|1 <enable beacon hints(default) | disable beacon hints>
#endif
chan_track=0|1 <restore channel tracking parameters(default) | set channel tracking new parameters> for 9098 only
keep_previous_scan=0|1, <Flush previous scan result before start scan | Keep previous scan result(default)>
@ -202,7 +728,9 @@
The following debug info are provided in /proc/net/mwlan/adapterX/mlanY|uapY|wfdY/debug,
on kernel 2.6.24 or later, the entry is /proc/mwlan/adapterX/mlanY|uapY|wfdY/debug.
#ifdef DEBUG_LEVEL1
drvdbg = <bit mask of driver debug message control>
#endif
wmm_ac_vo = <number of packets sent to device from WMM AcVo queue>
wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
@ -211,16 +739,30 @@
tx_buf_size = <current Tx buffer size>
curr_tx_buf_size = <current Tx buffer size in FW>
ps_mode = <0/1, CAM mode/PS mode>
#ifdef OPTIMIZED_PS
ps_state = <0/1/2/3, awake state/pre-sleep state/sleep-confirm state/sleep state>
#else
ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state>
#endif
#ifdef DEEP_SLEEP
is_deep_sleep = <0/1, not deep sleep state/deep sleep state> // Only for STA
#endif
#if defined(HS_SUPPORT)
wakeup_dev_req = <0/1, wakeup device not required/required>
#endif
#if defined(HS_SUPPORT) || defined(DEEP_SLEEP)
wakeup_tries = <wakeup device count, cleared when device awake>
#endif
#ifdef HS_SUPPORT
hs_configured = <0/1, host sleep not configured/configured>
hs_activated = <0/1, extended host sleep not activated/activated>
#endif
tx_pkts_queued = <number of Tx packets queued>
#ifdef WMM_UAPSD
pps_uapsd_mode = <0/1, PPS/UAPSD mode disabled/enabled> // Only for STA
sleep_pd = <sleep period in milliseconds> // Only for STA
qos_cfg = <WMM QoS info> // Only for STA
#endif
tx_lock_flag = <0/1, Tx lock flag> // Only for STA
port_open = <0/1, port open flag> // Only for STA
scan_processing = <0/1, scan processing flag> // Only for STA
@ -240,10 +782,12 @@
num_cmd_h2c_fail = <number of commands failed to send to device>
num_cmd_sleep_cfm_fail = <number of sleep confirm failed to send to device>
num_tx_h2c_fail = <number of data packets failed to send to device>
#ifdef SDIO
num_cmdevt_c2h_fail = <number of commands/events failed to receive from device>
num_rx_c2h_fail = <number of data packets failed to receive from device>
num_int_read_fail = <number of interrupt read failures>
last_int_status = <last interrupt status>
#endif
num_evt_deauth = <number of deauthenticated events received from device> // Only for STA
num_evt_disassoc = <number of disassociated events received from device> // Only for STA
num_evt_link_lost = <number of link lost events received from device> // Only for STA
@ -256,31 +800,45 @@
curr_rd_port = <SDIO multi-port current read port>
mp_wr_bitmap = <SDIO multi-port write bitmap>
curr_wr_port = <SDIO multi-port current write port>
#ifdef PCIE
txbd_rdptr = <PCIE transmit read pointer>
txbd_wrptr = <PCIE transmit write pointer>
rxbd_rdptr = <PCIE recieve read pointer>
rxbd_wrptr = <PCIE recieve write pointer>
eventbd_rdptr = <PCIE event read pointer>
eventbd_wrptr = <PCIE event write pointer>
#endif
cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
event_received = <0/1, no event to process/event received and yet to process>
#ifdef USB
tx_cmd_urb_pending = <number of URB pending for cmd transmit>
tx_data_urb_pending = <number of URB pending for data transmit>
#ifdef USB_CMD_DATA_EP
rx_cmd_urb_pending = <number of URB pending for cmd receive>
#endif
rx_data_urb_pending = <number of URB pending for data receive>
#endif
ioctl_pending = <number of ioctl pending>
tx_pending = <number of Tx packet pending>
rx_pending = <number of Rx packet pending>
lock_count = <number of lock used>
malloc_count = <number of malloc done>
mbufalloc_count = <number of mlan_buffer allocated>
#ifdef PCIE
malloc_cons_count = <number of consistent malloc done>
#endif
main_state = <current state of the main process>
#ifdef SDIO_MMC_DEBUG
sdiocmd53w = <SDIO Cmd53 write status>
sdiocmd53r = <SDIO Cmd52 read status>
#endif
#if defined(USB_SUSPEND_RESUME) || defined(SDIO_SUSPEND_RESUME)
hs_skip_count = <number of skipped suspends>
hs_force_count = <number of forced suspends>
#endif
#if !defined(MLANUTL_LITE)
#ifdef SDIO
Issue SDIO cmd52 read/write through proc.
Usage:
echo "sdcmd52rw=<func> <reg> [data]" > /proc/mwlan/adapterX/config
@ -288,13 +846,17 @@
func: The function number to use (0-7)
reg: The address of the register
data: The value to write, read if the value is absent
#ifdef SDIO_MMC
For SDIO MMC driver, only function 0 and WLAN function access is allowed.
And there is a limitation for function 0 write, only vendor specific CCCR
registers (0xf0 -0xff) are permiited.
#endif
Examples:
echo "sdcmd52rw= 0 4" > /proc/mwlan/adapterX/config # read func 0 address 4
cat /proc/mwlan/adapterX/config # display the register value
echo "sdcmd52rw= 1 3 0xf" > /proc/mwlan/adapterX/config # write 0xf to func 1 address 3
#endif
#endif /* !defined(MLANUTL_LITE) */
Issue debug_dump command through proc.
Usage:
@ -302,12 +864,36 @@
Examples:
echo "debug_dump" > /proc/mwlan/adapterX/config # dump driver internal debug status.
#ifdef DUMP_TO_PROC
To obtain fw dump or driver dump, use command:
cat /proc/mwlan/adapter0/drv_dump > file_drv_dump #save the drv dump to file_drv_dump
cat /proc/mwlan/adapter0/fw_dump > file_fw_dump #save the fw dump to file_fw_dump
#ifdef DUAL_MAC
cat /proc/mwlan/adapter1/drv_dump > file_drv_dump_2 #save the adapter1 drv dump to file_drv_dump_2
#endif
#endif
Use dmesg or cat /var/log/debug to check driver debug messages.
#ifdef CONFIG_X86
To log driver debug messages to file,
a) Edit /etc/syslog.conf, add one line "*.debug /var/log/debug"
on kernel 2.6.24 or later, edit /etc/rsyslog.conf instead
b) touch /var/log/debug (if the file doesn't exist)
c) service syslog restart
on kernel 2.6.24 or later, service rsyslog restart
#endif
#ifdef DEBUG_LOG
To control the driver log buffer through the proc, the following command can be used.
Note: proc can only read at max kernel PAGE_SIZE - 1024 bytes.
Usage:
cat /proc/mwlan/adapterX/logctrl # To read driver log messages
echo "lock" > /proc/mwlan/adapterX/logctrl # Lock the driver log buffer
echo "unlock" > /proc/mwlan/adapterX/logctrl # Unlock the driver log buffer
echo "clear" > /proc/mwlan/adapterX/logctrl # Clear the driver log buffer
echo "level=0xFF" > /proc/mwlan/adapterX/logctrl # Set log buffer level to 0xFF
#endif
Update /proc/sys/kernel/printk to change message log levels.
For example,
@ -315,6 +901,7 @@
will be printed to the console)
echo 15 > /proc/sys/kernel/printk (all messages will be printed to console)
#ifdef FW_RELOAD
4) FOR FW RELOAD
a) Enable parallel firmware download in driver parameter
insmod sdxxx.ko fw_serial=0
@ -326,12 +913,16 @@
echo "fw_reload=1" > /proc/mwlan/adapterX/config trigger SDIO inband firmware reset and reload firmware
echo "fw_reload=2" > /proc/mwlan/adapterX/config trigger firmware reload
echo "fw_reload=3" > /proc/mwlan/adapterX/config set firmware reload flag in driver.
#ifdef PCIE
echo "fw_reload=4" > /proc/mwlan/config trigger PCIe FLR and reload firmware.
echo "fw_reload=6" > /proc/mwlan/config trigger PCIe inband firmware reset and reload firmware.
#endif
(Note: This feature will be supported on Robin3 and KF2.
For CAC-A2, it only work with the board which supports parallel fw download)
#endif
#ifdef RF_TEST_MODE
5) FOR RF test mode commands:
Following commands are used to perform RF testing of the wifi chipset.
@ -354,21 +945,25 @@
Set Radio Mode
echo "radio_mode=<radioMode0> <radioMode1>"
Example: 2.4G[1x1] e.g Firecrest
Example: 2.4G[1x1]
echo "radio_mode=11 0" > /proc/mwlan/adapterX/config
5G[1x1] e.g Firecrest
5G[1x1]
echo "radio_mode=3 0" > /proc/mwlan/adapterX/config
Set Tx Antenna
For 1x1 chipsets, 1:Main, 2:Aux when antenna diversity is supported
#ifdef STREAM_2X2
For 2x2 chipsets, 1:Path A, 2: Path B, 3: Path A+B
Both Tx and Rx must be set to same antenna path
#endif
echo "tx_antenna=1" > /proc/mwlan/adapterX/config
Set Rx Antenna
For 1x1 chipsets, 1:Main, 2:Aux when antenna diversity is supported
#ifdef STREAM_2X2
For 2x2 chipsets, 1:Path A, 2:Path B, 3:Path A+B
Both Tx and Rx must be set to same antenna path
#endif
echo "rx_antenna=1" > /proc/mwlan/adapterX/config
Set RF band (0:2G, 1:5G)
@ -462,12 +1057,15 @@
Example : To start trigger frame transmission :
echo "rf_test_mode=1" > /proc/mwlan/adapter0/config
echo "radio_mode=3 0" > /proc/mwlan/adapterX/config
echo "band=1" > /proc/mwlan/adapter0/config
echo "bw=0" > /proc/mwlan/adapter0/config
echo "channel=36" > /proc/mwlan/adapter0/config
echo "trigger_frame=1 0 1 2 5484 0 256 0 0 0 1 0 0 0 1 60 1 0 65535 0 511 5 0 61 0 0 0 0 90 0 0 0 0" > /proc/mwlan/adapter0/config
echo "tx_frame=1 0x1102 0xabababab 200" >/proc/mwlan/adapter0/config
#endif
#ifdef HS_SUPPORT
6) Set host sleep parameters
hssetpara
@ -475,6 +1073,7 @@
Example:
echo "hssetpara=2 0xff 0xc8 3 400" > /proc/mwlan/adapter0/config
echo "hssetpara=2 1 0xc8 3 400 " > /proc/mwlan/adapter0/config
#endif
7) For Antenna Diversity Command
@ -484,25 +1083,42 @@
GET Command Format: cat /proc/mwlan/adapter0/config
SET Command Format: echo "antcfg=[m] [n] [o] [p]" > /proc/mwlan/adapter0/config
#ifdef STREAM_2X2
For chip which support STREAM_2X2
where value of m is:
Bit 0 -- Tx Path A or Tx/Rx Path A if [n] is not provided
Bit 1 -- Tx Path B or Tx/Rx Path B if [n] is not provided
Bit 0-1 -- Tx Path A+B or Tx/Rx Path A+B if [n] is not provided
For 9097/9098/IW62X, LOW BYTE for 2G setting
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)||defined(SDIW624)||defined(PCIEIW624)||defined(USBIW624)
For 9097/9098/IW624, LOW BYTE for 2G setting
Bit 8 -- Tx Path A or Tx/Rx Path A if [n] is not provided
Bit 9 -- Tx Path B or Tx/Rx Path B if [n] is not provided
Bit 8-9 -- Tx Path A+B or Tx/Rx Path A+B if [n] is not provided
For 9097/9098/IW62X, HIGH BYTE for 5G setting
For 9097/9098/IW624, HIGH BYTE for 5G setting
#endif
where value of n is:
Bit 0 -- Rx Path A
Bit 1 -- Rx Path B
Bit 0-1 -- Rx Path A+B
For 9097/9098/IW62X, LOW BYTE for 2G setting
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)||defined(SDIW624)||defined(PCIEIW624)||defined(USBIW624)
For 9097/9098/IW624, LOW BYTE for 2G setting
Bit 8 -- Rx Path A
Bit 8 -- Rx Path B
Bit 8-9 -- Rx Path A+B
For 9097/9098/IW62X, HIGH BYTE for 5G setting
For 9097/9098/IW624, HIGH BYTE for 5G setting
#endif
#ifdef ENABLE_802_116E
where value of o is:
For IW624, 6G setting
Bit 0 -- Tx Path A
Bit 1 -- Tx Path B
Bit 0-1 -- Tx Path A+B
where value of p is:
For IW624, 6G setting
Bit 0 -- Rx Path A
Bit 1 -- Rx Path B
Bit 0-1 -- Rx Path A+B
#endif
The Tx path setting (m) is used for both Tx and Rx if Rx path (n) is not provided.
Examples:
@ -510,9 +1126,15 @@
echo "antcfg=3" > /proc/mwlan/adapter0/config : Set Tx and Rx path to A+B
echo "antcfg=1 3" > /proc/mwlan/adapter0/config : Set Tx path to A and Rx path to A+B
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)||defined(SDIW624)||defined(PCIEIW624)||defined(USBIW624)
echo "antcfg=0x103" > /proc/mwlan/adapter0/config : Set Tx and Rx path to A+B on 2G and Tx and Rx path to A on 5G
echo "antcfg=0x103 0x103" > /proc/mwlan/adapter0/config : Set Tx path to A+B and Rx path to A+B on 2G, and Tx and Rx path to A on 5G
#endif
#ifdef ENABLE_802_116E
echo "antcfg=0x103 0x103 2 2" > /proc/mwlan/adapter0/config : Set both Tx and Rx path to A+B on 2G, both Tx and Rx path to A on 5G, both Tx and Rx path to B on 6G
#endif
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098)
echo "antcfg=0x202" > /proc/mwlan/adapter0/config : Use 5GHz path B pin for 5G TX/RX and 2GHz path B pin for 2G TX/RX
On RD board connection is as follows :
@ -520,7 +1142,9 @@
5GHz path B pin -> AntB
2GHz path A pin -> AntB
2GHz path B pin -> AntA
#endif
#ifdef FEATURE_CONTROL
For chip which support SAD
where value of m is:
Bit 0 -- Tx/Rx antenna 1
@ -537,3 +1161,28 @@
echo "antcfg=0xFFFF" > /proc/mwlan/adapter0/config : Set Tx/Rx antenna diversity
echo "antcfg=0xFFFF 0x1770" > /proc/mwlan/adapter0/config : Set antenna evaluate time interval to 6s
#endif
#else
This command is used to set/get the mode of Tx/Rx antenna.If SAD is enabled,
this command can also used to set SAD antenna evaluate time interval(antenna mode must
be antenna diversity when set SAD evaluate time interval).
where value of m is:
Bit 0 -- Tx/Rx antenna 1
Bit 1 -- Tx/Rx antenna 2
...
0xFFFF -- Tx/Rx antenna diversity
where value of n is:
if m = 0xFFFF, SAD evaluate time interval,default value is 6s(0x1770)
Examples:
cat /proc/mwlan/adapter0/config : Get Tx/Rx antenna mode
echo "antcfg=1" > /proc/mwlan/adapter0/config : Set Tx/Rx antenna 1
echo "antcfg=0xFFFF" > /proc/mwlan/adapter0/config : Set Tx/Rx antenna diversity
echo "antcfg=0xFFFF 0x1770" > /proc/mwlan/adapter0/config : Set antenna evaluate time interval to 6s
#endif

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_
/** MLAN release version */
#define MLAN_RELEASE_VERSION "391"
#define MLAN_RELEASE_VERSION "391.p3"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
@ -613,6 +613,8 @@ typedef enum {
#define MLAN_BUF_FLAG_TX_CTRL MBIT(14)
#define MLAN_BUF_FLAG_EASYMESH MBIT(16)
#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17)
#ifdef DEBUG_LEVEL1
@ -1321,6 +1323,8 @@ typedef struct _mlan_buffer {
t_u32 extra_ts_sec;
/** Time stamp when packet is dequed from rx_q(micro seconds) */
t_u32 extra_ts_usec;
/** When TX ra mac address, When Rx Ta mac address*/
t_u8 mac[MLAN_MAC_ADDR_LENGTH];
/** Fields below are valid for MLAN module only */
/** Pointer to parent mlan_buffer */
struct _mlan_buffer *pparent;

View file

@ -334,6 +334,9 @@ typedef enum _WLAN_802_11_WEP_STATUS {
/**TLV type : Host MLME Flag*/
#define TLV_TYPE_HOST_MLME (PROPRIETARY_TLV_BASE_ID + 307)
/** TLV type: MULTI AP Flag */
#define TLV_TYPE_MULTI_AP (PROPRIETARY_TLV_BASE_ID + 326)
/** TLV type : AP wacp mode */
#define TLV_TYPE_UAP_WACP_MODE (PROPRIETARY_TLV_BASE_ID + 0x147) /* 0x0247 */
@ -2168,6 +2171,8 @@ typedef enum _ENH_PS_MODES {
/** TDLS off channel */
#define TDLS_OFF_CHANNEL 1
#define RXPD_FLAG_PKT_EASYMESH MBIT(4)
/** structure for channel switch result from TDLS FW */
typedef MLAN_PACK_START struct _chan_switch_result {
/** current channel, 0 - base channel, 1 - off channel*/
@ -2285,6 +2290,9 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_TDLS_Idle_Timeout_t {
/** Bit mask for TxPD flags field for Tx status report */
#define MRVDRV_TxPD_FLAGS_TX_PACKET_STATUS MBIT(5)
/** Bit mask for TxPD flags field for EASYMESH */
#define MRVDRV_TxPD_FLAGS_EASYMESH MBIT(7)
/** Packet type: 802.11 */
#define PKT_TYPE_802DOT11 0x05
@ -2424,6 +2432,9 @@ typedef MLAN_PACK_START struct _TxPD {
t_u8 reserved;
/** Tx Control */
t_u32 tx_control_1;
/** ra mac address */
t_u8 ra_mac[6];
t_u8 reserved3[2];
} MLAN_PACK_END TxPD, *PTxPD;
/** RxPD Descriptor */
@ -2469,6 +2480,8 @@ typedef MLAN_PACK_START struct _RxPD {
/** Reserved */
t_u8 reserved3[8];
t_u8 ta_mac[6];
t_u8 reserved4[2];
} MLAN_PACK_END RxPD, *PRxPD;
/** IEEEtypes_FrameCtl_t*/
@ -2774,6 +2787,14 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_HostMlme_t {
t_u8 host_mlme;
} MLAN_PACK_END MrvlIEtypes_HostMlme_t;
/** MrvlIEtypes_MultiAp_t */
typedef MLAN_PACK_START struct _MrvlIEtypes_MultiAp_t {
/** Header */
MrvlIEtypesHeader_t header;
/** Multi AP flag */
t_u8 flag;
} MLAN_PACK_END MrvlIEtypes_MultiAp_t;
/** MrvlIEtypes_NumProbes_t */
typedef MLAN_PACK_START struct _MrvlIEtypes_NumProbes_t {
/** Header */

View file

@ -618,6 +618,7 @@ mlan_status wlan_init_priv(pmlan_private priv)
priv->hotspot_cfg = 0;
priv->intf_hr_len = pmadapter->ops.intf_header_len;
priv->multi_ap_flag = 0;
memset(pmadapter, &priv->chan_rep_req, 0, sizeof(priv->chan_rep_req));
#ifdef USB
if (IS_USB(pmadapter->card_type)) {

View file

@ -357,6 +357,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_TP_STATE = 0x0020007D,
MLAN_OID_MISC_HAL_PHY_CFG = 0x0020007E,
MLAN_OID_MISC_RF_TEST_HE_POWER = 0X0020007F,
MLAN_OID_MISC_MULTI_AP_CFG = 0x00200080,
#ifdef UAP_SUPPORT
MLAN_OID_MISC_WACP_MODE = 0x00200081,
#endif
@ -1172,6 +1173,8 @@ typedef struct _mlan_uap_bss_param {
/** uap host based config */
t_u32 uap_host_based_config;
/** multi ap flag */
t_u8 multi_ap_flag;
} mlan_uap_bss_param, *pmlan_uap_bss_param;
/** mlan_uap_scan_channels */
@ -6139,6 +6142,8 @@ typedef struct _mlan_ds_misc_cfg {
#endif
/** Hotspot config param set */
t_u32 hotspot_cfg;
/** Multi AP flag */
t_u8 multi_ap_flag;
#ifdef STA_SUPPORT
ExtCap_t ext_cap;
#endif

View file

@ -1051,6 +1051,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
MrvlIEtypes_HostMlme_t *host_mlme_tlv = MNULL;
MrvlIEtypes_PrevBssid_t *prev_bssid_tlv = MNULL;
t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0};
MrvlIEtypes_MultiAp_t *multi_ap_tlv = MNULL;
ENTER();
@ -1487,6 +1488,18 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv,
pos += sizeof(prev_bssid_tlv->header) + MLAN_MAC_ADDR_LENGTH;
}
if (pmpriv->multi_ap_flag) {
multi_ap_tlv = (MrvlIEtypes_MultiAp_t *)pos;
multi_ap_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_MULTI_AP);
multi_ap_tlv->header.len = sizeof(multi_ap_tlv->flag);
multi_ap_tlv->flag = pmpriv->multi_ap_flag;
PRINTM(MINFO, " TLV multi_ap_flag : 0x%x\n",
multi_ap_tlv->flag);
pos += sizeof(multi_ap_tlv->header) + multi_ap_tlv->header.len;
multi_ap_tlv->header.len =
wlan_cpu_to_le16(sizeof(multi_ap_tlv->flag));
}
if (wlan_11d_create_dnld_countryinfo(pmpriv, pbss_desc->bss_band)) {
PRINTM(MERROR, "Dnld_countryinfo_11d failed\n");
ret = MLAN_STATUS_FAILURE;
@ -1702,6 +1715,7 @@ mlan_status wlan_ret_802_11_associate(mlan_private *pmpriv,
/* Send a Media Connected event, according to the Spec */
pmpriv->media_connected = MTRUE;
pmpriv->multi_ap_flag = 0;
pmpriv->adapter->pps_uapsd_mode = MFALSE;
pmpriv->adapter->tx_lock_flag = MFALSE;
pmpriv->adapter->delay_null_pkt = MFALSE;

View file

@ -1332,6 +1332,7 @@ typedef struct _mlan_private {
/** IP address */
t_u8 ip_addr[IPADDR_LEN];
t_u32 hotspot_cfg;
t_u8 multi_ap_flag;
#ifdef STA_SUPPORT
ExtCap_t ext_cap;
ExtCap_t def_ext_cap;
@ -1589,6 +1590,8 @@ struct _sta_node {
t_void *cm_connectioninfo;
#endif
sta_stats stats;
/** station aid */
t_u16 aid;
};
/** 802.11h State information kept in the 'mlan_adapter' driver structure */
@ -3923,6 +3926,8 @@ static inline t_u8 wlan_is_port_ready(pmlan_adapter pmadapter, t_u32 port_index)
return MTRUE;
}
#endif
mlan_status wlan_check_easymesh_pkt(mlan_private *priv, pmlan_buffer pmbuf,
RxPD *prx_pd);
#ifdef UAP_SUPPORT
mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf);
@ -4074,6 +4079,9 @@ mlan_status wlan_set_drvdbg(pmlan_adapter pmadapter,
mlan_status wlan_misc_hotspot_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
mlan_status wlan_misc_multi_ap_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);
#ifdef STA_SUPPORT
mlan_status wlan_misc_ext_capa_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req);

View file

@ -3515,6 +3515,32 @@ mlan_status wlan_misc_hotspot_cfg(pmlan_adapter pmadapter,
return ret;
}
/**
* @brief Set multi ap flag
*
* @param pmadapter A pointer to mlan_adapter structure
* @param pioctl_req A pointer to ioctl request buffer
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
mlan_status wlan_misc_multi_ap_cfg(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
mlan_status ret = MLAN_STATUS_SUCCESS;
ENTER();
if (MLAN_ACT_GET == pioctl_req->action)
misc->param.multi_ap_flag = pmpriv->multi_ap_flag;
else if (MLAN_ACT_SET == pioctl_req->action)
pmpriv->multi_ap_flag = misc->param.multi_ap_flag;
LEAVE();
return ret;
}
#ifdef STA_SUPPORT
/**
* @brief This function check if we should enable beacon protection support

View file

@ -405,6 +405,7 @@ t_void wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect)
priv->rxpd_rate_info = 0;
priv->max_amsdu = 0;
priv->amsdu_disable = MFALSE;
priv->multi_ap_flag = 0;
wlan_coex_ampdu_rxwinsize(pmadapter);
priv->sec_info.ewpa_enabled = MFALSE;

View file

@ -5179,6 +5179,9 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_MISC_HOTSPOT_CFG:
status = wlan_misc_hotspot_cfg(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_MULTI_AP_CFG:
status = wlan_misc_multi_ap_cfg(pmadapter, pioctl_req);
break;
case MLAN_OID_MISC_OTP_USER_DATA:
status = wlan_misc_otp_user_data(pmadapter, pioctl_req);
break;

View file

@ -741,6 +741,13 @@ mlan_status wlan_ops_sta_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
rxpd_rate_info_orig, prx_pd->rate_info);
}
rx_pkt_type = prx_pd->rx_pkt_type;
if (prx_pd->flags & RXPD_FLAG_PKT_EASYMESH) {
PRINTM_NETINTF(MDAT_D, priv);
PRINTM(MDAT_D, "Easymesh flags : 0x%x\n", prx_pd->flags);
ret = wlan_check_easymesh_pkt(priv, pmbuf, prx_pd);
if (ret != MLAN_STATUS_SUCCESS)
goto done;
}
prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) !=

View file

@ -127,6 +127,11 @@ t_void *wlan_ops_sta_process_txpd(t_void *priv, pmlan_buffer pmbuf)
}
if (pmbuf->flags & MLAN_BUF_FLAG_TDLS)
plocal_tx_pd->flags |= MRVDRV_TxPD_FLAGS_TDLS_PACKET;
if (pmbuf->flags & MLAN_BUF_FLAG_EASYMESH) {
plocal_tx_pd->flags |= MRVDRV_TxPD_FLAGS_EASYMESH;
memcpy_ext(pmpriv->adapter, plocal_tx_pd->ra_mac, pmbuf->mac,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
/* Offset of actual data */
plocal_tx_pd->tx_pkt_offset = (t_u16)(
(t_ptr)pmbuf->pbuf + pmbuf->data_offset - (t_ptr)plocal_tx_pd);

View file

@ -446,3 +446,57 @@ t_void wlan_process_bypass_tx(pmlan_adapter pmadapter)
!wlan_bypass_tx_list_empty(pmadapter));
LEAVE();
}
/**
* @brief This function will convert 802.11 header to 802.3 header
and save the backhaul station aid to pmbuf
*
* @param priv A pointer to mlan_private
* @param pmbuf A pointer to mlan_buffer
* @param prx_pd A pointer to RxPD
*
* @return MLAN_STATUS_PENDING --success, otherwise fail
*/
mlan_status wlan_check_easymesh_pkt(mlan_private *priv, pmlan_buffer pmbuf,
RxPD *prx_pd)
{
Eth803Hdr_t *eth_header = MNULL;
sta_node *sta_ptr = MNULL;
mlan_status ret = MLAN_STATUS_SUCCESS;
t_u8 *pos = MNULL;
t_u32 tmp = 0;
ENTER();
pos = (t_u8 *)prx_pd + prx_pd->rx_pkt_offset;
eth_header = (Eth803Hdr_t *)pos;
PRINTM(MDAT_D,
"Rx Easymesh ETH header destination address: " FULL_MACSTR
"\nETH header source address: " FULL_MACSTR "\n",
FULL_MAC2STR(eth_header->dest_addr),
FULL_MAC2STR(eth_header->src_addr));
if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
pmbuf->flags |= MLAN_BUF_FLAG_EASYMESH;
memcpy_ext(priv->adapter, pmbuf->mac, prx_pd->ta_mac,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
sta_ptr = wlan_get_station_entry(priv, prx_pd->ta_mac);
if (!sta_ptr) {
PRINTM(MERROR,
"Easymesh Error! Can't find station in the station list\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* Save station aid to pmbuf and send it to moal */
tmp = (t_u32)sta_ptr->aid;
pmbuf->priority |= (tmp << 24);
PRINTM(MDAT_D, "Easymesh: Rx for VLAN " FULL_MACSTR "\n",
FULL_MAC2STR(prx_pd->ta_mac));
}
done:
LEAVE();
return ret;
}

View file

@ -708,6 +708,7 @@ static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv,
MrvlIETypes_HTCap_t *tlv_htcap = MNULL;
MrvlIEtypes_wmm_parameter_t *tlv_wmm_parameter = MNULL;
MrvlIEtypes_preamble_t *tlv_preamble = MNULL;
MrvlIEtypes_MultiAp_t *tlv_multi_ap = MNULL;
t_u32 cmd_size = 0;
t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0};
@ -1459,6 +1460,16 @@ static mlan_status wlan_uap_cmd_ap_config(pmlan_private pmpriv,
cmd_size += sizeof(MrvlIEtypes_preamble_t);
tlv += sizeof(MrvlIEtypes_preamble_t);
}
if (bss->param.bss_config.multi_ap_flag) {
/** Add multi AP tlv here */
tlv_multi_ap = (MrvlIEtypes_MultiAp_t *)tlv;
tlv_multi_ap->header.type = wlan_cpu_to_le16(TLV_TYPE_MULTI_AP);
tlv_multi_ap->header.len =
wlan_cpu_to_le16(sizeof(tlv_multi_ap->flag));
tlv_multi_ap->flag = bss->param.bss_config.multi_ap_flag;
cmd_size += sizeof(MrvlIEtypes_MultiAp_t);
tlv += sizeof(MrvlIEtypes_MultiAp_t);
}
cmd->size = (t_u16)wlan_cpu_to_le16(cmd_size);
PRINTM(MCMND, "AP config: cmd_size=%d\n", cmd_size);
LEAVE();
@ -4353,6 +4364,8 @@ static mlan_status wlan_uap_cmd_add_station(pmlan_private pmpriv,
LEAVE();
return MLAN_STATUS_FAILURE;
}
/* Save station aid for multi-ap */
sta_ptr->aid = bss->param.sta_info.aid;
memcpy_ext(pmadapter, new_sta->peer_mac, bss->param.sta_info.peer_mac,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (cmd_action != HostCmd_ACT_ADD_STA)

View file

@ -249,6 +249,11 @@ t_void *wlan_ops_uap_process_txpd(t_void *priv, pmlan_buffer pmbuf)
plocal_tx_pd->tx_pkt_type = (t_u16)pkt_type;
plocal_tx_pd->tx_control = tx_control;
}
if (pmbuf->flags & MLAN_BUF_FLAG_EASYMESH) {
plocal_tx_pd->flags |= MRVDRV_TxPD_FLAGS_EASYMESH;
memcpy_ext(pmpriv->adapter, plocal_tx_pd->ra_mac, pmbuf->mac,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
}
if (pmbuf->flags & MLAN_BUF_FLAG_TX_CTRL) {
if (pmbuf->u.tx_info.data_rate) {
@ -393,6 +398,14 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
}
rx_pkt_type = prx_pd->rx_pkt_type;
if (prx_pd->flags & RXPD_FLAG_PKT_EASYMESH) {
PRINTM_NETINTF(MDAT_D, priv);
PRINTM(MDAT_D, "UAP Rx Easymesh pkt flags : 0x%x\n",
prx_pd->flags);
ret = wlan_check_easymesh_pkt(priv, pmbuf, prx_pd);
if (ret != MLAN_STATUS_SUCCESS)
goto done;
}
prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
PRINTM(MINFO,
@ -554,7 +567,11 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
}
}
sta_ptr = wlan_get_station_entry(priv, prx_pkt->eth803_hdr.src_addr);
if (prx_pd->flags & RXPD_FLAG_PKT_EASYMESH)
sta_ptr = wlan_get_station_entry(priv, prx_pd->ta_mac);
else
sta_ptr = wlan_get_station_entry(priv,
prx_pkt->eth803_hdr.src_addr);
if (sta_ptr) {
sta_ptr->snr = prx_pd->snr;
sta_ptr->nf = prx_pd->nf;
@ -589,8 +606,12 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
wlan_process_uap_rx_packet(priv, pmbuf);
goto done;
}
memcpy_ext(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (prx_pd->flags & RXPD_FLAG_PKT_EASYMESH)
memcpy_ext(pmadapter, ta, prx_pd->ta_mac, MLAN_MAC_ADDR_LENGTH,
MLAN_MAC_ADDR_LENGTH);
else
memcpy_ext(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID)) {
sta_ptr = wlan_get_station_entry(priv, ta);
if (sta_ptr) {

View file

@ -2156,8 +2156,13 @@ t_void wlan_wmm_add_buf_txqueue(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
&priv->wmm.tid_tbl_ptr[tid_down].ra_list, MNULL,
MNULL);
} else {
memcpy_ext(pmadapter, ra, pmbuf->pbuf + pmbuf->data_offset,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
if (pmbuf->flags & MLAN_BUF_FLAG_EASYMESH)
memcpy_ext(pmadapter, ra, pmbuf->mac,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
else
memcpy_ext(pmadapter, ra,
pmbuf->pbuf + pmbuf->data_offset,
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
/** put multicast/broadcast packet in the same ralist */
if (ra[0] & 0x01)
memset(pmadapter, ra, 0xff, sizeof(ra));

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_
/** MLAN release version */
#define MLAN_RELEASE_VERSION "391"
#define MLAN_RELEASE_VERSION "391.p3"
/** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */
@ -613,6 +613,8 @@ typedef enum {
#define MLAN_BUF_FLAG_TX_CTRL MBIT(14)
#define MLAN_BUF_FLAG_EASYMESH MBIT(16)
#define MLAN_BUF_FLAG_MC_AGGR_PKT MBIT(17)
#ifdef DEBUG_LEVEL1
@ -1321,6 +1323,8 @@ typedef struct _mlan_buffer {
t_u32 extra_ts_sec;
/** Time stamp when packet is dequed from rx_q(micro seconds) */
t_u32 extra_ts_usec;
/** When TX ra mac address, When Rx Ta mac address*/
t_u8 mac[MLAN_MAC_ADDR_LENGTH];
/** Fields below are valid for MLAN module only */
/** Pointer to parent mlan_buffer */
struct _mlan_buffer *pparent;

View file

@ -357,6 +357,7 @@ enum _mlan_ioctl_req_id {
MLAN_OID_MISC_TP_STATE = 0x0020007D,
MLAN_OID_MISC_HAL_PHY_CFG = 0x0020007E,
MLAN_OID_MISC_RF_TEST_HE_POWER = 0X0020007F,
MLAN_OID_MISC_MULTI_AP_CFG = 0x00200080,
#ifdef UAP_SUPPORT
MLAN_OID_MISC_WACP_MODE = 0x00200081,
#endif
@ -1172,6 +1173,8 @@ typedef struct _mlan_uap_bss_param {
/** uap host based config */
t_u32 uap_host_based_config;
/** multi ap flag */
t_u8 multi_ap_flag;
} mlan_uap_bss_param, *pmlan_uap_bss_param;
/** mlan_uap_scan_channels */
@ -6139,6 +6142,8 @@ typedef struct _mlan_ds_misc_cfg {
#endif
/** Hotspot config param set */
t_u32 hotspot_cfg;
/** Multi AP flag */
t_u8 multi_ap_flag;
#ifdef STA_SUPPORT
ExtCap_t ext_cap;
#endif

View file

@ -228,6 +228,14 @@ struct ieee80211_channel *woal_get_ieee80211_channel(moal_private *priv,
*/
int woal_get_active_intf_freq(moal_private *priv)
{
#ifdef WIFI_DIRECT_SUPPORT
#if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
moal_private *pmpriv = NULL;
moal_handle *handle = priv->phandle;
int i;
#endif
#endif
#ifdef UAP_SUPPORT
if (priv->bss_role == MLAN_BSS_ROLE_UAP && priv->bss_started &&
priv->uap_host_based) {
@ -242,6 +250,33 @@ int woal_get_active_intf_freq(moal_private *priv)
return priv->conn_chan.center_freq;
}
#endif
#ifdef WIFI_DIRECT_SUPPORT
#if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) {
for (i = 0; i < handle->priv_num; i++) {
if (handle->priv[i] &&
handle->priv[i]->bss_type ==
MLAN_BSS_TYPE_WIFIDIRECT) {
pmpriv = handle->priv[i];
if (pmpriv->bss_role == MLAN_BSS_ROLE_STA &&
pmpriv->media_connected == MTRUE &&
pmpriv->sme_current.ssid_len) {
return pmpriv->conn_chan.center_freq;
}
if (pmpriv->bss_role == MLAN_BSS_ROLE_UAP &&
pmpriv->bss_started &&
pmpriv->uap_host_based) {
#if KERNEL_VERSION(3, 8, 0) <= CFG80211_VERSION_CODE
return pmpriv->chan.chan->center_freq;
#endif
}
}
}
}
#endif
#endif
return 0;
}
@ -1238,7 +1273,8 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy,
#endif /* WIFI_DIRECT_SUPPORT */
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
woal_cfg80211_del_beacon(wiphy, dev, 0);
#else
woal_cfg80211_del_beacon(wiphy, dev);
@ -2235,7 +2271,8 @@ done:
* @return 0 -- success, otherwise fail
*/
int woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
unsigned int link_id,
#endif
const u8 *peer,
@ -5044,7 +5081,8 @@ void woal_cfg80211_notify_channel(moal_private *priv,
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
cfg80211_ch_switch_notify(priv->netdev, &chandef, 0, 0);
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
IMX_ANDROID_13 || IMX_ANDROID_12_BACKPORT)
cfg80211_ch_switch_notify(priv->netdev, &chandef, 0);
#else
cfg80211_ch_switch_notify(priv->netdev, &chandef);

View file

@ -66,6 +66,10 @@
#define MRVL_PKT_TYPE_MGMT_FRAME 0xE5
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
#define MRVL_PKT_TYPE_MGMT_EASYMESH 0xCF
#endif
mlan_status woal_cfg80211_set_key(moal_private *priv, t_u8 is_enable_wep,
t_u32 cipher, const t_u8 *key, int key_len,
const t_u8 *seq, int seq_len, t_u8 key_index,
@ -161,7 +165,8 @@ int woal_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev);
#endif
int woal_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
unsigned int link_id,
#endif
const u8 *peer,
@ -440,7 +445,8 @@ int woal_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *params);
#endif
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id);
#else

View file

@ -2899,6 +2899,116 @@ done:
}
#endif
#if defined(UAP_SUPPORT)
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
/**
* @brief easymesh uap Set/Get multi AP mode handler
*
* @param priv A pointer to moal_private structure
* @param req A pointer to ifreq structure
* @return 0 --success, otherwise fail
*/
static int woal_uap_set_multiap_mode(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen)
{
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *misc = NULL;
mlan_status status = MLAN_STATUS_SUCCESS;
int mode[1] = {0};
int ret = 0;
int header_len = 0;
int user_data_len = 0;
ENTER();
if (!respbuf) {
PRINTM(MERROR, "response buffer is not available!\n");
ret = -EINVAL;
goto done;
}
header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SETMODE);
user_data_len = strlen(respbuf) - header_len;
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
/* Fill request buffer */
misc = (mlan_ds_misc_cfg *)req->pbuf;
misc->sub_command = MLAN_OID_MISC_MULTI_AP_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
if ((int)strlen(respbuf) == header_len) {
/* GET operation */
user_data_len = 0;
req->action = MLAN_ACT_GET;
} else {
/* SET operation */
parse_arguments(respbuf + header_len, mode, ARRAY_SIZE(mode),
&user_data_len);
if (user_data_len > 1) {
PRINTM(MERROR, "Invalid number of args!\n");
ret = -EINVAL;
goto done;
}
if ((mode[0] != EASY_MESH_MULTI_AP_BSS_MODE_3) &&
(mode[0] != EASY_MESH_MULTI_AP_BSS_MODE_2) &&
(mode[0] != EASY_MESH_MULTI_AP_BSS_MODE_1)) {
PRINTM(MERROR, "Invalid setmode value\n");
ret = -EINVAL;
goto done;
}
if (mode[0] == EASY_MESH_MULTI_AP_BSS_MODE_3)
/* Supports backhaul and fronthaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_BH_AND_FH_BSS;
else if (mode[0] == EASY_MESH_MULTI_AP_BSS_MODE_2)
/* Supports backhaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_BH_BSS;
else if (mode[0] == EASY_MESH_MULTI_AP_BSS_MODE_1)
/* Supports fronthaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_FH_BSS;
PRINTM(MINFO, "[EM:%s:%d] priv->multi_ap_flag 0x%x\n", __func__,
__LINE__, priv->multi_ap_flag);
req->action = MLAN_ACT_SET;
}
/* Send IOCTL request to MLAN */
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
if (req->action == MLAN_ACT_GET) {
if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_AND_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_3;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_2;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_FH_BSS)
mode[0] = EASY_MESH_MULTI_AP_BSS_MODE_1;
PRINTM(MINFO, "[EM:%s:%d] setmode to 0x%x\n", __func__,
__LINE__, mode[0]);
moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)mode,
sizeof(mode), respbuflen);
ret = sizeof(mode);
}
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
#endif
#endif
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
@ -19622,6 +19732,16 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
priv_cmd.total_len);
goto handled;
#endif
#if defined(UAP_SUPPORT)
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SETMODE,
strlen(PRIV_CMD_SETMODE)) == 0) {
/* Set multi_ap mode */
len = woal_uap_set_multiap_mode(priv, buf,
priv_cmd.total_len);
goto handled;
#endif
#endif
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_BSSROLE,

View file

@ -82,6 +82,9 @@ Change log:
#define PRIV_CMD_GET_STA_LIST "getstalist"
#define PRIV_CMD_BSS_CONFIG "bssconfig"
#endif
#if defined(UAP_SUPPORT)
#define PRIV_CMD_SETMODE "setmode"
#endif
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
#define PRIV_CMD_BSSROLE "bssrole"

View file

@ -7609,6 +7609,48 @@ done:
return status;
}
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/**
* @brief Set multi ap flag to mlan layer
*
* @param priv A pointer to moal_private structure
* @param wait_option wait_option of ioctl
* @param flag multi ap flag
*
* @return MLAN_STATUS_SUCCESS -- success, otherwise fail
*/
mlan_status woal_multi_ap_cfg(moal_private *priv, t_u8 wait_option, t_u8 flag)
{
mlan_status status = MLAN_STATUS_SUCCESS;
mlan_ioctl_req *req = NULL;
mlan_ds_misc_cfg *cfg = NULL;
ENTER();
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
if (req == NULL) {
status = MLAN_STATUS_FAILURE;
goto done;
}
cfg = (mlan_ds_misc_cfg *)req->pbuf;
cfg->param.multi_ap_flag = flag;
cfg->sub_command = MLAN_OID_MISC_MULTI_AP_CFG;
req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = MLAN_ACT_SET;
status = woal_request_ioctl(priv, req, wait_option);
if (status != MLAN_STATUS_SUCCESS)
goto done;
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return status;
}
#endif
/**
* @brief Set hotspot configuration value to mlan layer
*

View file

@ -1025,7 +1025,8 @@ void woal_clean_up(moal_handle *handle)
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev &&
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
priv->wdev->connected) {
#else
priv->wdev->current_bss) {
@ -1123,7 +1124,8 @@ static void woal_hang_work_queue(struct work_struct *work)
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev &&
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
priv->wdev->connected) {
#else
priv->wdev->current_bss) {
@ -5496,6 +5498,11 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index)
#endif
int i = 0;
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
int count = 0;
#endif
#endif
ENTER();
if (!priv || !priv->netdev)
@ -5597,6 +5604,18 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index)
if (IS_STA_OR_UAP_CFG80211(handle->params.cfg80211_wext))
priv->phandle->wiphy->extended_capabilities = NULL;
#endif
#ifdef UAP_SUPPORT
/* Clear the whole backhaul station list in moal */
for (count = 0; count < MAX_STA_COUNT; count++) {
if (priv->vlan_sta_list[count]) {
if (priv->vlan_sta_list[count]->is_valid)
unregister_netdevice(
priv->vlan_sta_list[count]->netdev);
kfree(priv->vlan_sta_list[count]);
}
priv->vlan_sta_list[count] = NULL;
}
#endif
#endif
priv->phandle->priv[priv->bss_index] = NULL;
priv->phandle = NULL;
@ -5981,6 +6000,9 @@ int woal_open(struct net_device *dev)
#endif /* < 2.6.34 */
#endif /* USB_SUSPEND_RESUME */
t_u8 carrier_on = MFALSE;
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
int cfg80211_wext = priv->phandle->params.cfg80211_wext;
#endif
ENTER();
@ -6048,6 +6070,13 @@ int woal_open(struct net_device *dev)
carrier_on = MTRUE;
#endif
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP_VLAN)
carrier_on = MTRUE;
}
#endif
if (carrier_on == MTRUE) {
if (!netif_carrier_ok(priv->netdev))
netif_carrier_on(priv->netdev);
@ -6085,6 +6114,18 @@ int woal_close(struct net_device *dev)
#endif
ENTER();
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
/** For multi-ap virtual interface */
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP_VLAN) {
woal_stop_queue(priv->netdev);
MODULE_PUT;
LEAVE();
return 0;
}
}
#endif
woal_flush_tx_stat_queue(priv);
if ((priv->media_connected == MTRUE)
@ -6108,7 +6149,8 @@ int woal_close(struct net_device *dev)
woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev->connected) {
#else
if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev->current_bss) {
@ -6227,6 +6269,13 @@ int woal_set_mac_address(struct net_device *dev, void *addr)
return -EFAULT;
}
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
/* No need to set mac address for multi-ap virtual interface */
if ((dev->ieee80211_ptr) &&
(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP_VLAN))
return 0;
#endif
moal_memcpy_ext(priv->phandle, prev_addr, priv->current_addr, ETH_ALEN,
ETH_ALEN);
memset(priv->current_addr, 0, ETH_ALEN);
@ -7505,6 +7554,66 @@ done:
#endif
#endif
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
/**
* @brief This function check if the packet is easymesh packet
*
* @param priv A pointer to moal_private structure
* @param skb A pointer to sk_buff structure
*
* @return MTRUE/MFALSE
*/
static BOOLEAN woal_check_easymesh_packet(moal_private *priv,
mlan_buffer *pmbuf)
{
struct sk_buff *skb = pmbuf->pdesc;
ENTER();
/** not construct 4 address if SA is same as local address */
if (!moal_memcmp(NULL, (skb->data + 6), priv->current_addr, ETH_ALEN)) {
PRINTM(MINFO,
"%s: SA is same as local address " FULL_MACSTR "\n",
__func__, FULL_MAC2STR(priv->current_addr));
LEAVE();
return MFALSE;
}
/* RA TA */
switch (priv->wdev->iftype) {
#ifdef UAP_SUPPORT
case NL80211_IFTYPE_AP_VLAN:
PRINTM(MDAT_D, "%s: Easymesh AP_VLAN\n", priv->netdev->name);
moal_memcpy_ext(priv->phandle, pmbuf->mac,
priv->vlan_sta_ptr->peer_mac,
MLAN_MAC_ADDR_LENGTH, ETH_ALEN);
pmbuf->flags |= MLAN_BUF_FLAG_EASYMESH;
break;
#endif
case NL80211_IFTYPE_STATION:
PRINTM(MDAT_D, "%s Easymesh STATION\n", priv->netdev->name);
moal_memcpy_ext(priv->phandle, pmbuf->mac, priv->cfg_bssid,
ETH_ALEN, ETH_ALEN);
pmbuf->flags |= MLAN_BUF_FLAG_EASYMESH;
break;
default:
PRINTM(MERROR, "Not supported iftype\n");
LEAVE();
return MFALSE;
}
PRINTM(MDAT_D,
"Easymesh Tx %s:\nRA: " FULL_MACSTR "\nTA: " FULL_MACSTR
"\nDA: " FULL_MACSTR "\nSA: " FULL_MACSTR "\n",
__func__, FULL_MAC2STR(pmbuf->mac),
FULL_MAC2STR(priv->current_addr), FULL_MAC2STR(skb->data),
FULL_MAC2STR(skb->data + ETH_ALEN));
LEAVE();
return MTRUE;
}
#endif
#endif
/**
* @brief This function handles packet transmission
*
@ -7523,6 +7632,12 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
#endif
int ret = 0;
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
BOOLEAN multi_ap_packet = MFALSE;
#endif
#endif
ENTER();
priv->num_tx_timeout = 0;
@ -7567,6 +7682,23 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
pmbuf->bss_index = priv->bss_index;
woal_fill_mlan_buffer(priv, pmbuf, skb);
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
if (priv->wdev->use_4addr) {
if ((priv->wdev->iftype == NL80211_IFTYPE_AP_VLAN &&
!priv->vlan_sta_ptr) ||
(priv->wdev->iftype == NL80211_IFTYPE_STATION &&
!priv->media_connected)) {
priv->stats.tx_dropped++;
dev_kfree_skb_any(skb);
LEAVE();
return;
}
multi_ap_packet = woal_check_easymesh_packet(priv, pmbuf);
}
#endif
#endif
if (priv->enable_tcp_ack_enh == MTRUE) {
ret = woal_process_tcp_ack(priv, pmbuf);
if (ret)
@ -7603,6 +7735,13 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb)
case MLAN_STATUS_PENDING:
atomic_inc(&priv->phandle->tx_pending);
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
if (priv->wdev->iftype == NL80211_IFTYPE_AP_VLAN)
priv = priv->parent_priv;
#endif
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
atomic_inc(&priv->wmm_tx_pending[index]);
if (atomic_read(&priv->wmm_tx_pending[index]) >=
@ -7906,6 +8045,12 @@ void woal_set_multicast_list(struct net_device *dev)
*/
void woal_init_priv(moal_private *priv, t_u8 wait_option)
{
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
int i;
#endif
#endif
ENTER();
#ifdef STA_SUPPORT
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
@ -7967,6 +8112,14 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option)
woal_init_wifi_hal(priv);
#endif
#endif
#endif
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
priv->vlan_sta_ptr = NULL;
for (i = 0; i < MAX_STA_COUNT; i++)
priv->vlan_sta_list[i] = NULL;
#endif
#endif
}
#endif
@ -8096,6 +8249,11 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option)
priv->chan_num_pkts = DEFAULT_RETRY_PKTS;
priv->user_cac_period_msec = 0;
priv->chan_under_nop = MFALSE;
#endif
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
priv->multi_ap_flag = 0;
#endif
#endif
LEAVE();
}
@ -9339,7 +9497,8 @@ t_void woal_send_disconnect_to_system(moal_private *priv,
if (IS_STA_CFG80211(cfg80211_wext)) {
spin_lock_irqsave(&priv->connect_lock, flags);
if (!priv->cfg_disconnect && !priv->cfg_connect && priv->wdev &&
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
priv->wdev->connected) {
#else
priv->wdev->current_bss) {

View file

@ -157,6 +157,7 @@ Change log:
#define CFG80211_VERSION_CODE MAX(LINUX_VERSION_CODE, COMPAT_VERSION_CODE)
#define IMX_ANDROID_13 0
#define IMX_ANDROID_12_BACKPORT 0
#if defined(IMX_SUPPORT)
#if defined(IMX_ANDROID)
@ -164,6 +165,10 @@ Change log:
#undef IMX_ANDROID_13
#define IMX_ANDROID_13 1
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 15, 41)
#undef IMX_ANDROID_12_BACKPORT
#define IMX_ANDROID_12_BACKPORT 1
#endif
#endif
#endif
@ -1412,6 +1417,27 @@ typedef struct _auto_zero_dfs_cfg {
t_u8 dfs_chan_list[MAX_DFS_CHAN_LIST];
} __ATTRIB_PACK__ auto_zero_dfs_cfg;
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
typedef struct _station_node {
/** station aid */
t_u16 aid;
/** station mac address */
t_u8 peer_mac[MLAN_MAC_ADDR_LENGTH];
/** net_device that station is bind to */
struct net_device *netdev;
/** is valid flag */
t_u8 is_valid;
} station_node;
#define EASY_MESH_MULTI_AP_FH_BSS (t_u8)(0x20)
#define EASY_MESH_MULTI_AP_BH_BSS (t_u8)(0x40)
#define EASY_MESH_MULTI_AP_BH_AND_FH_BSS (t_u8)(0x60)
#define EASY_MESH_MULTI_AP_BSS_MODE_1 (t_u8)(0x01)
#define EASY_MESH_MULTI_AP_BSS_MODE_2 (t_u8)(0x02)
#define EASY_MESH_MULTI_AP_BSS_MODE_3 (t_u8)(0x03)
#endif
/** Private structure for MOAL */
struct _moal_private {
/** Handle structure */
@ -1781,6 +1807,14 @@ struct _moal_private {
void *rings[RING_ID_MAX];
t_u8 pkt_fate_monitor_enable;
void *packet_filter;
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
t_u8 multi_ap_flag;
station_node *vlan_sta_ptr;
station_node *vlan_sta_list[MAX_STA_COUNT];
moal_private *parent_priv;
#endif
#endif
/** txwatchdog disable */
t_u8 txwatchdog_disable;
@ -4059,6 +4093,10 @@ void woal_hist_data_add(moal_private *priv, t_u16 rx_rate, t_s8 snr, t_s8 nflr,
mlan_status woal_set_hotspotcfg(moal_private *priv, t_u8 wait_option,
t_u32 hotspotcfg);
#if defined(STA_CFG80211)
mlan_status woal_multi_ap_cfg(moal_private *priv, t_u8 wait_option, t_u8 flag);
#endif
mlan_status woal_set_get_wowlan_config(moal_private *priv, t_u16 action,
t_u8 wait_option,
mlan_ds_misc_mef_flt_cfg *mefcfg);

View file

@ -148,6 +148,8 @@ static const struct pci_device_id wlan_ids[] = {
/* moal interface ops */
static moal_if_ops pcie_ops;
MODULE_DEVICE_TABLE(pci, wlan_ids);
/********************************************************
Global Variables
********************************************************/

View file

@ -135,6 +135,8 @@ static const struct sdio_device_id wlan_ids[] = {
{},
};
MODULE_DEVICE_TABLE(sdio, wlan_ids);
int woal_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id);
void woal_sdio_remove(struct sdio_func *func);
#ifdef SDIO

View file

@ -1886,6 +1886,32 @@ done:
#endif
#endif
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
/**
* @brief This function get binded net_device from station list
*
* @param priv Pointer to structure moal_private
* @param aid station aid from mlan
*
* @return binded net_device pointer or NULL if not found
*/
struct net_device *moal_get_netdev_from_stalist(moal_private *priv, t_u16 aid)
{
station_node *sta_node = NULL;
ENTER();
sta_node = priv->vlan_sta_list[(aid - 1) % MAX_STA_COUNT];
if (sta_node) {
LEAVE();
return sta_node->netdev;
}
LEAVE();
return NULL;
}
#endif
#endif
/**
* @brief This function uploads amsdu packet to the network stack
*
@ -2088,6 +2114,11 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
int j;
struct ethhdr *ethh = NULL;
struct net_device *netdev = NULL;
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
t_u16 aid = 0;
#endif
#endif
ENTER();
if (pmbuf) {
@ -2204,6 +2235,23 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
priv->deauth_evt_cnt = 0;
#endif
}
#ifdef UAP_SUPPORT
#if defined(UAP_CFG80211) || defined(STA_CFG80211)
if (pmbuf->flags & MLAN_BUF_FLAG_EASYMESH) {
aid = (pmbuf->priority & 0xFF000000) >> 24;
if (!priv->vlan_sta_list[(aid - 1) %
MAX_STA_COUNT]
->is_valid) {
status = MLAN_STATUS_FAILURE;
priv->stats.rx_dropped++;
goto done;
}
if (aid != 0)
netdev = moal_get_netdev_from_stalist(
priv, aid);
}
#endif
#endif
if (!netdev)
netdev = priv->netdev;
skb->dev = netdev;
@ -3593,7 +3641,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
|| priv->uap_host_based
#endif
#ifdef STA_CFG80211
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
|| priv->wdev->connected
#else
|| priv->wdev->current_bss
@ -3741,7 +3790,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0,
0);
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
IMX_ANDROID_13 || IMX_ANDROID_12_BACKPORT)
cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0);
#else
cfg80211_ch_switch_notify(priv->netdev, &priv->chan);
@ -4076,7 +4126,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
PRINTM(MEVENT,
"HostMlme %s: Receive deauth/disassociate\n",
priv->netdev->name);
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
if (!priv->wdev->connected) {
#else
if (!priv->wdev->current_bss) {
@ -4474,7 +4525,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
roam_info =
kzalloc(sizeof(struct cfg80211_roam_info), GFP_ATOMIC);
if (roam_info) {
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
roam_info->links[0].bssid = priv->cfg_bssid;
#else
roam_info->bssid = priv->cfg_bssid;

View file

@ -103,7 +103,8 @@ static int woal_cfg80211_dump_survey(struct wiphy *wiphy,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static int woal_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
unsigned int link_id,
#endif
struct cfg80211_chan_def *chandef);
@ -907,6 +908,9 @@ static int woal_cfg80211_assoc_ies_cfg(moal_private *priv, t_u8 *ie,
t_u8 wps_oui[] = {0x00, 0x50, 0xf2, 0x04};
t_u8 hs20_oui[] = {0x50, 0x6f, 0x9a, 0x10};
t_u8 multiap_oui[] = {0x50, 0x6f, 0x9a, 0x1b};
t_u8 multiap_flag = 0;
while (bytes_left >= 2) {
element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
element_len = *((t_u8 *)pcurrent_ptr + 1);
@ -944,6 +948,21 @@ static int woal_cfg80211_assoc_ies_cfg(moal_private *priv, t_u8 *ie,
}
}
if (!memcmp(pvendor_ie->vend_hdr.oui, multiap_oui,
sizeof(pvendor_ie->vend_hdr.oui)) &&
(pvendor_ie->vend_hdr.oui_type == multiap_oui[3])) {
multiap_flag = pvendor_ie->data[0];
if (MLAN_STATUS_SUCCESS !=
woal_multi_ap_cfg(priv, wait_option,
multiap_flag)) {
PRINTM(MERROR,
"%s: failed to configure multi ap\n",
__func__);
ret = -EFAULT;
goto done;
}
}
if (!memcmp(pvendor_ie->vend_hdr.oui, hs20_oui,
sizeof(pvendor_ie->vend_hdr.oui)) &&
(pvendor_ie->vend_hdr.oui_type == hs20_oui[3])) {
@ -5490,7 +5509,8 @@ static int woal_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
if (priv->media_connected == MFALSE) {
PRINTM(MMSG, " Already disconnected\n");
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
if (priv->wdev->connected &&
#else
if (priv->wdev->current_bss &&
@ -5820,7 +5840,8 @@ done:
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static int woal_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
unsigned int link_id,
#endif
struct cfg80211_chan_def *chandef)
@ -8593,8 +8614,41 @@ static int woal_cfg80211_change_station(struct wiphy *wiphy,
struct station_parameters *params)
{
int ret = 0;
#ifdef UAP_SUPPORT
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
moal_private *vlan_priv = NULL;
station_node *sta_node = NULL;
int i = 0;
#endif
ENTER();
#ifdef UAP_SUPPORT
/** Bind the station to uap virtual interface and
save the station info in moal_private */
if (params->vlan) {
if (params->vlan->ieee80211_ptr &&
params->vlan->ieee80211_ptr->iftype ==
NL80211_IFTYPE_AP_VLAN) {
vlan_priv = (moal_private *)woal_get_netdev_priv(
params->vlan);
for (i = 0; i < MAX_STA_COUNT; i++) {
sta_node = priv->vlan_sta_list[i];
if (sta_node &&
!moal_memcmp(priv->phandle,
sta_node->peer_mac, mac,
MLAN_MAC_ADDR_LENGTH)) {
PRINTM(MCMND,
"wlan: Easymesh change station aid=%d\n",
sta_node->aid);
sta_node->netdev = params->vlan;
sta_node->is_valid = MTRUE;
vlan_priv->vlan_sta_ptr = sta_node;
break;
}
}
}
}
#endif
/**do nothing*/
LEAVE();
@ -8625,12 +8679,29 @@ static int woal_cfg80211_add_station(struct wiphy *wiphy,
{
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
int ret = 0;
station_node *sta_node = NULL;
ENTER();
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
#ifdef UAP_SUPPORT
if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME) &&
(priv->bss_role == MLAN_BSS_ROLE_UAP)) {
sta_node = kmalloc(sizeof(station_node), GFP_KERNEL);
if (!sta_node) {
PRINTM(MERROR,
"Failed to alloc memory for station node\n");
LEAVE();
return -ENOMEM;
}
memset(sta_node, 0, sizeof(*sta_node));
moal_memcpy_ext(priv->phandle, sta_node->peer_mac, mac,
MLAN_MAC_ADDR_LENGTH, ETH_ALEN);
sta_node->netdev = dev;
sta_node->aid = params->aid;
sta_node->is_valid = MFALSE;
/** AID should start from 1 to MAX_STA_COUNT */
priv->vlan_sta_list[(params->aid - 1) % MAX_STA_COUNT] =
sta_node;
ret = woal_cfg80211_uap_add_station(wiphy, dev, (u8 *)mac,
params);
LEAVE();
@ -8749,7 +8820,8 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev,
passoc_rsp = (IEEEtypes_AssocRsp_t *)
assoc_rsp->assoc_resp_buf;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
roam_info.links[0].bssid = priv->cfg_bssid;
#else
roam_info.bssid = priv->cfg_bssid;
@ -9221,7 +9293,8 @@ void woal_start_roaming(moal_private *priv)
}
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
roam_info.links[0].bssid = priv->cfg_bssid;
#else
roam_info.bssid = priv->cfg_bssid;
@ -10034,8 +10107,9 @@ mlan_status woal_register_cfg80211(moal_private *priv)
wiphy->max_scan_ssids = MRVDRV_MAX_SSID_LIST_LENGTH;
wiphy->max_scan_ie_len = MAX_IE_SIZE;
wiphy->interface_modes = 0;
wiphy->interface_modes =
MBIT(NL80211_IFTYPE_STATION) | MBIT(NL80211_IFTYPE_AP);
wiphy->interface_modes = MBIT(NL80211_IFTYPE_STATION) |
MBIT(NL80211_IFTYPE_AP_VLAN) |
MBIT(NL80211_IFTYPE_AP);
wiphy->interface_modes |= MBIT(NL80211_IFTYPE_MONITOR);
#ifdef WIFI_DIRECT_SUPPORT
@ -10197,6 +10271,8 @@ mlan_status woal_register_cfg80211(moal_private *priv)
if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME))
wiphy->features |= NL80211_FEATURE_SAE;
#endif
wiphy->flags |= WIPHY_FLAG_4ADDR_AP;
wiphy->flags |= WIPHY_FLAG_4ADDR_STATION;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
#endif

View file

@ -4111,6 +4111,61 @@ done:
return ret;
}
#if defined(UAP_CFG80211)
#if defined(STA_WEXT) || defined(UAP_WEXT)
/**
* @brief Set/Get multi AP mode
*
* @param priv A pointer to moal_private structure
* @param wrq A pointer to structure iwreq
*
* @return 0 --success, otherwise fail
*/
int woal_uap_set_get_multi_ap_mode(moal_private *priv, struct iwreq *wrq)
{
int ret = 0;
int mode = 0;
ENTER();
if (wrq->u.data.length) {
if (wrq->u.data.length > 1) {
PRINTM(MERROR, "Invalid no of arguments!\n");
ret = -EINVAL;
goto done;
}
if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
PRINTM(MERROR, "copy from user failed\n");
ret = -EFAULT;
goto done;
}
if (mode == EASY_MESH_MULTI_AP_BSS_MODE_3)
/* Supports backhaul and fronthaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_BH_AND_FH_BSS;
else if (mode == EASY_MESH_MULTI_AP_BSS_MODE_2)
/* Supports backhaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_BH_BSS;
else if (mode == EASY_MESH_MULTI_AP_BSS_MODE_1)
/* Supports fronthaul BSS */
priv->multi_ap_flag = EASY_MESH_MULTI_AP_FH_BSS;
} else {
if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_AND_FH_BSS)
mode = EASY_MESH_MULTI_AP_BSS_MODE_3;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_BH_BSS)
mode = EASY_MESH_MULTI_AP_BSS_MODE_2;
else if (priv->multi_ap_flag == EASY_MESH_MULTI_AP_FH_BSS)
mode = EASY_MESH_MULTI_AP_BSS_MODE_1;
wrq->u.data.length = 1;
if (copy_to_user(wrq->u.data.pointer, &mode, sizeof(int)))
ret = -EFAULT;
}
done:
LEAVE();
return ret;
}
#endif
#endif
/**
* @brief Set AP configuration
*

View file

@ -588,6 +588,12 @@ mlan_status woal_set_get_ap_wmm_para(moal_private *priv, t_u16 action,
wmm_parameter_t *ap_wmm_para);
int woal_uap_set_ap_cfg(moal_private *priv, t_u8 *data, int len);
#if defined(UAP_CFG80211)
#if defined(STA_WEXT) || defined(UAP_WEXT)
int woal_uap_set_get_multi_ap_mode(moal_private *priv, struct iwreq *wrq);
#endif
#endif
int woal_uap_set_11ac_status(moal_private *priv, t_u8 action, t_u8 vht20_40,
IEEEtypes_VHTCap_t *vhtcap_ie);
int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg,

View file

@ -31,6 +31,7 @@
/********************************************************
Global Variables
********************************************************/
extern const struct net_device_ops woal_uap_netdev_ops;
/********************************************************
Local Functions
********************************************************/
@ -1443,6 +1444,11 @@ static int woal_cfg80211_beacon_config(moal_private *priv,
sys_config->sta_ageout_timer, sys_config->ps_sta_ageout_timer);
#endif
if (priv->multi_ap_flag) {
sys_config->multi_ap_flag = priv->multi_ap_flag;
PRINTM(MINFO, "%s: multi_ap_flag is 0x%x\n", __func__,
sys_config->multi_ap_flag);
}
if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv, MLAN_ACT_SET,
MOAL_IOCTL_WAIT,
sys_config)) {
@ -1605,7 +1611,12 @@ static int woal_cfg80211_add_mon_if(struct wiphy *wiphy,
}
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
ret = cfg80211_register_netdevice(ndev);
#else
ret = register_netdevice(ndev);
#endif
if (ret) {
PRINTM(MFATAL, "register net_device failed, ret=%d\n", ret);
free_netdev(ndev);
@ -1622,6 +1633,167 @@ fail:
return ret;
}
/**
* @brief This function setup the multi-ap virtual interface
*
* @param dev A pointer to structure net_device
*
* @return N/A
*/
static void woal_vlan_virt_if_setup(struct net_device *dev)
{
ENTER();
ether_setup(dev);
dev->netdev_ops = &woal_uap_netdev_ops;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 9)
dev->needs_free_netdev = true;
#else
dev->destructor = free_netdev;
#endif
LEAVE();
}
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
/**
* @brief Request the driver to add a multi-ap virtual interface
*
* @param wiphy A pointer to wiphy structure
* @param name Virtual interface name
* @param name_assign_type Interface name assignment type
* @param flags Flags for the virtual interface
* @param params A pointer to vif_params structure
* @param new_dev new net_device to return
*
* @return 0 -- success, otherwise fail
*/
static int woal_cfg80211_add_vlan_vir_if(struct wiphy *wiphy, const char *name,
unsigned char name_assign_type,
#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
u32 *flags,
#endif
struct vif_params *params,
struct net_device **new_dev)
#else
/**
* @brief Request the driver to add a multi-ap virtual interface
*
* @param wiphy A pointer to wiphy structure
* @param name Virtual interface name
* @param flags Flags for the virtual interface
* @param params A pointer to vif_params structure
* @param new_dev new net_device to return
*
* @return 0 -- success, otherwise fail
*/
static int woal_cfg80211_add_vlan_vir_if(struct wiphy *wiphy,
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
const
#endif
char *name,
u32 *flags, struct vif_params *params,
struct net_device **new_dev)
#endif
{
int ret = 0;
moal_handle *handle = (moal_handle *)woal_get_wiphy_priv(wiphy);
moal_private *priv =
(moal_private *)woal_get_priv(handle, MLAN_BSS_ROLE_UAP);
moal_private *new_priv = NULL;
struct net_device *ndev = NULL;
ENTER();
ASSERT_RTNL();
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
#ifndef MAX_WMM_QUEUE
#define MAX_WMM_QUEUE 4
#endif
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
ndev = alloc_netdev_mq(sizeof(moal_private), name, name_assign_type,
woal_vlan_virt_if_setup, 1);
#else
ndev = alloc_netdev_mq(sizeof(moal_private), name, NET_NAME_UNKNOWN,
woal_vlan_virt_if_setup, 1);
#endif
#else
ndev = alloc_netdev_mq(sizeof(moal_private), name,
woal_vlan_virt_if_setup, 1);
#endif
#else
ndev = alloc_netdev_mq(sizeof(moal_private), name,
woal_vlan_virt_if_setup);
#endif
if (!ndev) {
PRINTM(MFATAL, "Init virtual ethernet device failed\n");
ret = -EFAULT;
goto fail;
}
ret = dev_alloc_name(ndev, ndev->name);
if (ret < 0) {
PRINTM(MFATAL, "Net device alloc name fail.\n");
ret = -EFAULT;
goto fail;
}
dev_net_set(ndev, wiphy_net(wiphy));
moal_memcpy_ext(handle, ndev->perm_addr, wiphy->perm_addr, ETH_ALEN,
sizeof(ndev->perm_addr));
moal_memcpy_ext(handle, ndev->perm_addr, priv->current_addr, ETH_ALEN,
sizeof(ndev->perm_addr));
moal_memcpy_ext(handle, (t_void *)ndev->dev_addr, ndev->perm_addr,
ETH_ALEN, MAX_ADDR_LEN);
SET_NETDEV_DEV(ndev, wiphy_dev(wiphy));
ndev->watchdog_timeo = MRVDRV_DEFAULT_UAP_WATCHDOG_TIMEOUT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
ndev->needed_headroom += MLAN_MIN_DATA_HEADER_LEN +
sizeof(mlan_buffer) + priv->extra_tx_head_len;
#else
ndev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN +
sizeof(mlan_buffer) + priv->extra_tx_head_len;
#endif
ndev->flags |= IFF_BROADCAST | IFF_MULTICAST;
new_priv = netdev_priv(ndev);
ndev->ieee80211_ptr = &new_priv->w_dev;
new_priv->wdev = &new_priv->w_dev;
new_priv->netdev = ndev;
new_priv->extra_tx_head_len = priv->extra_tx_head_len;
moal_memcpy_ext(priv->phandle, new_priv->current_addr,
priv->current_addr, ETH_ALEN, ETH_ALEN);
new_priv->phandle = handle;
new_priv->wdev->wiphy = handle->wiphy;
new_priv->bss_type = MLAN_BSS_TYPE_UAP;
new_priv->bss_role = MLAN_BSS_ROLE_UAP;
new_priv->bss_index = priv->bss_index;
new_priv->parent_priv = priv;
new_priv->wdev->iftype = NL80211_IFTYPE_AP_VLAN;
ndev->ieee80211_ptr->use_4addr = params->use_4addr;
ret = register_netdevice(ndev);
if (ret) {
PRINTM(MFATAL, "register net_device failed, ret=%d\n", ret);
free_netdev(ndev);
goto fail;
}
if (new_dev)
*new_dev = ndev;
fail:
LEAVE();
return ret;
}
#ifdef WIFI_DIRECT_SUPPORT
#if CFG80211_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION
/**
@ -2304,6 +2476,20 @@ woal_cfg80211_add_virtual_intf(struct wiphy *wiphy, const char *name,
ret = -EFAULT;
}
break;
case NL80211_IFTYPE_AP_VLAN:
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
ret = woal_cfg80211_add_vlan_vir_if(
wiphy, name, name_assign_type, flags, params, &ndev);
#else
ret = woal_cfg80211_add_vlan_vir_if(
wiphy, name, name_assign_type, params, &ndev);
#endif
#else
ret = woal_cfg80211_add_vlan_vir_if(wiphy, name, flags, params,
&ndev);
#endif
break;
default:
PRINTM(MWARN, "Not supported if type: %d\n", type);
ret = -EFAULT;
@ -2360,6 +2546,9 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
struct net_device *dev = wdev->netdev;
#endif
moal_private *vlan_priv = NULL;
t_u16 aid = 0;
ENTER();
PRINTM(MIOCTL, "del virtual intf %s\n", dev->name);
@ -2384,6 +2573,26 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
return ret;
}
#ifdef UAP_SUPPORT
/**
* For multi-ap virtual interface, unregister netdevice
* directly for now. Will add more in the future.
*/
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP_VLAN) {
/* stop network before doing cleanup */
if (netif_carrier_ok(dev))
netif_carrier_off(dev);
vlan_priv = (moal_private *)netdev_priv(dev);
aid = vlan_priv->vlan_sta_ptr->aid;
PRINTM(MCMND, "wlan: Easymesh del Vlan aid=%d\n", aid);
vlan_priv->parent_priv->vlan_sta_list[(aid - 1) % MAX_STA_COUNT]
->is_valid = MFALSE;
unregister_netdevice(dev);
LEAVE();
return ret;
}
#endif
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
for (i = 0; i < handle->priv_num; i++) {
vir_priv = handle->priv[i];
@ -2397,7 +2606,8 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
}
}
if (vir_priv && vir_priv->bss_type == MLAN_BSS_TYPE_UAP) {
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
if (woal_cfg80211_del_beacon(wiphy, dev, 0))
#else
if (woal_cfg80211_del_beacon(wiphy, dev))
@ -2405,13 +2615,15 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
PRINTM(MERROR, "%s: del_beacon failed\n",
__func__);
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
vir_priv->wdev->links[0].ap.beacon_interval = 0;
#else
vir_priv->wdev->beacon_interval = 0;
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
memset(&vir_priv->wdev->links[0].ap.chandef, 0,
sizeof(vir_priv->wdev->links[0].ap.chandef));
#else
@ -2420,7 +2632,8 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy,
#endif
#endif
#endif
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
vir_priv->wdev->u.ap.ssid_len = 0;
#else
vir_priv->wdev->ssid_len = 0;
@ -2699,7 +2912,8 @@ done:
*
* @return 0 -- success, otherwise fail
*/
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13 || \
IMX_ANDROID_12_BACKPORT)
int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id)
#else
@ -2711,6 +2925,7 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
#ifdef STA_SUPPORT
moal_private *pmpriv = NULL;
#endif
int i;
ENTER();
@ -2791,6 +3006,19 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
priv->cipher = 0;
memset(priv->uap_wep_key, 0, sizeof(priv->uap_wep_key));
priv->channel = 0;
#ifdef UAP_SUPPORT
priv->multi_ap_flag = 0;
/* Clear the whole backhaul station list in moal */
for (i = 0; i < MAX_STA_COUNT; i++) {
if (priv->vlan_sta_list[i]) {
if (priv->vlan_sta_list[i]->is_valid)
unregister_netdevice(
priv->vlan_sta_list[i]->netdev);
kfree(priv->vlan_sta_list[i]);
}
priv->vlan_sta_list[i] = NULL;
}
#endif
PRINTM(MMSG, "wlan: AP stopped\n");
done:
LEAVE();
@ -3500,7 +3728,8 @@ static void woal_switch_uap_channel(moal_private *priv, t_u8 wait_option)
sizeof(struct cfg80211_chan_def), sizeof(priv->chan));
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0, 0);
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
#elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
IMX_ANDROID_13 || IMX_ANDROID_12_BACKPORT)
cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0);
#else
cfg80211_ch_switch_notify(priv->netdev, &priv->chan);

View file

@ -119,6 +119,16 @@ int woal_uap_do_priv_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = woal_set_get_bss_role(priv, wrq);
break;
#endif
#endif
#if defined(UAP_CFG80211)
#if defined(STA_WEXT) || defined(UAP_WEXT)
case WOAL_UAP_SET_MODE:
PRINTM(MINFO,
"%s: setting multi_ap flag through user command\n",
__func__);
ret = woal_uap_set_get_multi_ap_mode(priv, wrq);
break;
#endif
#endif
default:
ret = -EINVAL;

View file

@ -65,6 +65,11 @@ Change log:
#endif
#endif
#if defined(UAP_CFG80211)
/** Private command ID for set multi-AP BSS mode */
#define WOAL_UAP_SET_MODE 27
#endif
/** Private command ID for hostcmd */
#define WOAL_UAP_HOST_CMD (WOAL_UAP_IOCTL + 17)

View file

@ -84,6 +84,10 @@ static const struct iw_priv_args woal_uap_priv_args[] = {
#endif
#endif
#if defined(UAP_CFG80211)
{WOAL_UAP_SET_MODE, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_INT | 1,
"setmode"},
#endif
{WOAL_UAP_SET_GET_256_CHAR, IW_PRIV_TYPE_CHAR | 256,
IW_PRIV_TYPE_CHAR | 256, ""},
{WOAL_WL_FW_RELOAD, IW_PRIV_TYPE_CHAR | 256, IW_PRIV_TYPE_CHAR | 256,