From 000443c54debb3077afa967c3f2a629e6fe6468f Mon Sep 17 00:00:00 2001 From: yunjie Date: Thu, 8 Jun 2023 17:32:31 +0000 Subject: [PATCH] MA-21223-1 integrate WCS Q2 release code Reason: integrate WCS Q2 RC2 release Wlan Driver Test: on i.MX8M Mini Change-Id: I26708abf7a7be223a7bd2070c6efd2a17c1be745 Signed-off-by: yunjie --- mxm_wifiex/wlan_src/Makefile | 31 +- mxm_wifiex/wlan_src/README | 665 +++++++++++++++++- mxm_wifiex/wlan_src/mlan/mlan_decl.h | 6 +- mxm_wifiex/wlan_src/mlan/mlan_fw.h | 21 + mxm_wifiex/wlan_src/mlan/mlan_init.c | 1 + mxm_wifiex/wlan_src/mlan/mlan_ioctl.h | 5 + mxm_wifiex/wlan_src/mlan/mlan_join.c | 14 + mxm_wifiex/wlan_src/mlan/mlan_main.h | 8 + mxm_wifiex/wlan_src/mlan/mlan_misc.c | 26 + mxm_wifiex/wlan_src/mlan/mlan_sta_event.c | 1 + mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c | 3 + mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c | 7 + mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c | 5 + mxm_wifiex/wlan_src/mlan/mlan_txrx.c | 54 ++ mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c | 13 + mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c | 27 +- mxm_wifiex/wlan_src/mlan/mlan_wmm.c | 9 +- mxm_wifiex/wlan_src/mlinux/mlan_decl.h | 6 +- mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h | 5 + mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c | 44 +- mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h | 10 +- mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c | 120 ++++ mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h | 3 + mxm_wifiex/wlan_src/mlinux/moal_ioctl.c | 42 ++ mxm_wifiex/wlan_src/mlinux/moal_main.c | 167 ++++- mxm_wifiex/wlan_src/mlinux/moal_main.h | 38 + mxm_wifiex/wlan_src/mlinux/moal_shim.c | 60 +- .../wlan_src/mlinux/moal_sta_cfg80211.c | 90 ++- mxm_wifiex/wlan_src/mlinux/moal_uap.c | 55 ++ mxm_wifiex/wlan_src/mlinux/moal_uap.h | 6 + .../wlan_src/mlinux/moal_uap_cfg80211.c | 241 ++++++- mxm_wifiex/wlan_src/mlinux/moal_uap_priv.c | 10 + mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h | 5 + mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c | 4 + 34 files changed, 1752 insertions(+), 50 deletions(-) diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index 376d747..74d9904 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -54,9 +54,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 @@ -277,9 +280,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 @@ -313,9 +320,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 @@ -337,10 +344,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 diff --git a/mxm_wifiex/wlan_src/README b/mxm_wifiex/wlan_src/README index 4cfad44..08ca659 100755 --- a/mxm_wifiex/wlan_src/README +++ b/mxm_wifiex/wlan_src/README @@ -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= +#ifdef DEBUG_LOG + logctrl= + sh_mem_size= +#endif +#endif dev_cap_mask= mac_addr=xx:xx:xx:xx:xx:xx +#if defined(OPTIMIZED_PS) && defined(DEEP_SLEEP) auto_ds=0|1|2 +#endif +#if defined(EXT_SCAN_SUPPORT) && defined(EXT_SCAN_ENH) ext_scan=0|1|2 +#endif net_rx=0|1 amsdu_deaggr=0|1 +#ifdef ENABLE_802_11P + max_11p_bss = +#endif ps_mode=0|1|2 sched_scan=0|1 max_tx_buf=2048|4096|8192 +#ifdef SDIO_SUSPEND_RESUME pm_keep_power=1|0 shutdown_hs=1|0 +#endif +#ifdef ENABLE_802_11D cfg_11d=0|1|2 +#endif +#ifdef CONFIG_OF dts_enable=0|1 +#endif +#ifdef FW_DNLD_NEEDED fw_name = e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin +#endif hw_name = reg_work=0|1 hw_test=0|1 fw_serial=0|1 req_fw_nowait=0|1 +#if !defined(MLANUTL_LITE) +#ifdef DFS_SUPPORT dfs53cfg=0|1|2 +#endif mcs32=0|1 +#ifdef SDIOXXX SD8887: antcfg=0|1|2|0xffff SD8897/SD8997: antcfg=0x11|0x13|0x33 +#else +#ifdef SD8887 + antcfg=0|1|2|0xffff +#else +#if defined(SD8897) || defined(SD8997)||defined(SD9098) ||defined(SD9097)||defined(SDIW624) + antcfg=0x11|0x13|0x33 +#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= e.g. copy init_cfg.conf to firmware directory, init_cfg=nxp/init_cfg.conf cal_data_cfg= 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= e.g. copy dpd_data.conf to firmware directory, dpd_data_cfg=nxp/dpd_data.conf +#endif +#ifdef TX_POWERCFG txpwrlimit_cfg= 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= e.g. copy init_hostcmd_cfg.conf to firmware directory, init_hostcmd_cfg=nxp/init_hostcmd_cfg.conf band_steer_cfg= 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 +#endif +#ifdef SUSPEND_SDIO_PULL_DOWN + sdio_pd=0|1 +#endif +#ifdef SDIO_SP_RX_AGGR sdio_rx_aggr=1|0 +#endif +#ifdef T3T +#ifdef SDIO + minicard_pwrup=1|0 +#endif +#endif +#ifdef SIMU_CFG80211_WEXT cfg80211_wext= +#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 +#endif reg_alpha2= +#ifdef USB_NEW_FW_DNLD skip_fwdnld=0|1 +#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 +#endif +#ifdef PCIE +#if defined(PCIE) && defined(PCIE_MSIX) pcie_int_mode=0|1|2 +#elif defined(PCIE_MSI) pcie_int_mode=0|1 +#else + pcie_int_mode=0 +#endif +#if defined(PCIE9098) ||defined(PCIE9097)||defined(PCIEIW624) ring_size=32|64|128|256|512 +#endif +#endif +#if !defined(MLANUTL_LITE) +#ifdef AGGR_CTRL aggrctrl=1|0 +#endif +#endif /* !defined(MLANUTL_LITE) */ +#if defined(USB_TX_AGGR) || defined(USB_RX_DEAGGR) usb_aggr=0|1|2 +#endif +#if defined WLAN_LOW_POWER_ENABLE low_power_mode_enable=0|1 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= +#else wakelock_timeout= +#endif +#endif +#ifdef V16_FW_API pmic=0|1 +#endif +#ifdef HS_SUPPORT indication_gpio=0xXY hs_wake_interval= disconnect_on_suspend=0|1 +#ifdef HS_MIMO_SWITCH hs_mimo_switch=0|1 +#endif +#endif +#if defined(HS_SUPPORT) || defined(UAP_HS_SUPPORT) hs_auto_arp=0|1 +#endif +#ifdef GTK_REKEY_OFFLOAD gtk_rekey_offload=0|1|2 +#endif +#ifdef NAPI_SUPPORT napi=0|1 +#endif fixed_beacon_buffer=0|1 +#ifdef WIFI_DIRECT_SUPPORT GoAgeoutTime=0|x +#endif multi_dtim=0|x inact_tmo=0|x +#ifdef MULTI_CHAN_SUPPORT drcs_chantime_mode=0|x Bit31~Bit24:Channel time for channel index0; Bit23~Bit16:mode for channel index0; 0|1 Bit15~Bit8:Channel time for channel index1; Bit7~Bit0:mode for channel index1; 0|1 +#endif +#ifdef FW_ROAMING roamoffload_in_hs=0|1 +#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 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 beacon_hints=0|1 +#endif chan_track=0|1 for 9098 only keep_previous_scan=0|1, @@ -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 = +#endif wmm_ac_vo = wmm_ac_vi = wmm_ac_be = @@ -211,16 +739,30 @@ tx_buf_size = curr_tx_buf_size = 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 = +#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 = +#ifdef WMM_UAPSD pps_uapsd_mode = <0/1, PPS/UAPSD mode disabled/enabled> // Only for STA sleep_pd = // Only for STA qos_cfg = // 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 = num_cmd_sleep_cfm_fail = num_tx_h2c_fail = +#ifdef SDIO num_cmdevt_c2h_fail = num_rx_c2h_fail = num_int_read_fail = last_int_status = +#endif num_evt_deauth = // Only for STA num_evt_disassoc = // Only for STA num_evt_link_lost = // Only for STA @@ -256,31 +800,45 @@ curr_rd_port = mp_wr_bitmap = curr_wr_port = +#ifdef PCIE txbd_rdptr = txbd_wrptr = rxbd_rdptr = rxbd_wrptr = eventbd_rdptr = eventbd_wrptr = +#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 = tx_data_urb_pending = +#ifdef USB_CMD_DATA_EP rx_cmd_urb_pending = +#endif rx_data_urb_pending = +#endif ioctl_pending = tx_pending = rx_pending = lock_count = malloc_count = mbufalloc_count = +#ifdef PCIE malloc_cons_count = +#endif main_state = +#ifdef SDIO_MMC_DEBUG sdiocmd53w = sdiocmd53r = +#endif +#if defined(USB_SUSPEND_RESUME) || defined(SDIO_SUSPEND_RESUME) hs_skip_count = hs_force_count = +#endif +#if !defined(MLANUTL_LITE) +#ifdef SDIO Issue SDIO cmd52 read/write through proc. Usage: echo "sdcmd52rw= [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= " - 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 + diff --git a/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/mxm_wifiex/wlan_src/mlan/mlan_decl.h index e1b1d42..53eefff 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_decl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_decl.h @@ -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; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/mxm_wifiex/wlan_src/mlan/mlan_fw.h index fe66b5d..1d8dd99 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -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 */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_init.c b/mxm_wifiex/wlan_src/mlan/mlan_init.c index 38f70f6..ebd48c3 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_init.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_init.c @@ -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)) { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index 062b239..877cb25 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -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 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_join.c b/mxm_wifiex/wlan_src/mlan/mlan_join.c index b63c45c..d6e77cd 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_join.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_join.c @@ -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; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_main.h b/mxm_wifiex/wlan_src/mlan/mlan_main.h index 0e19825..8675f73 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -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); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_misc.c b/mxm_wifiex/wlan_src/mlan/mlan_misc.c index f53e4fc..5e3ac51 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_misc.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_misc.c @@ -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 diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c index 9d3b8fe..2bc5517 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c @@ -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; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c index 8959f6a..b6dfd1e 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c @@ -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; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c index 5e49e0a..671f176 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c @@ -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) != diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c index 49ff34d..7f274b0 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c @@ -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); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_txrx.c b/mxm_wifiex/wlan_src/mlan/mlan_txrx.c index c55c145..d97e36d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_txrx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_txrx.c @@ -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; +} diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index 12cc203..e89f291 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -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) diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c index b68ae09..6f3201e 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c @@ -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) { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c index 1f345c0..17e9a46 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c @@ -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)); diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index e1b1d42..53eefff 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h @@ -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; diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index 062b239..877cb25 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -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 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c index de24a92..928d22f 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c @@ -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, @@ -5046,7 +5083,8 @@ void woal_cfg80211_notify_channel(moal_private *priv, cfg80211_ch_switch_notify(priv->netdev, &chandef, 0, 0); #elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) && IMX_ANDROID_13)) 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, &chandef, 0); #else cfg80211_ch_switch_notify(priv->netdev, &chandef); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h index d658442..402c1aa 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h @@ -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 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index dbad2ed..1a379a4 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -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, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index e9a09b9..9eca736 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -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" diff --git a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index 4fc7873..8a98b31 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -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 * diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.c b/mxm_wifiex/wlan_src/mlinux/moal_main.c index 0286c43..0cee5e1 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -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) { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.h b/mxm_wifiex/wlan_src/mlinux/moal_main.h index 69f7db7..45324e7 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -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); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/mxm_wifiex/wlan_src/mlinux/moal_shim.c index 59192c0..063c7eb 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -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 @@ -3743,7 +3792,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) 0); #elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) && IMX_ANDROID_13)) 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); @@ -4078,7 +4128,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) { @@ -4476,7 +4527,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; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index 84ab167..bf39f0e 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -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 diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.c b/mxm_wifiex/wlan_src/mlinux/moal_uap.c index fe5d259..66207aa 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.c @@ -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 * diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.h b/mxm_wifiex/wlan_src/mlinux/moal_uap.h index 5719f66..1c4d25c 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.h @@ -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, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c index 34cade2..13d507b 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c @@ -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(); @@ -3502,7 +3730,8 @@ static void woal_switch_uap_channel(moal_private *priv, t_u8 wait_option) cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0, 0); #elif ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) && IMX_ANDROID_13)) 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); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.c index b28e0db..ab503b2 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.c @@ -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; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h index 4eab2f5..c49d36a 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_priv.h @@ -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) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c index aa4dc78..5fe4926 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c @@ -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,