From 9bbd4d8c5266bc122e391ff693c6e994ac0cb736 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Tue, 20 Dec 2022 15:45:49 +0800 Subject: [PATCH] mxm_wifiex: update to mxm5x17368 release Driver Bug Fixes: ----------------- 1. WCSWREL-357: WiFi crash when enable Android Global CFI configuration 2. WSW-23818: DUT setup DFS channel failed 3. WSW-20079: Tx RvR and TP Improvement 4. WSW-23330: Fix P2P-GO start failure post auto recovery 5. WSW-22914: Fixed WiFiHAL can't print hotfix release version Signed-off-by: Sherry Sun --- mxm_wifiex/wlan_src/Makefile | 57 ++ mxm_wifiex/wlan_src/README_MLAN | 126 +++-- mxm_wifiex/wlan_src/mlan/mlan_11ax.c | 8 +- mxm_wifiex/wlan_src/mlan/mlan_11h.c | 34 +- mxm_wifiex/wlan_src/mlan/mlan_11n.c | 15 + mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.c | 6 +- mxm_wifiex/wlan_src/mlan/mlan_cfp.c | 3 - mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c | 500 +++++++++++++++++- mxm_wifiex/wlan_src/mlan/mlan_decl.h | 24 +- mxm_wifiex/wlan_src/mlan/mlan_fw.h | 123 ++++- mxm_wifiex/wlan_src/mlan/mlan_ieee.h | 14 + mxm_wifiex/wlan_src/mlan/mlan_init.c | 8 +- mxm_wifiex/wlan_src/mlan/mlan_ioctl.h | 73 ++- mxm_wifiex/wlan_src/mlan/mlan_join.c | 336 ++++++++---- mxm_wifiex/wlan_src/mlan/mlan_main.h | 148 +++++- mxm_wifiex/wlan_src/mlan/mlan_misc.c | 322 ++++++++++- mxm_wifiex/wlan_src/mlan/mlan_scan.c | 62 ++- mxm_wifiex/wlan_src/mlan/mlan_sdio.c | 2 +- mxm_wifiex/wlan_src/mlan/mlan_shim.c | 12 +- mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c | 21 +- mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c | 67 ++- mxm_wifiex/wlan_src/mlan/mlan_sta_event.c | 23 +- mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c | 192 +------ mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c | 17 +- mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c | 6 + mxm_wifiex/wlan_src/mlan/mlan_txrx.c | 28 +- mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c | 35 ++ mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c | 33 +- mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c | 12 +- mxm_wifiex/wlan_src/mlan/mlan_usb.c | 112 +++- mxm_wifiex/wlan_src/mlan/mlan_wmm.c | 16 + mxm_wifiex/wlan_src/mlinux/mlan_decl.h | 24 +- mxm_wifiex/wlan_src/mlinux/mlan_ieee.h | 14 + mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h | 73 ++- mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c | 89 +++- mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h | 15 +- .../wlan_src/mlinux/moal_cfg80211_util.c | 13 +- mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c | 435 +++++++++++---- mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h | 6 +- mxm_wifiex/wlan_src/mlinux/moal_init.c | 147 ++++- mxm_wifiex/wlan_src/mlinux/moal_ioctl.c | 328 +++++++++++- mxm_wifiex/wlan_src/mlinux/moal_main.c | 203 +++++-- mxm_wifiex/wlan_src/mlinux/moal_main.h | 36 +- mxm_wifiex/wlan_src/mlinux/moal_pcie.c | 2 +- mxm_wifiex/wlan_src/mlinux/moal_priv.c | 15 +- mxm_wifiex/wlan_src/mlinux/moal_proc.c | 7 +- mxm_wifiex/wlan_src/mlinux/moal_sdio.h | 3 + mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c | 33 +- mxm_wifiex/wlan_src/mlinux/moal_shim.c | 35 +- .../wlan_src/mlinux/moal_sta_cfg80211.c | 113 +++- mxm_wifiex/wlan_src/mlinux/moal_uap.c | 25 +- mxm_wifiex/wlan_src/mlinux/moal_uap.h | 3 +- .../wlan_src/mlinux/moal_uap_cfg80211.c | 86 ++- mxm_wifiex/wlan_src/mlinux/moal_usb.c | 73 +++ mxm_wifiex/wlan_src/mlinux/moal_usb.h | 10 + mxm_wifiex/wlan_src/mlinux/moal_wext.c | 112 +++- 56 files changed, 3618 insertions(+), 717 deletions(-) diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index bde631b..8a62008 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -87,7 +87,15 @@ CONFIG_OPENWRT_SUPPORT=n # Big-endian platform CONFIG_BIG_ENDIAN=n +#ifdef EMBEDDED_AUTH +# Enable driver based authenticator +CONFIG_DRV_EMBEDDED_AUTHENTICATOR=n +#endif +#ifdef EMBEDDED_SUPP +# Enable driver based supplicant +CONFIG_DRV_EMBEDDED_SUPPLICANT=n +#endif ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT), y) CONFIG_EMBEDDED_SUPP_AUTH=y @@ -105,6 +113,8 @@ CONFIG_SDIO_SUSPEND_RESUME=y # DFS testing support CONFIG_DFS_TESTING_SUPPORT=y +# Multi-channel support +CONFIG_MULTI_CHAN_SUPPORT=y @@ -126,6 +136,12 @@ ccflags-y += -DLINUX +#if defined(EMBEDDED_SUPP) || defined(EMBEDDED_AUTH) +ifeq ($(CONFIG_EMBEDDED_SUPP_AUTH), y) +ccflags-y += -I$(M)/mlan/esa +ccflags-y += -I$(M)/mlan/esa/common +endif +#endif @@ -208,6 +224,9 @@ ifeq ($(CONFIG_SDIO_SUSPEND_RESUME),y) endif #endif +ifeq ($(CONFIG_MULTI_CHAN_SUPPORT),y) + ccflags-y += -DMULTI_CHAN_SUPPORT +endif ifeq ($(CONFIG_DFS_TESTING_SUPPORT),y) ccflags-y += -DDFS_TESTING_SUPPORT @@ -480,7 +499,17 @@ endif endif +#ifdef EMBEDDED_AUTH +ifeq ($(CONFIG_DRV_EMBEDDED_AUTHENTICATOR), y) + ccflags-y += -DDRV_EMBEDDED_AUTHENTICATOR +endif +#endif +#ifdef EMBEDDED_SUPP +ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT), y) + ccflags-y += -DDRV_EMBEDDED_SUPPLICANT +endif +#endif MOALOBJS = mlinux/moal_main.o \ @@ -560,9 +589,37 @@ endif +#if defined(EMBEDDED_SUPP) || defined(EMBEDDED_AUTH) +ifeq ($(CONFIG_EMBEDDED_SUPP_AUTH), y) +MLANOBJS += mlan/esa/common/crypto_api.o \ + mlan/esa/common/aes_cmac_rom.o \ + mlan/esa/common/crypt_new_rom.o \ + mlan/esa/common/pmkCache.o \ + mlan/esa/common/pmkCache_rom.o \ + mlan/esa/common/parser.o \ + mlan/esa/common/parser_rom.o \ + mlan/esa/keyMgmtApStaCommon.o \ + mlan/esa/hostsa_init.o \ + mlan/esa/authenticator_api.o +endif +#endif +#ifdef EMBEDDED_SUPP +ifeq ($(CONFIG_DRV_EMBEDDED_SUPPLICANT),y) +MLANOBJS += mlan/esa/keyMgmtSta.o \ + mlan/esa/keyMgmtSta_rom.o \ + mlan/esa/supplicant.o +endif +#endif +#ifdef EMBEDDED_AUTH +ifeq ($(CONFIG_DRV_EMBEDDED_AUTHENTICATOR),y) +MLANOBJS += mlan/esa/AssocAp_srv_rom.o \ + mlan/esa/keyMgmtAp_rom.o \ + mlan/esa/keyMgmtAp.o +endif +#endif obj-m := mlan.o mlan-objs := $(MLANOBJS) diff --git a/mxm_wifiex/wlan_src/README_MLAN b/mxm_wifiex/wlan_src/README_MLAN index 3e96bc6..fe3a413 100644 --- a/mxm_wifiex/wlan_src/README_MLAN +++ b/mxm_wifiex/wlan_src/README_MLAN @@ -44,6 +44,9 @@ To load driver with MFG firmware file, use mfg_mode=1 when insmod WLAN driver and specify MFG firmware name if needed. + To load driver with rf_test firmware file, use rf_test_mode=1 when insmod WLAN driver. + This parameter only used for 9177(FC) + There are some other parameters for debugging purpose etc. Use modinfo to check details. drvdbg= dev_cap_mask= @@ -95,6 +98,7 @@ Bit 1: uAP WEXT Bit 2: STA CFG80211 Bit 3: uAP CFG80211 + cfg80211_drcs=1|0 reg_alpha2= skip_fwdnld=0|1 wq_sched_prio: Priority for work queue @@ -126,6 +130,11 @@ GoAgeoutTime=0|x multi_dtim=0|x inact_tmo=0|x + 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 roamoffload_in_hs=0|1 uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64) host_mlme=0|1 @@ -524,6 +533,7 @@ SYNOPSIS mlanutl uapX clear_nop mlanutl uapX nop_list mlanutl uapX fake_radar + mlanutl uapX getchload [] mlanutl uapX getchload mlanutl dfsX dfs_cac [ ] mlanutl dfsX autodfs [conf_file] @@ -611,7 +621,6 @@ SYNOPSIS mlanutl mlanX mgmtframetx mlanutl mlanX mpactrl [tx_ena] [rx_ena] [tx_size] [rx_size] [tx_ports] [rx_ports] mlanutl mlanX netmon [ [ ]] - mlanutl mlanX monitormode [l] mlanutl mlanX offchannel [ ] mlanutl mlanX otpuserdata mlanutl mlanX passphrase [l] @@ -691,6 +700,9 @@ SYNOPSIS [AC_VI AIFSN ECW_MAX ECW_MIN TX_OP] [AC_VO AIFSN ECW_MAX ECW_MIN TX_OP] mlanutl mlanX wwscfg [m] + mlanutl mlanX mc_cfg [n] + mlanutl mlanX mc_policy [n] + mlanutl mlanX mc_cfg_ext [c] [s] [u] [m] mlanutl p2pX cfg_noa [h] [i] [j] [k] [l] mlanutl p2pX cfg_opp_ps [m] [n] mlanutl mlanX get_sensor_temp @@ -1416,7 +1428,7 @@ htcapinfo This command is used to config 11ax HE capability using command. Usage: - mlanutl 11axcmd [value_1] [value_2] + mlanutl 11axcmd [value_1] [value_2] [value_3] : spatial reuse configuration set obss_pd offset, [value_1] = NON_SRG_OffSET, [value_2] = SRG_OFFSET @@ -1439,12 +1451,21 @@ htcapinfo Bit 0-9: TXOP RTS Threshold : set/get omi value used for OMI transmission in MAC header HTC+ field, please see 11ax spec for OMI definition - set OMI when [value_1 = ], where is defined as: - Bit 0-2: Rx NSS - Bit 3-4: Channel Width - Bit 6 : Tx NSTS (applies to client mode only) - All other bits are not supported currently. - get OMI without value_1 and value_2 + set OMI: [value_1 = ] [value_2 = ] [value_3 = ] + where + is defined as: + Bit 0-2: Rx NSS + Bit 3-4: Channel Width + Bit 6 : Tx NSTS (applies to client mode only) + All other bits are not supported currently. + is defined as: + 0: OMI is transmitted in QoS NULL frame; + 1: OMI is transmitted in QoS data frame; + 0xFF: OMI is transmitted in both QoS NULL and QoS data frame. + is applied only if OMI is sent in QoS data frame. + It specifies the number of consecutive data frames containing the OMI. + + get OMI without any value : set/get OBSS narrow band RU tolerance time value in seconds set tolerance time when [value_1 = + + where: + channel index0: + [c] : chantime(in TU) + [s] : switchtime(in TU) + [u] : undozetime(in TU) + [m] : mode :0x0 --- PM1(default) + 0x1 --- Null2Self + channel index1: + : chantime(in TU) + : switchtime(in TU) + : undozetime(in TU) + : mode :0x0 --- PM1(default) + 0x1 --- Null2Self + Note: + channel index0: the first channel + channel index1: the second channel + undozetime should be less than other channel's switchtime + If want to set two channels the same parameters, just ignore the last four parameters and + use [c] [s] [u] [m] to set. + Examples: + mlanutl mlanX mc_cfg_ext : Get the drcs parameters for two channels. + mlanutl mlanX mc_cfg_ext 15 10 5 0 : Set two channels:channeltime 15TU, switchtime 10TU, undozetime 5TU, mode PM1 + mlanutl mlanX mc_cfg_ext 15 10 5 0 25 15 9 0 : Set channel index0: channeltime 17TU, switchtime 10TU, undozetime 5TU, mode PM1; + set channel index1: channeltime 25TU, switchtime 15TU, undozetime 9TU, mode PM1. + cfg_noa This is used to get/set P2P NoA (Notice of Absence) parameters only for P2P GO. diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11ax.c b/mxm_wifiex/wlan_src/mlan/mlan_11ax.c index cc94b28..38b903d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11ax.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11ax.c @@ -957,8 +957,9 @@ mlan_status wlan_cmd_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, break; case MLAN_11AXCMD_TXOMI_SUBID: memcpy_ext(pmadapter, axcmd->val, &txomi_cmd->omi, - sizeof(t_u16), sizeof(t_u16)); - cmd->size += sizeof(t_u16); + sizeof(mlan_ds_11ax_txomi_cmd), + sizeof(mlan_ds_11ax_txomi_cmd)); + cmd->size += sizeof(mlan_ds_11ax_txomi_cmd); break; case MLAN_11AXCMD_OBSS_TOLTIME_SUBID: memcpy_ext(pmadapter, axcmd->val, &toltime_cmd->tol_time, @@ -1034,7 +1035,8 @@ mlan_status wlan_ret_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, break; case MLAN_11AXCMD_TXOMI_SUBID: memcpy_ext(pmadapter, &cfg->param.txomi_cfg.omi, axcmd->val, - sizeof(t_u16), sizeof(t_u16)); + sizeof(mlan_ds_11ax_txomi_cmd), + sizeof(mlan_ds_11ax_txomi_cmd)); break; case MLAN_11AXCMD_OBSS_TOLTIME_SUBID: memcpy_ext(pmadapter, &cfg->param.toltime_cfg.tol_time, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11h.c b/mxm_wifiex/wlan_src/mlan/mlan_11h.c index 73fc5ba..ce3b024 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11h.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11h.c @@ -3171,7 +3171,10 @@ mlan_status wlan_11h_handle_event_chanswann(mlan_private *priv) ENTER(); #ifdef UAP_SUPPORT - if (priv->adapter->state_11h.is_master_radar_det_active) { + /** No need handle AP if mc_policy is disabled, FW will move the AP to + * client's new channel */ + if (pmadapter->mc_policy && + priv->adapter->state_11h.is_master_radar_det_active) { for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM); i++) { if (pmadapter->priv[i] && @@ -3811,8 +3814,13 @@ void wlan_dfs_rep_disconnect(mlan_adapter *pmadapter) if (wlan_11h_radar_detect_required(pmpriv, pmadapter->dfsr_channel)) { - wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); + mlan_status ret = MLAN_STATUS_SUCCESS; + ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP, + HostCmd_ACT_GEN_SET, 0, MNULL, + MNULL); + if (ret) { + PRINTM(MMSG, "Error sending message to FW\n"); + } } } } @@ -3829,6 +3837,7 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter) mlan_private *priv_list[MLAN_MAX_BSS_NUM]; mlan_private *pmpriv = MNULL; t_u8 pcount, i; + mlan_status ret = MLAN_STATUS_SUCCESS; memset(pmadapter, priv_list, 0x00, sizeof(priv_list)); pcount = wlan_get_privs_by_cond(pmadapter, wlan_is_intf_active, @@ -3855,8 +3864,12 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter) pmpriv, pmadapter->dfsr_channel)) return; - wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP, - HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); + ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_STOP, + HostCmd_ACT_GEN_SET, 0, MNULL, + MNULL); + if (ret) { + PRINTM(MERROR, "Error sending message to FW\n"); + } } } @@ -3865,8 +3878,12 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter) pmpriv = priv_list[i]; if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP) { - wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START, - HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); + ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_BSS_START, + HostCmd_ACT_GEN_SET, 0, MNULL, + MNULL); + if (ret) { + PRINTM(MERROR, "Error sending message to FW\n"); + } } } } @@ -4215,7 +4232,8 @@ mlan_status wlan_11h_radar_detected_handling(mlan_adapter *pmadapter, /* check next intf */ while ((++pstate_rdh->priv_curr_idx) < - pstate_rdh->priv_list_count) { + pstate_rdh->priv_list_count && + (pstate_rdh->priv_curr_idx < MLAN_MAX_BSS_NUM)) { pmpriv = pstate_rdh->priv_list[pstate_rdh->priv_curr_idx]; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n.c b/mxm_wifiex/wlan_src/mlan/mlan_11n.c index 7fe30fe..473f5c4 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n.c @@ -61,9 +61,24 @@ static mlan_status wlan_11n_ioctl_max_tx_buf_size(pmlan_adapter pmadapter, { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_ds_11n_cfg *cfg = MNULL; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; ENTER(); cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf; + if (pioctl_req->action == MLAN_ACT_SET) { + if (cfg->param.tx_buf_size == 0xffff) { + PRINTM(MIOCTL, "Send reconfigure tx buf to FW\n"); + ret = wlan_prepare_cmd(pmpriv, + HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, + (t_void *)pioctl_req, + &cfg->param.tx_buf_size); + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + LEAVE(); + return ret; + } + } cfg->param.tx_buf_size = (t_u32)pmadapter->max_tx_buf_size; pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.c b/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.c index 43ee75e..27b94bf 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n_rxreorder.c @@ -1156,6 +1156,7 @@ void wlan_11n_ba_stream_timeout(mlan_private *priv, HostCmd_DS_11N_BATIMEOUT *event) { HostCmd_DS_11N_DELBA delba; + mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); @@ -1169,7 +1170,10 @@ void wlan_11n_ba_stream_timeout(mlan_private *priv, delba.del_ba_param_set |= (t_u16)event->origninator << DELBA_INITIATOR_POS; delba.reason_code = REASON_CODE_STA_TIMEOUT; - wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, MNULL, &delba); + ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, MNULL, + &delba); + if (ret) + PRINTM(MERROR, "Failed to send cmd to FW\n"); LEAVE(); return; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c index 3cd009f..f981114 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c @@ -2446,9 +2446,6 @@ static oper_bw_chan *wlan_get_nonglobal_operclass_table(mlan_private *pmpriv, poper_bw_chan = oper_bw_chan_eu; *arraysize = sizeof(oper_bw_chan_eu); break; - default: - PRINTM(MERROR, "Country not support!\n"); - break; } LEAVE(); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c index 0c13ae3..7d18b43 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c @@ -4477,6 +4477,32 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter) goto done; } } + if (pmadapter->init_para.drcs_chantime_mode) { + mlan_ds_drcs_cfg drcs_init_cfg[2]; + drcs_init_cfg[0].chan_idx = 0x1; + drcs_init_cfg[0].chantime = + (t_u8)(pmadapter->init_para.drcs_chantime_mode >> 8); + /* switchtime use default value in fw*/ + drcs_init_cfg[0].switchtime = 10; + drcs_init_cfg[0].undozetime = 5; + drcs_init_cfg[0].mode = + (t_u8)(pmadapter->init_para.drcs_chantime_mode); + drcs_init_cfg[1].chan_idx = 0x2; + drcs_init_cfg[1].chantime = + (t_u8)(pmadapter->init_para.drcs_chantime_mode >> 24); + /* switchtime use default value in fw*/ + drcs_init_cfg[1].switchtime = 10; + drcs_init_cfg[1].undozetime = 5; + drcs_init_cfg[1].mode = + (t_u8)(pmadapter->init_para.drcs_chantime_mode >> 16); + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DRCS_CONFIG, + HostCmd_ACT_GEN_SET, 0, MNULL, + (t_void *)drcs_init_cfg); + if (ret) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + } /* Send request to firmware */ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_ANTENNA, HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); @@ -4673,10 +4699,19 @@ static mlan_status wlan_get_vdll_image(pmlan_adapter pmadapter, t_u32 vdll_len) ENTER(); if (ctrl->vdll_mem) { - PRINTM(MCMND, "VDLL mem is not empty: %p len=%d\n", - ctrl->vdll_mem, ctrl->vdll_len); - goto done; + PRINTM(MCMND, + "VDLL mem is not empty: %p old_len=%d new_len=%d\n", + ctrl->vdll_mem, ctrl->vdll_len, vdll_len); + if (pcb->moal_vmalloc && pcb->moal_vfree) + pcb->moal_vfree(pmadapter->pmoal_handle, + (t_u8 *)ctrl->vdll_mem); + else + pcb->moal_mfree(pmadapter->pmoal_handle, + (t_u8 *)ctrl->vdll_mem); + ctrl->vdll_mem = MNULL; + ctrl->vdll_len = 0; } + if (pcb->moal_vmalloc && pcb->moal_vfree) status = pcb->moal_vmalloc(pmadapter->pmoal_handle, vdll_len, (t_u8 **)&ctrl->vdll_mem); @@ -4836,6 +4871,454 @@ mlan_status wlan_process_csi_event(pmlan_private pmpriv) return status; } +/** + * @brief This function handle the multi_chan info event + * + * @param pmpriv A pointer to mlan_private structure + * @param pevent A pointer to event buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_handle_event_multi_chan_info(pmlan_private pmpriv, + pmlan_buffer pevent) +{ + pmlan_adapter pmadapter = pmpriv->adapter; + t_u32 interfaces = 0; + MrvlIEtypes_multi_chan_info_t *pmulti_chan_info = MNULL; + MrvlIEtypes_multi_chan_group_info_t *pmulti_chan_grp_info = MNULL; + int tlv_buf_left = pevent->data_len - sizeof(mlan_event_id); + t_u16 tlv_type, tlv_len; + mlan_status ret = MLAN_STATUS_SUCCESS; + pmlan_private intf_priv = MNULL; + int num_intf = 0, bss_type = 0, bss_num = 0; + MrvlIEtypesHeader_t *tlv = MNULL; + + ENTER(); + + PRINTM(MEVENT, "multi channel event\n"); + pmulti_chan_info = + (MrvlIEtypes_multi_chan_info_t *)(pevent->pbuf + + pevent->data_offset + + sizeof(mlan_event_id)); + if (tlv_buf_left < (int)(sizeof(MrvlIEtypes_multi_chan_info_t)) || + wlan_le16_to_cpu(pmulti_chan_info->header.type) != + TLV_TYPE_MULTI_CHAN_INFO) { + PRINTM(MERROR, "Invalid multi channel event\n"); + goto done; + } + + pmadapter->mc_status = wlan_le16_to_cpu(pmulti_chan_info->status); + PRINTM(MEVENT, "mc_status=%d\n", pmadapter->mc_status); + tlv_buf_left -= sizeof(MrvlIEtypes_multi_chan_info_t); + tlv = (MrvlIEtypesHeader_t *)pmulti_chan_info->tlv_buffer; + + while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) { + tlv_type = wlan_le16_to_cpu(tlv->type); + tlv_len = wlan_le16_to_cpu(tlv->len); + if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) > + (unsigned int)tlv_buf_left) { + PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", + tlv_len, tlv_buf_left); + break; + } + if (tlv_type != TLV_TYPE_MULTI_CHAN_GROUP_INFO_TLV_ID) { + PRINTM(MERROR, "wrong tlv type:0x%x\n", tlv_type); + break; + } + pmulti_chan_grp_info = + (MrvlIEtypes_multi_chan_group_info_t *)tlv; + PRINTM(MEVENT, "mc_info: groupid=%d chan=%d, numintf=%d\n", + pmulti_chan_grp_info->chan_group_id, + pmulti_chan_grp_info->chan_band_info.chan_num, + pmulti_chan_grp_info->num_intf); + num_intf = pmulti_chan_grp_info->num_intf; + for (interfaces = 0; interfaces < (t_u32)num_intf; + interfaces++) { + bss_type = pmulti_chan_grp_info + ->bss_type_numlist[interfaces] >> + 4; + bss_num = pmulti_chan_grp_info + ->bss_type_numlist[interfaces] & + BSS_NUM_MASK; + PRINTM(MEVENT, "intf%d: bss_type=%d bss_num=%d\n", + interfaces, bss_type, bss_num); + intf_priv = wlan_get_priv_by_id(pmadapter, bss_num, + bss_type); + if (intf_priv) { +#ifdef USB + if (IS_USB(pmadapter->card_type)) { + if (pmulti_chan_grp_info->hid_num + .usb_epnum == + MLAN_USB_EP_DATA || + pmulti_chan_grp_info->hid_num + .usb_epnum == + MLAN_USB_EP_DATA_CH2 || + pmulti_chan_grp_info->hid_num + .usb_epnum == + MLAN_USB_EP_DATA_IF2 || + pmulti_chan_grp_info->hid_num + .usb_epnum == + MLAN_USB_EP_DATA_CH2_IF2) { + intf_priv->port = + pmulti_chan_grp_info + ->hid_num + .usb_epnum; + intf_priv->port_index = + wlan_get_port_index( + pmadapter, + intf_priv->port); + PRINTM(MEVENT, + "intf%d: bss_type=%d bss_num=%d port=%d index=%d\n", + interfaces, bss_type, + bss_num, intf_priv->port, + intf_priv->port_index); + + } else + PRINTM(MERROR, + "Invalid Endpoint num in multi_channel event\n"); + } +#endif + } else { + PRINTM(MERROR, + "Invalid bss_type, bss_num in multi_channel event\n"); + } + } + + tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len); + tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len + + sizeof(MrvlIEtypesHeader_t)); + } + +#ifdef USB + if (IS_USB(pmadapter->card_type)) { + wlan_resync_usb_port(pmadapter); + } +#endif + +done: + LEAVE(); + return ret; +} + +/** + * @brief This function prepares the command MULTI_CHAN_CFG + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action Command action: GET or SET + * @param pdata_buf A pointer to new setting buf + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_multi_chan_cfg(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, + t_void *pdata_buf) +{ + mlan_ds_multi_chan_cfg *multi_chan_cfg = + (mlan_ds_multi_chan_cfg *)pdata_buf; + HostCmd_DS_MULTI_CHAN_CFG *pmchan_cfg = + (HostCmd_DS_MULTI_CHAN_CFG *)&cmd->params.multi_chan_cfg; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_CONFIG); + pmchan_cfg->action = wlan_cpu_to_le16(cmd_action); + + if (cmd_action == HostCmd_ACT_GEN_SET) { + pmchan_cfg->buffer_weight = multi_chan_cfg->buffer_weight; + pmchan_cfg->channel_time = + wlan_cpu_to_le32(multi_chan_cfg->channel_time); + PRINTM(MCMND, + "Set multi-channel: buffer_weight=%d channel_time=%d\n", + multi_chan_cfg->buffer_weight, + multi_chan_cfg->channel_time); + cmd->size = wlan_cpu_to_le16(S_DS_GEN + + sizeof(HostCmd_DS_MULTI_CHAN_CFG)); + } else { + cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action)); + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function handles the command response of MULTI_CHAN_CFG + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_multi_chan_cfg(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *pcfg = MNULL; + const HostCmd_DS_MULTI_CHAN_CFG *presp_cfg = + &resp->params.multi_chan_cfg; + + ENTER(); + + if (pioctl_buf) { + pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + pcfg->param.multi_chan_cfg.channel_time = + wlan_le32_to_cpu(presp_cfg->channel_time); + pcfg->param.multi_chan_cfg.buffer_weight = + presp_cfg->buffer_weight; + pcfg->param.multi_chan_cfg.tlv_len = + resp->size - (sizeof(HostCmd_DS_GEN) + + sizeof(HostCmd_DS_MULTI_CHAN_CFG)); + PRINTM(MCMND, + "Get multi-channel: buffer_weight=%d channel_time=%d tlv_len=%d\n", + pcfg->param.multi_chan_cfg.buffer_weight, + pcfg->param.multi_chan_cfg.channel_time, + pcfg->param.multi_chan_cfg.tlv_len); + memcpy_ext(pmpriv->adapter, pcfg->param.multi_chan_cfg.tlv_buf, + presp_cfg->tlv_buf, + pcfg->param.multi_chan_cfg.tlv_len, + pcfg->param.multi_chan_cfg.tlv_len); + pioctl_buf->buf_len = sizeof(mlan_ds_multi_chan_cfg) + + pcfg->param.multi_chan_cfg.tlv_len; + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function prepares the command MULTI_CHAN_POLICY + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action Command action: GET or SET + * @param pdata_buf A pointer to new setting buf + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_multi_chan_policy(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + t_u16 policy = 0; + HostCmd_DS_MULTI_CHAN_POLICY *pmulti_chan_policy = + (HostCmd_DS_MULTI_CHAN_POLICY *)&cmd->params.multi_chan_policy; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MULTI_CHAN_POLICY); + pmulti_chan_policy->action = wlan_cpu_to_le16(cmd_action); + cmd->size = wlan_cpu_to_le16(S_DS_GEN + + sizeof(HostCmd_DS_MULTI_CHAN_POLICY)); + if (cmd_action == HostCmd_ACT_GEN_SET) { + policy = *((t_u16 *)pdata_buf); + pmulti_chan_policy->policy = wlan_cpu_to_le16(policy); + PRINTM(MCMND, "Set multi-channel policy: %d\n", policy); + } + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function handles the command response of MULTI_CHAN_POLICY + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_multi_chan_policy(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *pcfg = MNULL; + const HostCmd_DS_MULTI_CHAN_POLICY *presp_cfg = + &resp->params.multi_chan_policy; + + ENTER(); + + if (pioctl_buf) { + pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + pcfg->param.multi_chan_policy = + wlan_le16_to_cpu(presp_cfg->policy); + + if (pioctl_buf->action == HostCmd_ACT_GEN_SET) { + if (pcfg->param.multi_chan_policy) + pmpriv->adapter->mc_policy = MTRUE; + else + pmpriv->adapter->mc_policy = MFALSE; + } + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function prepares the command DRCD_CFG + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action Command action: GET or SET + * @param pdata_buf A pointer to new setting buf + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_cmd_drcs_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + mlan_ds_drcs_cfg *drcs_cfg = (mlan_ds_drcs_cfg *)pdata_buf; + HostCmd_DS_DRCS_CFG *pdrcs_cfg = + (HostCmd_DS_DRCS_CFG *)&cmd->params.drcs_cfg; + MrvlTypes_DrcsTimeSlice_t *channel_time_slicing = + &pdrcs_cfg->time_slicing; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_DRCS_CONFIG); + pdrcs_cfg->action = wlan_cpu_to_le16(cmd_action); + + if (cmd_action == HostCmd_ACT_GEN_SET) { + channel_time_slicing->header.type = + wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID); + channel_time_slicing->header.len = + wlan_cpu_to_le16(sizeof(MrvlTypes_DrcsTimeSlice_t) - + sizeof(MrvlIEtypesHeader_t)); + channel_time_slicing->chan_idx = + wlan_cpu_to_le16(drcs_cfg->chan_idx); + channel_time_slicing->chantime = drcs_cfg->chantime; + channel_time_slicing->switchtime = drcs_cfg->switchtime; + channel_time_slicing->undozetime = drcs_cfg->undozetime; + channel_time_slicing->mode = drcs_cfg->mode; + PRINTM(MCMND, + "Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n", + channel_time_slicing->chan_idx, + channel_time_slicing->chantime, + channel_time_slicing->switchtime, + channel_time_slicing->undozetime, + channel_time_slicing->mode); + cmd->size = wlan_cpu_to_le16(S_DS_GEN + + sizeof(HostCmd_DS_DRCS_CFG)); + /* Set two channels different parameters */ + if (0x3 != channel_time_slicing->chan_idx) { + drcs_cfg++; + channel_time_slicing = pdrcs_cfg->drcs_buf; + channel_time_slicing->header.type = + wlan_cpu_to_le16(MRVL_DRCS_TIME_SLICE_TLV_ID); + channel_time_slicing->header.len = wlan_cpu_to_le16( + sizeof(MrvlTypes_DrcsTimeSlice_t) - + sizeof(MrvlIEtypesHeader_t)); + channel_time_slicing->chan_idx = + wlan_cpu_to_le16(drcs_cfg->chan_idx); + channel_time_slicing->chantime = drcs_cfg->chantime; + channel_time_slicing->switchtime = drcs_cfg->switchtime; + channel_time_slicing->undozetime = drcs_cfg->undozetime; + channel_time_slicing->mode = drcs_cfg->mode; + PRINTM(MCMND, + "Set multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n", + channel_time_slicing->chan_idx, + channel_time_slicing->chantime, + channel_time_slicing->switchtime, + channel_time_slicing->undozetime, + channel_time_slicing->mode); + cmd->size += wlan_cpu_to_le16( + sizeof(MrvlTypes_DrcsTimeSlice_t)); + } + } else { + cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(cmd_action)); + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function handles the command response of DRCS_CFG + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_drcs_cfg(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *pcfg = MNULL; + const HostCmd_DS_DRCS_CFG *presp_cfg = &resp->params.drcs_cfg; + const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing = + &presp_cfg->time_slicing; + const MrvlTypes_DrcsTimeSlice_t *channel_time_slicing1 = MNULL; + mlan_ds_drcs_cfg *drcs_cfg1 = MNULL; + + ENTER(); + + if (pioctl_buf) { + pcfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + if (wlan_le16_to_cpu(channel_time_slicing->header.type) != + MRVL_DRCS_TIME_SLICE_TLV_ID || + wlan_le16_to_cpu(channel_time_slicing->header.len) != + sizeof(MrvlTypes_DrcsTimeSlice_t) - + sizeof(MrvlIEtypesHeader_t)) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + pcfg->param.drcs_cfg[0].chan_idx = + wlan_le16_to_cpu(channel_time_slicing->chan_idx); + pcfg->param.drcs_cfg[0].chantime = + channel_time_slicing->chantime; + pcfg->param.drcs_cfg[0].switchtime = + channel_time_slicing->switchtime; + pcfg->param.drcs_cfg[0].undozetime = + channel_time_slicing->undozetime; + pcfg->param.drcs_cfg[0].mode = channel_time_slicing->mode; + PRINTM(MCMND, + "multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n", + pcfg->param.drcs_cfg[0].chan_idx, + channel_time_slicing->chantime, + channel_time_slicing->switchtime, + channel_time_slicing->undozetime, + channel_time_slicing->mode); + pioctl_buf->buf_len = sizeof(mlan_ds_drcs_cfg); + /*Channel for chan_idx 1 and 2 have different parameters*/ + if (0x3 != pcfg->param.drcs_cfg[0].chan_idx) { + channel_time_slicing1 = presp_cfg->drcs_buf; + if (wlan_le16_to_cpu( + channel_time_slicing1->header.type) != + MRVL_DRCS_TIME_SLICE_TLV_ID || + wlan_le16_to_cpu( + channel_time_slicing1->header.len) != + sizeof(MrvlTypes_DrcsTimeSlice_t) - + sizeof(MrvlIEtypesHeader_t)) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + drcs_cfg1 = + (mlan_ds_drcs_cfg *)&pcfg->param.drcs_cfg[1]; + drcs_cfg1->chan_idx = wlan_le16_to_cpu( + channel_time_slicing1->chan_idx); + drcs_cfg1->chantime = channel_time_slicing1->chantime; + drcs_cfg1->switchtime = + channel_time_slicing1->switchtime; + drcs_cfg1->undozetime = + channel_time_slicing1->undozetime; + drcs_cfg1->mode = channel_time_slicing1->mode; + PRINTM(MCMND, + "multi-channel: chan_idx=%d chantime=%d switchtime=%d undozetime=%d mode=%d\n", + drcs_cfg1->chan_idx, drcs_cfg1->chantime, + drcs_cfg1->switchtime, drcs_cfg1->undozetime, + drcs_cfg1->mode); + pioctl_buf->buf_len += sizeof(mlan_ds_drcs_cfg); + } + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /** * @brief This function prepares command of get_hw_spec. * @@ -5422,7 +5905,7 @@ mlan_status wlan_cmd_802_11_radio_control(pmlan_private pmpriv, t_u16 cmd_action, t_void *pdata_buf) { HostCmd_DS_802_11_RADIO_CONTROL *pradio_control = &cmd->params.radio; - t_u32 radio_ctl; + t_u32 radio_ctl = 0; ENTER(); cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RADIO_CONTROL)) + S_DS_GEN); @@ -7495,8 +7978,12 @@ mlan_status wlan_ret_chan_region_cfg(pmlan_private pmpriv, /* Add FW cfp tables and region info */ wlan_add_fw_cfp_tables(pmpriv, tlv_buf, tlv_buf_left); if (pmadapter->otp_region) { - wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code, - pmadapter->fw_bands); + if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code, + pmadapter->fw_bands)) { + PRINTM(MERROR, + "Set region table failure!! region_code = 0x%X, fw_bands = 0x%X\n", + pmadapter->region_code, pmadapter->fw_bands); + } } if (!pioctl_buf) goto done; @@ -9211,6 +9698,7 @@ mlan_status wlan_cmd_get_ch_load(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, cfg_cmd->noise = wlan_cpu_to_le16(cfg->noise); cfg_cmd->rx_quality = wlan_cpu_to_le16(cfg->rx_quality); cfg_cmd->duration = wlan_cpu_to_le16(cfg->duration); + cfg_cmd->cca_th = wlan_cpu_to_le16(cfg->cca_th); LEAVE(); return MLAN_STATUS_SUCCESS; } diff --git a/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/mxm_wifiex/wlan_src/mlan/mlan_decl.h index 70e970a..8544bc4 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 "366.p5" +#define MLAN_RELEASE_VERSION "368" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -1747,6 +1747,15 @@ typedef struct { t_u32 time_usec; } wifi_timeval; +#define timeval_to_msec(timeval) \ + (t_u64)((t_u64)(timeval.time_sec) * 1000 + \ + (t_u64)(timeval.time_usec) / 1000) +#define timeval_to_usec(timeval) \ + (t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \ + (t_u64)(timeval.time_usec)) +#define is_zero_timeval(timeval) \ + ((timeval.time_sec == 0) && (timeval.time_usec == 0)) + #define MAX_NUM_RATE 32 #define MAX_RADIO 2 #define MAX_NUM_CHAN 1 @@ -1828,15 +1837,6 @@ typedef struct { t_u32 cca_busy_time; } wifi_channel_stat; -#define timeval_to_msec(timeval) \ - (t_u64)((t_u64)(timeval.time_sec) * 1000 + \ - (t_u64)(timeval.time_usec) / 1000) -#define timeval_to_usec(timeval) \ - (t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \ - (t_u64)(timeval.time_usec)) -#define is_zero_timeval(timeval) \ - ((timeval.time_sec == 0) && (timeval.time_usec == 0)) - /** radio statistics */ typedef struct { /** wifi radio (if multiple radio supported) */ @@ -2322,6 +2322,8 @@ typedef struct _mlan_device { t_u8 indication_gpio; /** Dynamic MIMO-SISO switch for hscfg*/ t_u8 hs_mimo_switch; + /** channel time and mode for DRCS*/ + t_u32 drcs_chantime_mode; #ifdef USB /** Tx CMD endpoint address */ t_u8 tx_cmd_ep; @@ -2332,6 +2334,8 @@ typedef struct _mlan_device { t_u8 rx_data_ep; /** Tx data endpoint address */ t_u8 tx_data_ep; + /** Tx data second endpoint address */ + t_u8 tx_data2_ep; #endif /** passive to active scan */ t_u8 passive_to_active_scan; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/mxm_wifiex/wlan_src/mlan/mlan_fw.h index 6a74e15..91cc1e9 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -94,6 +94,9 @@ typedef MLAN_PACK_START struct { /** Setup the number of rates passed in the driver/firmware API */ #define A_SUPPORTED_RATES 9 +/** IEEEtypes Data Frame Subtype of QoS pkt */ +#define QOS_DATA 8 + /** CapInfo Short Slot Time Disabled */ /* #define SHORT_SLOT_TIME_DISABLED(CapInfo) * ((IEEEtypes_CapInfo_t)(CapInfo).short_slot_time = 0) */ @@ -245,7 +248,7 @@ typedef enum _KEY_INFO_WAPI { #define MRVDRV_SNAP_HEADER_LEN 8 /** The number of times to try when polling for status bits */ -#define MAX_POLL_TRIES 100 +#define MAX_POLL_TRIES 300 /** The number of times to try when waiting for downloaded firmware to become active when multiple interface is present */ @@ -1298,6 +1301,19 @@ typedef enum _WLAN_802_11_WEP_STATUS { /** Host Command ID : ROAMING OFFLOAD TO FW*/ #define HostCmd_CMD_ROAM_OFFLOAD 0x0245 +/** Host Command ID: Multi chan config */ +#define HostCmd_CMD_MULTI_CHAN_CONFIG 0x011e +/** Host Command ID: Multi chan policy */ +#define HostCmd_CMD_MULTI_CHAN_POLICY 0x0121 +/** TLV ID for multi chan info */ +#define TLV_TYPE_MULTI_CHAN_INFO (PROPRIETARY_TLV_BASE_ID + 0xb7) +/** TLV ID for multi chan group info */ +#define TLV_TYPE_MULTI_CHAN_GROUP_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 0xb8) +/** TLV ID for DRCS TimeSlice */ +#define MRVL_DRCS_TIME_SLICE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 263) +/** Host Command ID: DRCS config */ +#define HostCmd_CMD_DRCS_CONFIG 0x024a + #ifdef RX_PACKET_COALESCE /** TLV ID for RX pkt coalesce config */ #define TLV_TYPE_RX_PKT_COAL_CONFIG (PROPRIETARY_TLV_BASE_ID + 0xC9) @@ -1553,6 +1569,12 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_He_Op_t { t_u8 option[9]; } MLAN_PACK_END MrvlIEtypes_He_Op_t; +/** fw_cap_info bit30 for Embedded OWE Support*/ +#define FW_CAPINFO_EMBEDDED_OWE_SUPPORT MBIT(30) +/** Check if Embedded OWE is supported by firmware */ +#define IS_FW_SUPPORT_EMBEDDED_OWE(_adapter) \ + (_adapter->fw_cap_info & FW_CAPINFO_EMBEDDED_OWE_SUPPORT) + #ifdef RX_PACKET_COALESCE /** Host Command ID : Rx packet coalescing configuration */ #define HostCmd_CMD_RX_PKT_COALESCE_CFG 0x012c @@ -2063,6 +2085,9 @@ typedef enum _ENH_PS_MODES { /** Event ID: SAD Report */ #define EVENT_SAD_REPORT 0x00000066 +/** Event ID: Multi Chan Info*/ +#define EVENT_MULTI_CHAN_INFO 0x0000006a + #define EVENT_FW_DUMP_INFO 0x00000073 /** Event ID: Tx status */ #define EVENT_TX_STATUS_REPORT 0x00000074 @@ -2171,6 +2196,8 @@ typedef enum _tdls_error_code_e { #define RXPD_FLAG_EXTRA_HEADER (1 << 1) +#define RXPD_FLAG_UCAST_PKT (1 << 3) + /** Event_WEP_ICV_ERR structure */ typedef MLAN_PACK_START struct _Event_WEP_ICV_ERR { /** Reason code */ @@ -2220,6 +2247,10 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_TDLS_Idle_Timeout_t { #define PAIRWISE_CIPHER_SUITE_LEN 4 /** AKM Suite length */ #define AKM_SUITE_LEN 4 +/** PMKID length */ +#define PMKID_LEN 16 +/** Group mgmt Cipher Suite length */ +#define GROUP_MGMT_CIPHER_SUITE_LEN 4 /** MFPC bit in RSN capability */ #define MFPC_BIT 7 /** MFPR bit in RSN capability */ @@ -3645,6 +3676,7 @@ typedef MLAN_PACK_START struct _HostCmd_DS_GET_CH_LOAD { t_s16 noise; t_u16 rx_quality; t_u16 duration; + t_u16 cca_th; } MLAN_PACK_END HostCmd_DS_GET_CH_LOAD; /** HostCmd_DS_CMD_802_11_RSSI_INFO */ @@ -6975,6 +7007,92 @@ typedef MLAN_PACK_START struct _HostCmd_DS_RX_PKT_COAL_CFG { } MLAN_PACK_END HostCmd_DS_RX_PKT_COAL_CFG; #endif +typedef MLAN_PACK_START struct _MrvlTypes_DrcsTimeSlice_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** Channel Index*/ + t_u16 chan_idx; + /** Channel time (in TU) for chan_idx*/ + t_u8 chantime; + /** Channel swith time (in TU) for chan_idx*/ + t_u8 switchtime; + /** Undoze time (in TU) for chan_idx*/ + t_u8 undozetime; + /** Rx traffic control scheme when channel switch*/ + /** only valid for GC/STA interface*/ + t_u8 mode; +} MLAN_PACK_END MrvlTypes_DrcsTimeSlice_t; +typedef MLAN_PACK_START struct _HostCmd_DS_MULTI_CHAN_CFG { + /** Action */ + t_u16 action; + /** Channel time */ + t_u32 channel_time; + /** Buffer weight */ + t_u8 buffer_weight; + /** TLV buffer */ + t_u8 tlv_buf[]; + /* t_u8 *tlv_buf; */ +} MLAN_PACK_END HostCmd_DS_MULTI_CHAN_CFG; + +typedef MLAN_PACK_START struct _HostCmd_DS_DRCS_CFG { + /** Action */ + t_u16 action; + /** TLV buffer */ + MrvlTypes_DrcsTimeSlice_t time_slicing; + /** TLV buffer */ + MrvlTypes_DrcsTimeSlice_t drcs_buf[]; + /* t_u8 *tlv_buf; */ +} MLAN_PACK_END HostCmd_DS_DRCS_CFG; + +typedef MLAN_PACK_START struct _HostCmd_DS_MULTI_CHAN_POLICY { + /** Action */ + t_u16 action; + /** Multi-channel Policy */ + t_u16 policy; +} MLAN_PACK_END HostCmd_DS_MULTI_CHAN_POLICY; + +/** Channel band info */ +typedef MLAN_PACK_START struct _ChannelBandInfo { + /* band config */ + Band_Config_t bandcfg; + /** channel num for specificed band */ + t_u8 chan_num; +} MLAN_PACK_END ChannelBandInfo; + +/** MrvlIETypes_mutli_chan_group_info_t */ +typedef MLAN_PACK_START struct _MrvlIETypes_mutli_chan_group_info_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** channel group id */ + t_u8 chan_group_id; + /** buffer weight for this channel group */ + t_u8 chan_buff_weight; + /** channel number and band information */ + ChannelBandInfo chan_band_info; + /** Max channel time (us) */ + t_u32 channel_time; + /** Reserved */ + t_u32 reserved; + MLAN_PACK_START union { + t_u8 sdio_func_num; + t_u8 usb_epnum; + } MLAN_PACK_END hid_num; + /** interface number in this group */ + t_u8 num_intf; + /** bss_type list */ + t_u8 bss_type_numlist[]; +} MLAN_PACK_END MrvlIEtypes_multi_chan_group_info_t; + +/** MrvlIEtypes_multi_chan_info_t */ +typedef MLAN_PACK_START struct _MrvlIETypes_mutli_chan_info_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** multi channel operation status */ + t_u16 status; + /** Tlv buffer */ + t_u8 tlv_buffer[]; +} MLAN_PACK_END MrvlIEtypes_multi_chan_info_t; + /** TLV buffer : firmware roam keys */ typedef MLAN_PACK_START struct _MrvlIEtypes_keyParams_t { /** Header */ @@ -8130,6 +8248,9 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { #ifdef USB HostCmd_DS_PACKET_AGGR_OVER_HOST_INTERFACE packet_aggr; #endif + HostCmd_DS_MULTI_CHAN_CFG multi_chan_cfg; + HostCmd_DS_MULTI_CHAN_POLICY multi_chan_policy; + HostCmd_DS_DRCS_CFG drcs_cfg; HostCmd_CONFIG_LOW_PWR_MODE low_pwr_mode_cfg; HostCmd_DS_TSF tsf; HostCmd_DS_DFS_REPEATER_MODE dfs_repeater; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h index d9a2ce7..cf2ef85 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h @@ -1939,6 +1939,11 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END wlan_bgscan_cfg; #endif /* STA_SUPPORT */ +/** The open AP in OWE transmition Mode */ +#define OWE_TRANS_MODE_OPEN 1 +/** The security AP in OWE trsnsition Mode */ +#define OWE_TRANS_MODE_OWE 2 + #ifdef PRAGMA_PACK #pragma pack(pop) #endif @@ -1953,6 +1958,15 @@ typedef struct _BSSDescriptor_t { /** SSID */ mlan_802_11_ssid ssid; + /** Transition MAC address */ + mlan_802_11_mac_addr trans_mac_address; + + /** Transition SSID */ + mlan_802_11_ssid trans_ssid; + + /** OWE Transition mode */ + t_u8 owe_transition_mode; + /** WEP encryption requirement */ t_u32 privacy; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_init.c b/mxm_wifiex/wlan_src/mlan/mlan_init.c index 8213c41..a9fd9cd 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_init.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_init.c @@ -614,6 +614,7 @@ mlan_status wlan_init_priv(pmlan_private priv) priv->intf_hr_len = MLAN_USB_TX_AGGR_HEADER; } priv->port = pmadapter->tx_data_ep; + priv->port_index = 0; } #endif ret = wlan_add_bsspriotbl(priv); @@ -823,6 +824,9 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter) #ifdef USB if (IS_USB(pmadapter->card_type)) { + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { + pmadapter->pcard_usb->usb_port_status[i] = MFALSE; + } for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { pmadapter->pcard_usb->usb_tx_aggr[i].aggr_ctrl.enable = MFALSE; @@ -842,7 +846,7 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter) pmadapter->pcard_usb->usb_tx_aggr[i].hold_timeout_msec = MLAN_USB_TX_AGGR_TIMEOUT_MSEC; pmadapter->pcard_usb->usb_tx_aggr[i].port = - pmadapter->tx_data_ep; + pmadapter->usb_tx_ports[i]; pmadapter->pcard_usb->usb_tx_aggr[i].phandle = (t_void *)pmadapter; } @@ -946,6 +950,8 @@ t_void wlan_init_adapter(pmlan_adapter pmadapter) pmadapter->arp_filter_size = 0; #endif /* STA_SUPPORT */ + pmadapter->mc_status = MFALSE; + #ifdef PCIE if (IS_PCIE(pmadapter->card_type)) { pmadapter->pcard_pcie->txbd_wrptr = 0; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index b09307d..be6d8ed 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -293,6 +293,8 @@ enum _mlan_ioctl_req_id { #if defined(STA_SUPPORT) MLAN_OID_MISC_PMFCFG = 0x00200022, #endif + MLAN_OID_MISC_MULTI_CHAN_CFG = 0x00200023, + MLAN_OID_MISC_MULTI_CHAN_POLICY = 0x00200024, #ifdef WIFI_DIRECT_SUPPORT MLAN_OID_MISC_WIFI_DIRECT_CONFIG = 0x00200025, #endif @@ -319,6 +321,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046, MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048, MLAN_OID_MISC_OPER_CLASS_CHECK = 0x00200049, + MLAN_OID_MISC_DRCS_CFG = 0x00200050, MLAN_OID_MISC_CWMODE_CTRL = 0x00200051, MLAN_OID_MISC_AGGR_CTRL = 0x00200052, @@ -766,6 +769,11 @@ typedef struct _mlan_ssid_bssid { t_u8 host_mlme; /** assoicate resp frame/ie from firmware */ mlan_ds_misc_assoc_rsp assoc_rsp; + t_u8 owe_transition_mode; + /** Transition SSID */ + mlan_802_11_ssid trans_ssid; + /** Transition BSSID */ + mlan_802_11_mac_addr trans_bssid; } mlan_ssid_bssid, *pmlan_ssid_bssid; /** Data structure of WMM ECW */ @@ -911,6 +919,8 @@ typedef struct _mlan_deauth_param { #define PROTOCOL_WAPI 0x80 /** WPA3 SAE */ #define PROTOCOL_WPA3_SAE 0x100 +/** OWE */ +#define PROTOCOL_OWE 0x200 /** Key_mgmt_psk */ #define KEY_MGMT_NONE 0x04 @@ -2592,6 +2602,7 @@ enum _mlan_auth_mode { MLAN_AUTH_MODE_SHARED = 0x01, MLAN_AUTH_MODE_FT = 0x02, MLAN_AUTH_MODE_SAE = 0x03, + MLAN_AUTH_MODE_OWE = 0x04, MLAN_AUTH_MODE_NETWORKEAP = 0x80, MLAN_AUTH_MODE_AUTO = 0xFF, }; @@ -2604,6 +2615,7 @@ typedef enum { AssocAgentAuth_FastBss_Skip, AssocAgentAuth_Network_EAP, AssocAgentAuth_Wpa3Sae = 6, + AssocAgentAuth_Owe = 7, AssocAgentAuth_Auto, } AssocAgentAuthType_e; @@ -4065,10 +4077,19 @@ typedef struct _mlan_ds_11ax_txop_cmd { } mlan_ds_11ax_txop_cmd, *pmlan_ds_11ax_txop_cmd; /** Type definition of mlan_ds_11ax_htc_cmd for MLAN_OID_11AX_CMD_CFG */ -typedef struct _mlan_ds_11ax_txomi_cmd { +typedef struct MLAN_PACK_START_mlan_ds_11ax_txomi_cmd { /* 11ax spec 9.2.4.6a.2 OM Control 12 bits. Bit 0 to bit 11 */ t_u16 omi; -} mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd; + /* tx option + * 0: send OMI in QoS NULL; 1: send OMI in QoS data; 0xFF: set OMI in + * both + */ + t_u8 tx_option; + /* if OMI is sent in QoS data, specify the number of consecutive data + * packets containing the OMI + */ + t_u8 num_data_pkts; +} MLAN_PACK_END mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd; /** Type definition of mlan_ds_11ax_toltime_cmd for MLAN_OID_11AX_CMD_CFG */ typedef struct _mlan_ds_11ax_toltime_cmd { @@ -4471,12 +4492,13 @@ enum _mlan_func_cmd { MLAN_FUNC_SHUTDOWN, }; -/** Net monitor filter: management frame */ -#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0) -/** Net monitor filter: control frame */ -#define MLAN_NETMON_CONTROL_FRAME MBIT(1) -/** Net monitor filter: data frame */ -#define MLAN_NETMON_DATA_FRAME MBIT(2) +/* Net monitor filters: */ +/* management frame */ +#define MLAN_NETMON_MANAGEMENT MBIT(0) +/* control frame */ +#define MLAN_NETMON_CONTROL MBIT(1) +/* data frame */ +#define MLAN_NETMON_DATA MBIT(2) typedef struct _mlan_ds_misc_net_monitor { /** Enable/disable network monitor */ @@ -4912,6 +4934,31 @@ typedef struct _mlan_ds_misc_pmfcfg { } mlan_ds_misc_pmfcfg; #endif +typedef MLAN_PACK_START struct _mlan_ds_multi_chan_cfg { + /** Channel Time */ + t_u32 channel_time; + /** Buffer Weight */ + t_u8 buffer_weight; + /** tlv len */ + t_u16 tlv_len; + /** TLV buffer */ + t_u8 tlv_buf[]; +} MLAN_PACK_END mlan_ds_multi_chan_cfg; + +typedef MLAN_PACK_START struct _mlan_ds_drcs_cfg { + /** Channel Index*/ + t_u16 chan_idx; + /** Channel time (in TU) for chan_idx */ + t_u8 chantime; + /** Channel swith time (in TU) for chan_idx */ + t_u8 switchtime; + /** Undoze time (in TU) for chan_idx */ + t_u8 undozetime; + /** Rx traffic control scheme when channel switch*/ + /** only valid for GC/STA interface*/ + t_u8 mode; +} MLAN_PACK_END mlan_ds_drcs_cfg; + #define MAX_SSID_NUM 16 #define MAX_AP_LIST 8 #define RETRY_UNLIMITED_TIME 0xFF @@ -5627,7 +5674,7 @@ struct MLAN_PACK_START mfg_Cmd_HE_TBTx_t { /** AXQ Mu Timer */ t_u16 axq_mu_timer; /** Tx Power */ - t_u16 tx_power; + t_s16 tx_power; } MLAN_PACK_END; typedef struct _mlan_ds_misc_chnrgpwr_cfg { @@ -5684,6 +5731,7 @@ typedef struct _mlan_ds_ch_load { t_s16 noise; t_u16 rx_quality; t_u16 duration; + t_u16 cca_th; } mlan_ds_ch_load; /** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ @@ -5770,6 +5818,13 @@ typedef struct _mlan_ds_misc_cfg { #if defined(STA_SUPPORT) mlan_ds_misc_pmfcfg pmfcfg; #endif + /** Multi-channel config for MLAN_OID_MISC_MULTI_CHAN_CFG */ + mlan_ds_multi_chan_cfg multi_chan_cfg; + /** Multi-channel policy for MLAN_OID_MISC_MULTI_CHAN_POLICY */ + t_u16 multi_chan_policy; + /** channel drcs time slicing config for MLAN_OID_MISC_DRCS_CFG + */ + mlan_ds_drcs_cfg drcs_cfg[2]; #ifdef WIFI_DIRECT_SUPPORT mlan_ds_wifi_direct_config p2p_config; #endif diff --git a/mxm_wifiex/wlan_src/mlan/mlan_join.c b/mxm_wifiex/wlan_src/mlan/mlan_join.c index 26b5f90..02d202c 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_join.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_join.c @@ -351,7 +351,7 @@ static mlan_status wlan_setup_rates_from_bssdesc(mlan_private *pmpriv, t_u8 *pout_rates, t_u32 *pout_rates_size) { - t_u8 card_rates[WLAN_SUPPORTED_RATES]; + t_u8 card_rates[WLAN_SUPPORTED_RATES] = {0}; t_u32 card_rates_size = 0; ENTER(); /* Copy AP supported rates */ @@ -625,19 +625,53 @@ static t_u8 wlan_use_mfp(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc) * @param ptlv_rsn_ie A pointer to rsn_ie TLV */ static int wlan_update_rsn_ie(mlan_private *pmpriv, - MrvlIEtypes_RsnParamSet_t *ptlv_rsn_ie) + MrvlIEtypes_RsnParamSet_t *ptlv_rsn_ie, + t_u16 *rsn_ie_len, t_u8 *akm_type) { t_u16 *prsn_cap; - t_u16 *ptr; - t_u16 *akm_suite_count_ptr; + t_u8 *ptr; + t_u8 *pairwise_cipher_count_ptr; + t_u8 *group_mgmt_cipher_suite_ptr = MNULL; + t_u8 *pmkid_list_ptr = MNULL; + t_u8 *end_ptr; t_u16 pmf_mask = 0x00; - t_u8 *temp; t_u16 pairwise_cipher_count = 0; t_u16 akm_suite_count = 0; - t_u16 temp_akm_suite_count = 0; - int found = 0; - t_u8 sha_256_oui[4] = {0x00, 0x0f, 0xac, 0x06}; - t_u8 sae_oui[4] = {0x00, 0x0f, 0xac, 0x08}; + t_u16 pmkid_count = 0; + t_u8 i; + +#define PREFERENCE_TKIP 1 + /* Cipher Perference Order: + (5) CIPHER_SYITE_TYPE_GCMP_256 = 9 + (4) CIPHER_SYITE_TYPE_GCMP_128 = 8 + (3) CIPHER_SYITE_TYPE_CCMP_256 = 10 + (2) CIPHER_SYITE_TYPE_CCMP_128 = 4 + (1) CIPHER_SYITE_TYPE_TKIP = 2 + (0) Skip + */ + t_u8 preference_selected; + t_u8 cipher_selected_id; +#if 0 // defined(ENABLE_GCMP_SUPPORT) + // embedded supplicant doesn't support GCMP yet + t_u8 cipher_preference[11] = {0, 0, 1, 0, 2, 0, 0, 0, 4, 5, 3}; +#else + t_u8 cipher_preference[5] = {0, 0, 1, 0, 2}; +#endif + t_u8 oui[4] = {0x00, 0x0f, 0xac, 0x00}; + + /* AKM Perference Order: + (6) AKM_SUITE_TYPE_FT_SAE = 9 //Not supported in esupp + (5) AKM_SUITE_TYPE_SAE = 8 + (4) AKM_SUITE_TYPE_OWE = 18 + (3) AKM_SUITE_TYPE_FT_PSK = 4 //Not supported in esupp + (2) AKM_SUITE_TYPE_PSK_SHA256 = 6 + (1) AKM_SUITE_TYPE_PSK = 2 + (0) Skip + */ + t_u8 akm_type_selected; + t_u8 akm_type_id = 0; + t_u8 akm_preference[19] = {0, 0, 1, 0, 0, 0, 2, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4}; mlan_adapter *pmadapter = pmpriv->adapter; int ap_mfpc = 0, ap_mfpr = 0, ret = MLAN_STATUS_SUCCESS; @@ -650,82 +684,114 @@ static int wlan_update_rsn_ie(mlan_private *pmpriv, * pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + 2 bytes * akm_suite_count + akm_suite_count * AKM_SUITE_LEN */ - ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8)); - pairwise_cipher_count = wlan_le16_to_cpu(*ptr); - ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN); - temp_akm_suite_count = wlan_le16_to_cpu(*ptr); - akm_suite_count = wlan_le16_to_cpu(*ptr); - /* Save pointer to akm_suite_count in RSN IE to update it later */ - akm_suite_count_ptr = ptr; - temp = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16); - /* ptr now points to the 1st AKM suite */ - if (temp_akm_suite_count > 1) { - while (temp_akm_suite_count) { - if (pmpriv->sec_info.authentication_mode == - MLAN_AUTH_MODE_SAE) { - if (!memcmp(pmadapter, temp, sae_oui, - AKM_SUITE_LEN)) { - found = 1; + end_ptr = ptlv_rsn_ie->rsn_ie + *rsn_ie_len; + + ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8); + + pairwise_cipher_count_ptr = ptr; + pairwise_cipher_count = wlan_le16_to_cpu(*(t_u16 *)ptr); + ptr += sizeof(t_u16); + + preference_selected = 0; + cipher_selected_id = 0; + for (i = 0; i < pairwise_cipher_count; i++) { + if ((ptr[3] < sizeof(cipher_preference)) && + (cipher_preference[ptr[3]] > preference_selected)) { + preference_selected = cipher_preference[ptr[3]]; + cipher_selected_id = ptr[3]; + } + ptr += PAIRWISE_CIPHER_SUITE_LEN; + } + + if (preference_selected == 0) { + PRINTM(MERROR, "RSNE: PAIRWISE_CIPHER not supported\n"); + return MLAN_STATUS_FAILURE; + } + if ((preference_selected == PREFERENCE_TKIP) && + ((*akm_type == AssocAgentAuth_Wpa3Sae) || + (*akm_type == AssocAgentAuth_Owe))) { + PRINTM(MERROR, + "RSNE: PAIRWISE_CIPHER TKIP not allowed for AKM %s\n", + (*akm_type == AssocAgentAuth_Wpa3Sae) ? "SAE" : "ÖWE"); + return MLAN_STATUS_FAILURE; + } + if ((preference_selected == PREFERENCE_TKIP) && + (*akm_type == AssocAgentAuth_Auto)) { + *akm_type = AssocAgentAuth_Open; + } + /* Process AKM + * Preference order for AssocAgentAuth_Auto: + * FT Authentication using SAE 00-0F-AC:9 (not supported in embedded + * supplicant) SAE Authentication 00-0F-AC:8 OWE Authentication + * 00-0F-AC:18 FT Authentication using PSK 00-0F-AC:4 (not supported in + * embedded supplicant) PSK using SHA-256 00-0F-AC:6 PSK 00-0F-AC:2 + */ + ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) + + sizeof(t_u16) + pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN; + akm_suite_count = wlan_le16_to_cpu(*(t_u16 *)ptr); + ptr += sizeof(t_u16); // move pointer to AKM suite + + akm_type_selected = 0; + if (*akm_type == AssocAgentAuth_Auto) { + // find the best one + for (i = 0; i < akm_suite_count; i++) { + if ((ptr[3] < sizeof(akm_preference)) && + (akm_preference[ptr[3]] > akm_type_selected)) { + akm_type_selected = akm_preference[ptr[3]]; + akm_type_id = ptr[3]; + } + ptr += AKM_SUITE_LEN; + } + if (akm_type_selected) { + if (akm_type_id == 6) + *akm_type = AssocAgentAuth_Open; + else if (akm_type_id == 2) + *akm_type = AssocAgentAuth_Open; + else if (akm_type_id == 18) + *akm_type = AssocAgentAuth_Owe; + else if (akm_type_id == 8) + *akm_type = AssocAgentAuth_Wpa3Sae; + } + } else { + // find the matched AKM + for (i = 0; i < akm_suite_count; i++) { + if (ptr[3] < sizeof(akm_preference)) { + if ((*akm_type == AssocAgentAuth_Open) && + (ptr[3] == 6)) { + break; + } else if ((*akm_type == AssocAgentAuth_Open) && + (ptr[3] == 2)) { + break; + } else if ((*akm_type == + AssocAgentAuth_Wpa3Sae) && + (ptr[3] == 8)) { + break; + } else if ((*akm_type == AssocAgentAuth_Owe) && + (ptr[3] == 18)) { break; } - } else if (!memcmp(pmadapter, temp, sha_256_oui, - AKM_SUITE_LEN)) { - found = 1; - break; } - temp += AKM_SUITE_LEN; - temp_akm_suite_count--; + ptr += AKM_SUITE_LEN; } - if (found) { - /* Copy SHA256 as AKM suite */ - memcpy_ext(pmadapter, - ptlv_rsn_ie->rsn_ie + - (sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * - PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16)), - temp, AKM_SUITE_LEN, AKM_SUITE_LEN); - /* Shift remaining bytes of RSN IE after this */ - memmove(pmadapter, - ptlv_rsn_ie->rsn_ie + - (sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * - PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16) + AKM_SUITE_LEN), - ptlv_rsn_ie->rsn_ie + - (sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * - PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16) + - akm_suite_count * AKM_SUITE_LEN), - ptlv_rsn_ie->header.len - - (sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * - PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16) + - akm_suite_count * AKM_SUITE_LEN)); - ptlv_rsn_ie->header.len = - ptlv_rsn_ie->header.len - - (akm_suite_count - 1) * AKM_SUITE_LEN; - /* Update akm suite count */ - akm_suite_count = 1; - *akm_suite_count_ptr = akm_suite_count; + if (i == akm_suite_count) { + akm_type_selected = 0; // not found + } else { + akm_type_selected = akm_preference[ptr[3]]; + akm_type_id = ptr[3]; } } - ptr = (t_u16 *)(ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) + - sizeof(t_u16) + - pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + - sizeof(t_u16) + akm_suite_count * AKM_SUITE_LEN); - prsn_cap = ptr; + + if (akm_type_selected == 0) { + PRINTM(MERROR, "RSNE: AKM Suite not found for authtype %d\n", + *akm_type); + return MLAN_STATUS_FAILURE; + } + /* Process RSNCAP */ + ptr = ptlv_rsn_ie->rsn_ie + sizeof(t_u16) + 4 * sizeof(t_u8) + + sizeof(t_u16) + + pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + + sizeof(t_u16) + akm_suite_count * AKM_SUITE_LEN; + prsn_cap = (t_u16 *)ptr; ap_mfpc = ((*prsn_cap & (0x1 << MFPC_BIT)) == (0x1 << MFPC_BIT)); ap_mfpr = ((*prsn_cap & (0x1 << MFPR_BIT)) == (0x1 << MFPR_BIT)); @@ -734,15 +800,61 @@ static int wlan_update_rsn_ie(mlan_private *pmpriv, ((!ap_mfpc) && ap_mfpr) || (ap_mfpc && ap_mfpr && (!pmpriv->pmfcfg.mfpc))) { PRINTM(MERROR, - "Mismatch in PMF config of STA and AP, can't associate to AP\n"); + "RSNE: Mismatch in PMF config of STA and AP, can't associate to AP\n"); return MLAN_STATUS_FAILURE; } - if ((pmpriv->pmfcfg.mfpr && pmpriv->pmfcfg.mfpc) || - pmpriv->pmfcfg.mfpc) { - *prsn_cap |= PMF_MASK; - *prsn_cap &= pmf_mask; - } + *prsn_cap |= PMF_MASK; + *prsn_cap &= pmf_mask; + // PMKID + ptr += sizeof(t_u16); + if (end_ptr > ptr) { + pmkid_count = wlan_le16_to_cpu(*(t_u16 *)ptr); + ptr += sizeof(t_u16); + pmkid_list_ptr = ptr; + ptr += pmkid_count * PMKID_LEN; + } + // Group Mgmt Cipher Suite + if ((end_ptr > ptr) && (pmf_mask & PMF_MASK)) { + group_mgmt_cipher_suite_ptr = ptr; + } + /* Compose new RSNE */ + // pairwiase + ptr = pairwise_cipher_count_ptr; + *(t_u16 *)ptr = wlan_cpu_to_le16(1); + ptr += sizeof(t_u16); + oui[3] = cipher_selected_id; + *(t_u32 *)ptr = *(t_u32 *)oui; + ptr += PAIRWISE_CIPHER_SUITE_LEN; + // akm + *(t_u16 *)ptr = wlan_cpu_to_le16(1); + ptr += sizeof(t_u16); + oui[3] = akm_type_id; + *(t_u32 *)ptr = *(t_u32 *)oui; + ptr += AKM_SUITE_LEN; + // RSNCAP + *(t_u16 *)ptr = wlan_cpu_to_le16(*prsn_cap); + ptr += sizeof(t_u16); + // PMKID list + if (pmkid_list_ptr || group_mgmt_cipher_suite_ptr) { + // Add PMKID + *(t_u16 *)ptr = wlan_cpu_to_le16(pmkid_count); + ptr += sizeof(t_u16); + if (pmkid_count) { + memcpy_ext(pmadapter, ptr, (t_u8 *)pmkid_list_ptr, + (pmkid_count * PMKID_LEN), (end_ptr - ptr)); + ptr += pmkid_count * PMKID_LEN; + } + if (group_mgmt_cipher_suite_ptr) { + // Add Group Mgmt Cipher Suite + memcpy_ext(pmadapter, ptr, + (t_u8 *)group_mgmt_cipher_suite_ptr, + GROUP_MGMT_CIPHER_SUITE_LEN, + (end_ptr - ptr)); + ptr += GROUP_MGMT_CIPHER_SUITE_LEN; + } + } + *rsn_ie_len = ptr - ptlv_rsn_ie->rsn_ie; return ret; } @@ -884,6 +996,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, t_u8 ft_akm = 0; t_u8 oper_class; t_u8 oper_class_flag = MFALSE; + t_u8 akm_type = 0; MrvlIEtypes_HostMlme_t *host_mlme_tlv = MNULL; MrvlIEtypes_PrevBssid_t *prev_bssid_tlv = MNULL; t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0}; @@ -961,7 +1074,8 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, PRINTM(MINFO, "ASSOC_CMD: Rates size = %d\n", rates_size); /* Add the Authentication type to be used for Auth frames if needed */ - if ((pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO)) { + if ((pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO) || + (pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OWE)) { pauth_tlv = (MrvlIEtypes_AuthType_t *)pos; pauth_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE); pauth_tlv->header.len = sizeof(pauth_tlv->auth_type); @@ -978,9 +1092,16 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, MLAN_AUTH_MODE_SAE) pauth_tlv->auth_type = wlan_cpu_to_le16(AssocAgentAuth_Wpa3Sae); + else if (!pmpriv->curr_bss_params.host_mlme && + ((pbss_desc->owe_transition_mode == + OWE_TRANS_MODE_OWE) || + pmpriv->sec_info.authentication_mode == + MLAN_AUTH_MODE_OWE)) + pauth_tlv->auth_type = + wlan_cpu_to_le16(AssocAgentAuth_Owe); else pauth_tlv->auth_type = - wlan_cpu_to_le16(MLAN_AUTH_MODE_OPEN); + wlan_cpu_to_le16(AssocAgentAuth_Open); pos += sizeof(pauth_tlv->header) + pauth_tlv->header.len; pauth_tlv->header.len = wlan_cpu_to_le16(pauth_tlv->header.len); } @@ -1097,7 +1218,11 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, pmpriv->psapriv, rsn_wpa_ie_tmp, prsn_ie_tlv); } #endif - else if (pmpriv->sec_info.ewpa_enabled) { + else if (pmpriv->sec_info.ewpa_enabled || + (pbss_desc->owe_transition_mode == + OWE_TRANS_MODE_OWE) || + (pmpriv->sec_info.authentication_mode == + MLAN_AUTH_MODE_OWE)) { prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *)pos; if (pbss_desc->pwpa_ie) { prsn_ie_tlv->header.type = @@ -1156,8 +1281,16 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, .data[0]), prsn_ie_tlv->header.len, prsn_ie_tlv->header.len); - ret = wlan_update_rsn_ie(pmpriv, - prsn_ie_tlv); + akm_type = + pauth_tlv ? + wlan_le16_to_cpu( + pauth_tlv + ->auth_type) : + AssocAgentAuth_Auto; + ret = wlan_update_rsn_ie( + pmpriv, prsn_ie_tlv, + &prsn_ie_tlv->header.len, + &akm_type); if (ret != MLAN_STATUS_SUCCESS) { goto done; } @@ -1174,8 +1307,29 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, prsn_ie_tlv->header.len; prsn_ie_tlv->header.len = wlan_cpu_to_le16( prsn_ie_tlv->header.len); + + if ((pauth_tlv == MNULL) && + (pmpriv->sec_info.authentication_mode == + MLAN_AUTH_MODE_AUTO)) { + pauth_tlv = + (MrvlIEtypes_AuthType_t *)pos; + pauth_tlv->header.type = + wlan_cpu_to_le16( + TLV_TYPE_AUTH_TYPE); + pauth_tlv->header.len = + sizeof(pauth_tlv->auth_type); + pauth_tlv->auth_type = + wlan_cpu_to_le16(akm_type); + + pos += sizeof(pauth_tlv->header) + + pauth_tlv->header.len; + pauth_tlv->header.len = + wlan_cpu_to_le16( + pauth_tlv->header.len); + } } - if (pbss_desc->prsnx_ie) { + if ((pbss_desc->prsnx_ie) && + (akm_type == AssocAgentAuth_Wpa3Sae)) { prsnx_ie_tlv = (MrvlIEtypes_SAE_PWE_Mode_t *)pos; prsnx_ie_tlv->header.type = diff --git a/mxm_wifiex/wlan_src/mlan/mlan_main.h b/mxm_wifiex/wlan_src/mlan/mlan_main.h index 5f730db..0d59837 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -1343,6 +1343,8 @@ typedef struct _mlan_private { #ifdef USB /** USB data port */ t_u32 port; + /** port Index */ + t_u32 port_index; #endif /** Control TX AMPDU on infra link */ t_u8 txaggrctrl; @@ -1817,7 +1819,7 @@ typedef struct _usb_rx_deaggr_params { usb_aggr_ctrl_cfg aggr_ctrl; } usb_rx_deaggr_params; -#define MAX_USB_TX_PORT_NUM 1 +#define MAX_USB_TX_PORT_NUM 2 /** data structure for USB Tx Aggregation */ typedef struct _usb_tx_aggr_params { /** Tx aggregation control */ @@ -1920,6 +1922,8 @@ typedef struct _mlan_init_para { t_u32 dev_cap_mask; /** oob independent reset mode */ t_u32 indrstcfg; + /** drcs channel time mode */ + t_u32 drcs_chantime_mode; /** passive to active scan */ t_u8 passive_to_active_scan; /** uap max sta */ @@ -2258,6 +2262,8 @@ typedef struct _mlan_usb_card { /** USB sggregation supported by FW */ t_u8 fw_usb_aggr; + /** port status: MFALSE-port available MTRUE--port busy*/ + t_u8 usb_port_status[MAX_USB_TX_PORT_NUM]; } mlan_usb_card, *pmlan_usb_card; #endif @@ -2633,6 +2639,14 @@ struct _mlan_adapter { /** Tx data endpoint address */ t_u8 tx_data_ep; #endif + /** Multi channel status */ + t_u8 mc_status; +#ifdef USB + /** port status: MFALSE-port available MTRUE--port busy*/ + t_u8 usb_port_status[MAX_USB_TX_PORT_NUM]; + /** usb tx ports */ + t_u8 usb_tx_ports[MAX_USB_TX_PORT_NUM]; +#endif /** sleep_params_t */ sleep_params_t sleep_params; @@ -2808,6 +2822,7 @@ struct _mlan_adapter { t_u8 coex_rx_winsize; t_bool dfs_repeater; t_u32 dfsr_channel; + t_bool mc_policy; t_u8 chanrpt_param_bandcfg; #if defined(PCIE) mlan_buffer *ssu_buf; @@ -2860,6 +2875,19 @@ struct _mlan_adapter { /** Ethernet packet type offset */ #define MLAN_ETHER_PKT_TYPE_OFFSET (12) +/** Rx packet Sniffer Operation Mode + * + * MODE1 : Can be enabled only in disconnected state. + * + * MODE3 : Can be enabled irrespective of active connection state. + * Both 802.11 and rtap headers are attached to all destined + * unicast data frames in the FW and uploaded to the host driver. + * Such frame will be duplicated in mlan, one for monitor interface + * and other for data interface, by reconstructing the 802.3 header. + */ +#define NET_MON_MODE_DISABLED 0 +#define NET_MON_MODE1 1 +#define NET_MON_MODE3 3 mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf); @@ -3328,11 +3356,61 @@ mlan_status wlan_ret_rx_pkt_coalesce_cfg(pmlan_private pmpriv, const HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); #endif +mlan_status wlan_handle_event_multi_chan_info(pmlan_private pmpriv, + pmlan_buffer pevent); +#ifdef USB + +/** + * @brief This function update the port status + * + * @param pmadapter A pointer to mlan_adapter + * @param port USB port + * @param status port status + * + * @return N/A + */ +static INLINE void wlan_update_port_status(pmlan_adapter pmadapter, t_u32 port, + t_u8 status) +{ + int i; + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { + if (port == pmadapter->usb_tx_ports[i]) { + pmadapter->pcard_usb->usb_port_status[i] = status; + break; + } + } + return; +} + +inline t_u8 wlan_usb_data_sent(pmlan_adapter pmadapter); +void wlan_resync_usb_port(pmlan_adapter pmadapter); + +/** + * @brief This function return port index + * + * @param pmadapter A pointer to mlan_adapter + * @param port USB port + * @return port index + * + */ +static INLINE t_u8 wlan_get_port_index(pmlan_adapter pmadapter, t_u32 port) +{ + t_u8 i; + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { + if (port == pmadapter->usb_tx_ports[i]) { + return i; + } + } + return 0; +} + +#endif -#ifdef STA_SUPPORT /** warm reset */ mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); + +#ifdef STA_SUPPORT /** Process received packet */ mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf); /** ioctl handler for station mode */ @@ -3699,6 +3777,15 @@ void wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent, t_u8 *wlan_get_specific_ie(pmlan_private priv, t_u8 *ie_buf, t_u8 ie_len, IEEEtypes_ElementId_e id, t_u8 ext_id); t_u8 wlan_is_wmm_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf, t_u16 buf_len); +/** Ethernet II header */ +typedef struct { + /** Ethernet II header destination address */ + t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH]; + /** Ethernet II header source address */ + t_u8 src_addr[MLAN_MAC_ADDR_LENGTH]; + /** Ethernet II header length */ + t_u16 ethertype; +} EthII_Hdr_t; /** * @brief This function checks whether a station TDLS link is enabled or not @@ -3789,6 +3876,27 @@ static INLINE int wlan_is_tx_pause(mlan_private *priv, t_u8 *ra) } t_u16 wlan_update_ralist_tx_pause(pmlan_private priv, t_u8 *mac, t_u8 tx_pause); +#if defined(USB) +/** + * @brief This function used to check if specific port is ready + * + * @param pmadapter A pointer to mlan_adapter + * @param port_index port index; + * + * @return MTRUE -- port is ready. + * MFALSE -- port is busy. + */ +static inline t_u8 wlan_is_port_ready(pmlan_adapter pmadapter, t_u32 port_index) +{ + if (IS_USB(pmadapter->card_type)) + return (pmadapter->pcard_usb->usb_port_status[port_index]) ? + MFALSE : + MTRUE; + else + return MTRUE; +} +#endif + #ifdef UAP_SUPPORT mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf); t_void wlan_drop_tx_pkts(pmlan_private priv); @@ -3985,6 +4093,38 @@ mlan_status wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); #endif +mlan_status wlan_misc_ioctl_multi_chan_config(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); + +mlan_status wlan_cmd_multi_chan_cfg(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, + t_void *pdata_buf); + +mlan_status wlan_ret_multi_chan_cfg(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + +mlan_status wlan_misc_ioctl_multi_chan_policy(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); + +mlan_status wlan_cmd_multi_chan_policy(pmlan_private pmpriv, + HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); + +mlan_status wlan_ret_multi_chan_policy(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + +mlan_status wlan_misc_ioctl_drcs_config(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); + +mlan_status wlan_cmd_drcs_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); + +mlan_status wlan_ret_drcs_cfg(pmlan_private pmpriv, + const HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + void wlan_bt_coex_wlan_param_update_event(pmlan_private priv, pmlan_buffer pevent); @@ -4140,6 +4280,10 @@ mlan_status wlan_ret_get_sensor_temp(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); +/** Set/Get Country code */ +mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req); + /** * @brief RA based queueing * diff --git a/mxm_wifiex/wlan_src/mlan/mlan_misc.c b/mxm_wifiex/wlan_src/mlan/mlan_misc.c index 11dec48..cfa4949 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_misc.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_misc.c @@ -224,7 +224,7 @@ static mlan_status wlan_custom_ioctl_auto_delete(pmlan_private pmpriv, mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_adapter pmadapter = pmpriv->adapter; t_u16 index = 0, insert = MFALSE, del_len; - t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE]; + t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE] = {0}; t_s32 cnt, tmp_len = 0; t_u8 *tmp_ie; @@ -1136,7 +1136,9 @@ t_void wlan_delay_func(mlan_adapter *pmadapter, t_u32 delay, t_delay_unit u) break; case MSEC: delay *= 1000; - /* fall through */ + upto_tv_sec += (delay / 1000000); + upto_tv_usec += (delay % 1000000); + break; case USEC: upto_tv_sec += (delay / 1000000); upto_tv_usec += (delay % 1000000); @@ -2130,8 +2132,11 @@ t_void wlan_tdls_config(pmlan_private pmpriv, t_u8 enable) tdls_all_cfg->u.tdls_config.enable = enable; tdls_config->tdls_action = WLAN_TDLS_CONFIG; /* Send command to firmware */ - wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET, - 0, MNULL, tdls_config); + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, + HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config); + if (ret) + PRINTM(MERROR, "Error sending cmd to FW\n"); + PRINTM(MCMND, "tdls_config: enable=%d\n", enable); if (tdls_config) @@ -2175,8 +2180,10 @@ static t_void wlan_tdls_cs_param_config(pmlan_private pmpriv) tdls_all_cfg->u.tdls_cs_params.threshold_directlink = 0; /* Send command to firmware */ - wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET, - 0, MNULL, tdls_config); + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, + HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config); + if (ret) + PRINTM(MERROR, "Error sending cmd to FW\n"); if (tdls_config) pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config); @@ -2259,8 +2266,10 @@ static t_void wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr, tdls_all_cfg->u.tdls_chan_switch.periodicity = 1; /* Send command to firmware */ - wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET, - 0, MNULL, tdls_config); + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, + HostCmd_ACT_GEN_SET, 0, MNULL, tdls_config); + if (ret) + PRINTM(MERROR, "Error sending cmd to FW\n"); if (tdls_config) pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config); @@ -4942,6 +4951,122 @@ mlan_status wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter, return ret; } #endif +/** + * @brief Get/Set channel time and buffer weight configuration + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_misc_ioctl_multi_chan_config(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_misc_cfg *misc = MNULL; + t_u16 cmd_action = 0; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else + cmd_action = HostCmd_ACT_GEN_GET; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MULTI_CHAN_CONFIG, + cmd_action, 0, (t_void *)pioctl_req, + &misc->param.multi_chan_cfg); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + +/** + * @brief Get/Set multi-channel policy setting + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_misc_ioctl_multi_chan_policy(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_misc_cfg *misc = MNULL; + t_u16 cmd_action = 0; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (pioctl_req->action == MLAN_ACT_SET) { + if (pmadapter->dfs_repeater) { + PRINTM(MMSG, + "DFS-Repeater is on, can not enable DRCS\n"); + ret = MLAN_STATUS_FAILURE; + goto fail; + } + cmd_action = HostCmd_ACT_GEN_SET; + } else { + cmd_action = HostCmd_ACT_GEN_GET; + } + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MULTI_CHAN_POLICY, + cmd_action, 0, (t_void *)pioctl_req, + &misc->param.multi_chan_policy); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; +fail: + LEAVE(); + return ret; +} + +/** + * @brief Get/Set DRCS configuration + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_misc_ioctl_drcs_config(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_misc_cfg *misc = MNULL; + t_u16 cmd_action = 0; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + + ENTER(); + + misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else + cmd_action = HostCmd_ACT_GEN_GET; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_DRCS_CONFIG, cmd_action, 0, + (t_void *)pioctl_req, &misc->param.drcs_cfg); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} /** * @brief Is any uAP started or STA connected? @@ -5008,6 +5133,14 @@ mlan_status wlan_misc_ioctl_dfs_repeater_cfg(pmlan_adapter pmadapter, goto done; } + /* If DRCS is on then we should not set + * DFS-repeater mode */ + if (pmadapter->mc_policy) { + PRINTM(MERROR, + "DFS-repeater cannot be started when DRCS is on\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } cmd_action = HostCmd_ACT_GEN_SET; } else { cmd_action = HostCmd_ACT_GEN_GET; @@ -6324,18 +6457,6 @@ mlan_status wlan_misc_ioctl_net_monitor(pmlan_adapter pmadapter, pmpriv = pmadapter->priv[pioctl_req->bss_index]; misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; - - if (misc->param.net_mon.enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { - /* Net monitor IOCTL not allowed in connected state */ - if (pmpriv->media_connected == MTRUE) { - PRINTM(MERROR, - "IOCTL not allowed in connected state\n"); - pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; - LEAVE(); - return MLAN_STATUS_FAILURE; - } - } - if (pioctl_req->action == MLAN_ACT_SET) cmd_action = HostCmd_ACT_GEN_SET; else @@ -6899,6 +7020,98 @@ mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter, return ret; } +/** + * @brief Perform warm reset + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE + */ +mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_status ret = MLAN_STATUS_SUCCESS; + pmlan_callbacks pcb = &pmadapter->callbacks; + pmlan_buffer pmbuf; + t_s32 i = 0; + t_u16 mc_policy = pmadapter->mc_policy; + mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + + ENTER(); + mlan_block_rx_process(pmadapter, MTRUE); + + /* Cancel all pending commands and complete ioctls */ + if (misc->param.fw_reload) + wlan_cancel_all_pending_cmd(pmadapter, MTRUE); + + /** Init all the head nodes and free all the locks here */ + for (i = 0; i < pmadapter->priv_num; i++) + wlan_free_priv(pmadapter->priv[i]); + + while ((pmbuf = (pmlan_buffer)util_dequeue_list( + pmadapter->pmoal_handle, &pmadapter->rx_data_queue, + pcb->moal_spin_lock, pcb->moal_spin_unlock))) { + pmadapter->ops.data_complete(pmadapter, pmbuf, + MLAN_STATUS_FAILURE); + } + pmadapter->rx_pkts_queued = 0; + + /* Initialize adapter structure */ + wlan_init_adapter(pmadapter); + pmadapter->hw_status = WlanHardwareStatusInitializing; + + /* Initialize private structures */ + for (i = 0; i < pmadapter->priv_num; i++) { + if (pmadapter->priv[i]) + wlan_init_priv(pmadapter->priv[i]); + } + mlan_block_rx_process(pmadapter, MFALSE); + + if (misc->param.fw_reload != MTRUE) { + /* Restart the firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN, + HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); + if (ret) + goto done; + } + + /* Issue firmware initialize commands for first BSS, + * for other interfaces it will be called after getting + * the last init command response of previous interface + */ + pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); + if (!pmpriv) { + ret = MLAN_STATUS_FAILURE; + LEAVE(); + return ret; + } + ret = wlan_adapter_get_hw_spec(pmpriv->adapter); + if (ret == MLAN_STATUS_FAILURE) { + LEAVE(); + return ret; + } + ret = pmpriv->ops.init_cmd(pmpriv, MTRUE); + if (ret == MLAN_STATUS_FAILURE) { + LEAVE(); + return ret; + } + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MULTI_CHAN_POLICY, + HostCmd_ACT_GEN_SET, 0, MNULL, &mc_policy); + if (ret == MLAN_STATUS_FAILURE) { + LEAVE(); + return ret; + } + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + if (ret == MLAN_STATUS_PENDING) + pmadapter->pwarm_reset_ioctl_req = pioctl_req; +done: + LEAVE(); + return ret; +} + #ifdef UAP_SUPPORT /** * @brief set wacp mode @@ -6964,3 +7177,72 @@ mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter, LEAVE(); return ret; } + +/** + * @brief This function sets up country code and downloads CMD to FW + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req Pointer to the IOCTL request buffer + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter, + mlan_ioctl_req *pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_country_code *country_code = MNULL; + mlan_ds_misc_cfg *cfg_misc = MNULL; + t_u8 cfp_bg = 0, cfp_a = 0; + + ENTER(); + + cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + country_code = &cfg_misc->param.country_code; + + if (pioctl_req->action == MLAN_ACT_SET) { + if (pmadapter->otp_region && pmadapter->otp_region->force_reg) { + PRINTM(MERROR, + "ForceRegionRule is set in the on-chip OTP" + "memory\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + /* Update region code and table based on country code */ + if (wlan_misc_country_2_cfp_table_code( + pmadapter, country_code->country_code, &cfp_bg, + &cfp_a)) { + PRINTM(MERROR, "Country code not found!\n"); + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + pmadapter->cfp_code_bg = cfp_bg; + pmadapter->cfp_code_a = cfp_a; + if (cfp_a) + pmadapter->region_code = cfp_a; + else if (cfp_bg) + pmadapter->region_code = cfp_bg; + else + pmadapter->region_code = 0; + if (wlan_set_regiontable(pmpriv, pmadapter->region_code, + pmadapter->config_bands | + pmadapter->adhoc_start_band)) { + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + memcpy_ext(pmadapter, pmadapter->country_code, + country_code->country_code, COUNTRY_CODE_LEN, + COUNTRY_CODE_LEN); + } else { + /* GET operation */ + memcpy_ext(pmadapter, country_code->country_code, + pmadapter->country_code, COUNTRY_CODE_LEN, + COUNTRY_CODE_LEN); + } + +done: + LEAVE(); + return ret; +} diff --git a/mxm_wifiex/wlan_src/mlan/mlan_scan.c b/mxm_wifiex/wlan_src/mlan/mlan_scan.c index ad5a165..75beff5 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_scan.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_scan.c @@ -1740,6 +1740,7 @@ static mlan_status wlan_interpret_bss_desc_with_ie(pmlan_adapter pmadapter, IEEEtypes_VendorSpecific_t *pvendor_ie; const t_u8 wpa_oui[4] = {0x00, 0x50, 0xf2, 0x01}; const t_u8 wmm_oui[4] = {0x00, 0x50, 0xf2, 0x02}; + const t_u8 owe_oui[4] = {0x50, 0x6f, 0x9a, 0x1c}; const t_u8 osen_oui[] = {0x50, 0x6f, 0x9a, 0x12}; IEEEtypes_CountryInfoSet_t *pcountry_info; @@ -2079,6 +2080,54 @@ static mlan_status wlan_interpret_bss_desc_with_ie(pmlan_adapter pmadapter, (t_u8 *)&pbss_entry->wmm_ie, total_ie_len); } + } else if (IS_FW_SUPPORT_EMBEDDED_OWE(pmadapter) && + !memcmp(pmadapter, pvendor_ie->vend_hdr.oui, + owe_oui, sizeof(owe_oui))) { + /* Current Format of OWE IE is + * element_id:element_len:oui:MAC Address:SSID + * length:SSID */ + t_u8 trans_ssid_len = *( + pcurrent_ptr + + sizeof(IEEEtypes_Header_t) + + sizeof(owe_oui) + MLAN_MAC_ADDR_LENGTH); + + if (!trans_ssid_len || + trans_ssid_len > MRVDRV_MAX_SSID_LENGTH) { + bytes_left_for_current_beacon = 0; + continue; + } + if (!pcap_info->privacy) + pbss_entry->owe_transition_mode = + OWE_TRANS_MODE_OPEN; + else + pbss_entry->owe_transition_mode = + OWE_TRANS_MODE_OWE; + + memcpy_ext( + pmadapter, + pbss_entry->trans_mac_address, + (pcurrent_ptr + + sizeof(IEEEtypes_Header_t) + + sizeof(owe_oui)), + MLAN_MAC_ADDR_LENGTH, + sizeof(pbss_entry->trans_mac_address)); + pbss_entry->trans_ssid.ssid_len = + trans_ssid_len; + memcpy_ext( + pmadapter, pbss_entry->trans_ssid.ssid, + (pcurrent_ptr + + sizeof(IEEEtypes_Header_t) + + sizeof(owe_oui) + + MLAN_MAC_ADDR_LENGTH + sizeof(t_u8)), + trans_ssid_len, + sizeof(pbss_entry->trans_ssid.ssid)); + + PRINTM(MCMND, + "InterpretIE: OWE Transition AP privacy=%d MAC Addr-" MACSTR + " ssid %s\n", + pbss_entry->owe_transition_mode, + MAC2STR(pbss_entry->trans_mac_address), + pbss_entry->trans_ssid.ssid); } else if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui, osen_oui, sizeof(osen_oui))) { pbss_entry->posen_ie = @@ -3781,6 +3830,13 @@ t_s32 wlan_is_network_compatible(mlan_private *pmpriv, t_u32 index, t_u32 mode) LEAVE(); return index; } + if ((pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OPEN) && + (pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_OWE)) { + PRINTM(MINFO, + "Return success directly in OWE Transition mode\n"); + LEAVE(); + return index; + } if (pmpriv->sec_info.osen_enabled && pbss_desc->posen_ie && ((*(pbss_desc->posen_ie)).ieee_hdr.element_id == @@ -3799,7 +3855,8 @@ t_s32 wlan_is_network_compatible(mlan_private *pmpriv, t_u32 index, t_u32 mode) #ifdef DRV_EMBEDDED_SUPPLICANT || supplicantIsEnabled(pmpriv->psapriv) #endif - )) { + || pmpriv->sec_info.authentication_mode == MLAN_AUTH_MODE_OWE || + pbss_desc->owe_transition_mode == OWE_TRANS_MODE_OWE)) { if (((pbss_desc->pwpa_ie) && ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE)) || ((pbss_desc->prsn_ie) && @@ -4142,7 +4199,6 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf, t_u8 filtered_scan; t_u8 scan_current_chan_only; t_u8 max_chan_per_scan; - t_u8 i; ENTER(); @@ -4209,8 +4265,6 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf, } else { wlan_scan_delete_ageout_entry(pmpriv); } - for (i = 0; i < pmadapter->num_in_chan_stats; i++) - pmadapter->pchan_stats[i].cca_scan_duration = 0; pmadapter->idx_chan_stats = 0; ret = wlan_scan_channel_list(pmpriv, pioctl_buf, max_chan_per_scan, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c index 83e6a60..9a9b360 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c @@ -976,7 +976,7 @@ static mlan_status wlan_sdio_prog_fw_w_helper(pmlan_adapter pmadapter, t_u8 *fw, t_u8 *firmware = fw; t_u32 firmwarelen = fw_len; t_u32 offset = 0; - t_u32 base0, base1; + t_u32 base0 = 0, base1; t_void *tmpfwbuf = MNULL; t_u32 tmpfwbufsz; t_u8 *fwbuf; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_shim.c b/mxm_wifiex/wlan_src/mlan/mlan_shim.c index fef623f..fdd7140 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_shim.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_shim.c @@ -170,7 +170,6 @@ static void wlan_process_pending_ioctl(mlan_adapter *pmadapter) } break; #endif -#ifdef STA_SUPPORT case MLAN_IOCTL_MISC_CFG: misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; if (misc->sub_command == MLAN_OID_MISC_WARM_RESET) { @@ -179,7 +178,6 @@ static void wlan_process_pending_ioctl(mlan_adapter *pmadapter) pioctl_buf); } break; -#endif default: break; } @@ -442,6 +440,7 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter) pmadapter->multiple_dtim = pmdevice->multi_dtim; pmadapter->inact_tmo = pmdevice->inact_tmo; + pmadapter->init_para.drcs_chantime_mode = pmdevice->drcs_chantime_mode; pmadapter->hs_wake_interval = pmdevice->hs_wake_interval; if (pmdevice->indication_gpio != 0xff) { pmadapter->ind_gpio = pmdevice->indication_gpio & 0x0f; @@ -459,6 +458,8 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter) pmadapter->rx_cmd_ep = pmdevice->rx_cmd_ep; pmadapter->tx_data_ep = pmdevice->tx_data_ep; pmadapter->rx_data_ep = pmdevice->rx_data_ep; + pmadapter->usb_tx_ports[0] = pmdevice->tx_data_ep; + pmadapter->usb_tx_ports[1] = pmdevice->tx_data2_ep; } #endif pmadapter->init_para.dfs53cfg = pmdevice->dfs53cfg; @@ -1525,6 +1526,9 @@ mlan_status mlan_write_data_async_complete(t_void *padapter, pmlan_buffer pmbuf, wlan_free_mlan_buffer(pmadapter, pmbuf); } else { pmadapter->data_sent = MFALSE; + wlan_update_port_status(pmadapter, port, MFALSE); + PRINTM(MDATA, "mlan_write_data_async_complete: DATA(%d)\n", + port); ret = wlan_write_data_complete(pmadapter, pmbuf, status); } @@ -1548,9 +1552,9 @@ mlan_status mlan_recv(t_void *padapter, pmlan_buffer pmbuf, t_u32 port) mlan_adapter *pmadapter = (mlan_adapter *)padapter; t_u8 *pbuf; t_u32 len, recv_type; - t_u32 event_cause; + t_u32 event_cause = 0; #ifdef DEBUG_LEVEL1 - t_u32 sec, usec; + t_u32 sec = 0, usec = 0; #endif t_u32 max_rx_data_size = MLAN_RX_DATA_BUF_SIZE; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c index 06a1cc5..0aa13e9 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c @@ -2669,13 +2669,15 @@ mlan_status wlan_cmd_net_monitor(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, cmd->command = wlan_cpu_to_le16(cmd->command); cmd_net_mon->action = wlan_cpu_to_le16(cmd_action); if (cmd_action == HostCmd_ACT_GEN_SET) { - cmd_net_mon->enable_net_mon = - wlan_cpu_to_le16((t_u16)net_mon->enable_net_mon); if (net_mon->enable_net_mon) { - pchan_band = - &cmd_net_mon->monitor_chan.chan_band_param[0]; + cmd_net_mon->enable_net_mon = + wlan_cpu_to_le16((t_u16)NET_MON_MODE1); cmd_net_mon->filter_flag = wlan_cpu_to_le16((t_u16)net_mon->filter_flag); + } + if (net_mon->enable_net_mon && net_mon->channel) { + pchan_band = + &cmd_net_mon->monitor_chan.chan_band_param[0]; cmd_net_mon->monitor_chan.header.type = wlan_cpu_to_le16(TLV_TYPE_CHANNELBANDLIST); cmd_net_mon->monitor_chan.header.len = @@ -4017,6 +4019,17 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, pdata_buf); break; #endif + case HostCmd_CMD_MULTI_CHAN_CONFIG: + ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_MULTI_CHAN_POLICY: + ret = wlan_cmd_multi_chan_policy(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_DRCS_CONFIG: + ret = wlan_cmd_drcs_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); + break; case HostCMD_CONFIG_LOW_POWER_MODE: ret = wlan_cmd_low_pwr_mode(pmpriv, cmd_ptr, pdata_buf); break; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c index 79432a7..746e265 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c @@ -1318,11 +1318,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv, } if (memcmp(pmpriv->adapter, pmpriv->gtk_rekey.kek, zero_kek, sizeof(zero_kek)) != 0) { - wlan_prepare_cmd( + mlan_status ret = MLAN_STATUS_SUCCESS; + ret = wlan_prepare_cmd( pmpriv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG, HostCmd_ACT_GEN_SET, 0, MNULL, &pmpriv->gtk_rekey); + if (ret) { + PRINTM(MINFO, + "Error sending message to FW\n"); + } memset(pmpriv->adapter, &pmpriv->gtk_rekey, 0, sizeof(mlan_ds_misc_gtk_rekey_data)); } @@ -1391,13 +1396,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv, wlan_le16_to_cpu( pkey->key_param_set.key_params .aes.key_len); - memcpy_ext( - pmpriv->adapter, - sec->param.encrypt_key.key_material, - pkey->key_param_set.key_params.aes.key, + sec->param.encrypt_key + .key_len = MIN( sec->param.encrypt_key.key_len, - sizeof(sec->param.encrypt_key - .key_material)); + sizeof(pkey->key_param_set.key_params + .aes.key)), + memcpy_ext(pmpriv->adapter, + sec->param.encrypt_key.key_material, + pkey->key_param_set.key_params.aes.key, + sec->param.encrypt_key.key_len, + sizeof(sec->param.encrypt_key.key_material)); memcpy_ext( pmpriv->adapter, sec->param.encrypt_key.pn, @@ -1410,13 +1418,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv, wlan_le16_to_cpu( pkey->key_param_set.key_params .cmac_aes.key_len); - memcpy_ext(pmpriv->adapter, - sec->param.encrypt_key.key_material, - pkey->key_param_set.key_params - .cmac_aes.key, - sec->param.encrypt_key.key_len, - sizeof(sec->param.encrypt_key - .key_material)); + sec->param.encrypt_key + .key_len = MIN( + sec->param.encrypt_key.key_len, + sizeof(pkey->key_param_set.key_params + .cmac_aes.key)), + memcpy_ext(pmpriv->adapter, + sec->param.encrypt_key.key_material, + pkey->key_param_set.key_params.cmac_aes.key, + sec->param.encrypt_key.key_len, + sizeof(sec->param.encrypt_key.key_material)); memcpy_ext(pmpriv->adapter, sec->param.encrypt_key.pn, pkey->key_param_set.key_params @@ -1429,13 +1440,16 @@ static mlan_status wlan_ret_802_11_key_material(pmlan_private pmpriv, wlan_le16_to_cpu( pkey->key_param_set.key_params .wep.key_len); - memcpy_ext( - pmpriv->adapter, - sec->param.encrypt_key.key_material, - pkey->key_param_set.key_params.wep.key, + sec->param.encrypt_key + .key_len = MIN( sec->param.encrypt_key.key_len, - sizeof(sec->param.encrypt_key - .key_material)); + sizeof(pkey->key_param_set.key_params + .wep.key)), + memcpy_ext(pmpriv->adapter, + sec->param.encrypt_key.key_material, + pkey->key_param_set.key_params.wep.key, + sec->param.encrypt_key.key_len, + sizeof(sec->param.encrypt_key.key_material)); break; } } @@ -3216,6 +3230,10 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: wlan_set_tx_pause_flag(pmpriv, MFALSE); +#if defined(USB) + if (IS_USB(pmadapter->card_type)) + wlan_resync_usb_port(pmadapter); +#endif pmadapter->tx_buf_size = (t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size); @@ -3383,6 +3401,15 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf); break; #endif + case HostCmd_CMD_MULTI_CHAN_CONFIG: + ret = wlan_ret_multi_chan_cfg(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_MULTI_CHAN_POLICY: + ret = wlan_ret_multi_chan_policy(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_DRCS_CONFIG: + ret = wlan_ret_drcs_cfg(pmpriv, resp, pioctl_buf); + break; case HostCMD_CONFIG_LOW_POWER_MODE: break; case HostCmd_DFS_REPEATER_MODE: diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c index d336eb7..effe3cc 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c @@ -171,6 +171,7 @@ static void wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent) case TDLS_EVENT_TYPE_LINK_TORN_DOWN: if (sta_ptr) { if (sta_ptr->external_tdls) { + mlan_status ret = MLAN_STATUS_SUCCESS; PRINTM(MMSG, "Receive TDLS TEAR DOWN event, Disable TDLS LINK\n"); pmadapter->tdls_status = TDLS_TEAR_DOWN; @@ -183,10 +184,13 @@ static void wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent) MLAN_MAC_ADDR_LENGTH); /* Send command to firmware to delete tdls * link*/ - wlan_prepare_cmd(priv, - HostCmd_CMD_TDLS_OPERATION, - HostCmd_ACT_GEN_SET, 0, - (t_void *)MNULL, &tdls_oper); + ret = wlan_prepare_cmd( + priv, HostCmd_CMD_TDLS_OPERATION, + HostCmd_ACT_GEN_SET, 0, (t_void *)MNULL, + &tdls_oper); + if (ret) + PRINTM(MERROR, + "11D: failed to send cmd to FW\n"); ptdls_event->bss_index = priv->bss_index; ptdls_event->event_id = MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ; @@ -799,7 +803,12 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) if (pmadapter->pps_uapsd_mode && pmadapter->gen_null_pkt) { if (MTRUE == wlan_check_last_packet_indication(pmpriv)) { - if (!pmadapter->data_sent) { + if (!pmadapter->data_sent +#if defined(USB) + && wlan_is_port_ready(pmadapter, + pmpriv->port_index) +#endif + ) { if (wlan_send_null_packet( pmpriv, MRVDRV_TxPD_POWER_MGMT_NULL_PACKET | @@ -1258,6 +1267,10 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) eventcause, pevt_dat[0] + 1, pevt_dat[1] + 1, pevt_dat[2], pevt_dat[3]); } break; + case EVENT_MULTI_CHAN_INFO: + PRINTM(MEVENT, "EVENT: MULTI_CHAN_INFO\n"); + wlan_handle_event_multi_chan_info(pmpriv, pmbuf); + break; case EVENT_FW_DUMP_INFO: PRINTM(MINFO, "EVENT: Dump FW info\n"); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c index 6b70bed..323596d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c @@ -1016,12 +1016,6 @@ static mlan_status wlan_bss_ioctl_start(pmlan_adapter pmadapter, ENTER(); - if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { - PRINTM(MINFO, - "Association is blocked in Channel Specified Network Monitor mode...\n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } /* Before ASSOC REQ, If "port ctrl" mode is enabled, * move the port to CLOSED state */ if (pmpriv->port_ctrl_mode == MTRUE) { @@ -2945,7 +2939,9 @@ static mlan_status wlan_sec_ioctl_set_wep_key(pmlan_adapter pmadapter, goto exit; if (!sec->param.encrypt_key.key_len) { sec->param.encrypt_key.key_index = pwep_key->key_index; - sec->param.encrypt_key.key_len = pwep_key->key_length; + sec->param.encrypt_key.key_len = + MIN(pwep_key->key_length, + sizeof(pwep_key->key_material)); memcpy_ext(pmadapter, sec->param.encrypt_key.key_material, pwep_key->key_material, @@ -3994,89 +3990,6 @@ static mlan_status wlan_misc_ioctl_gen_ie(pmlan_adapter pmadapter, return ret; } -/** - * @brief Perform warm reset - * - * @param pmadapter A pointer to mlan_adapter structure - * @param pioctl_req A pointer to ioctl request buffer - * - * @return MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE - */ -mlan_status wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter, - pmlan_ioctl_req pioctl_req) -{ - pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index]; - mlan_status ret = MLAN_STATUS_SUCCESS; - pmlan_callbacks pcb = &pmadapter->callbacks; - pmlan_buffer pmbuf; - t_s32 i = 0; - mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; - - ENTER(); - mlan_block_rx_process(pmadapter, MTRUE); - - /* Cancel all pending commands and complete ioctls */ - if (misc->param.fw_reload) - wlan_cancel_all_pending_cmd(pmadapter, MTRUE); - - /** Init all the head nodes and free all the locks here */ - for (i = 0; i < pmadapter->priv_num; i++) - wlan_free_priv(pmadapter->priv[i]); - - while ((pmbuf = (pmlan_buffer)util_dequeue_list( - pmadapter->pmoal_handle, &pmadapter->rx_data_queue, - pcb->moal_spin_lock, pcb->moal_spin_unlock))) { - pmadapter->ops.data_complete(pmadapter, pmbuf, - MLAN_STATUS_FAILURE); - } - pmadapter->rx_pkts_queued = 0; - - /* Initialize adapter structure */ - wlan_init_adapter(pmadapter); - pmadapter->hw_status = WlanHardwareStatusInitializing; - - /* Initialize private structures */ - for (i = 0; i < pmadapter->priv_num; i++) { - if (pmadapter->priv[i]) - wlan_init_priv(pmadapter->priv[i]); - } - mlan_block_rx_process(pmadapter, MFALSE); - - if (misc->param.fw_reload != MTRUE) { - /* Restart the firmware */ - ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN, - HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); - if (ret) - goto done; - } - - /* Issue firmware initialize commands for first BSS, - * for other interfaces it will be called after getting - * the last init command response of previous interface - */ - pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); - if (!pmpriv) { - ret = MLAN_STATUS_FAILURE; - LEAVE(); - return ret; - } - ret = wlan_adapter_get_hw_spec(pmpriv->adapter); - if (ret == MLAN_STATUS_FAILURE) { - LEAVE(); - return ret; - } - ret = pmpriv->ops.init_cmd(pmpriv, MTRUE); - if (ret == MLAN_STATUS_FAILURE) { - LEAVE(); - return ret; - } - if (ret == MLAN_STATUS_PENDING) - pmadapter->pwarm_reset_ioctl_req = pioctl_req; -done: - LEAVE(); - return ret; -} - #ifdef SDIO /** * @brief Reconfigure SDIO multiport aggregation parameters @@ -4762,75 +4675,6 @@ done: return ret; } -/** - * @brief This function sets up country code and downloads CMD to FW - * - * @param pmadapter A pointer to mlan_adapter structure - * @param pioctl_req Pointer to the IOCTL request buffer - * - * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE - */ -static mlan_status wlan_misc_ioctl_country_code(pmlan_adapter pmadapter, - mlan_ioctl_req *pioctl_req) -{ - mlan_status ret = MLAN_STATUS_SUCCESS; - mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; - mlan_ds_misc_country_code *country_code = MNULL; - mlan_ds_misc_cfg *cfg_misc = MNULL; - t_u8 cfp_bg = 0, cfp_a = 0; - - ENTER(); - - cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; - country_code = &cfg_misc->param.country_code; - - if (pioctl_req->action == MLAN_ACT_SET) { - if (pmadapter->otp_region && pmadapter->otp_region->force_reg) { - PRINTM(MERROR, - "ForceRegionRule is set in the on-chip OTP" - "memory\n"); - ret = MLAN_STATUS_FAILURE; - goto done; - } - /* Update region code and table based on country code */ - if (wlan_misc_country_2_cfp_table_code( - pmadapter, country_code->country_code, &cfp_bg, - &cfp_a)) { - PRINTM(MERROR, "Country code not found!\n"); - pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; - ret = MLAN_STATUS_FAILURE; - goto done; - } - pmadapter->cfp_code_bg = cfp_bg; - pmadapter->cfp_code_a = cfp_a; - if (cfp_a) - pmadapter->region_code = cfp_a; - else if (cfp_bg) - pmadapter->region_code = cfp_bg; - else - pmadapter->region_code = 0; - if (wlan_set_regiontable(pmpriv, pmadapter->region_code, - pmadapter->config_bands | - pmadapter->adhoc_start_band)) { - pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; - ret = MLAN_STATUS_FAILURE; - goto done; - } - memcpy_ext(pmadapter, pmadapter->country_code, - country_code->country_code, COUNTRY_CODE_LEN, - COUNTRY_CODE_LEN); - } else { - /* GET operation */ - memcpy_ext(pmadapter, country_code->country_code, - pmadapter->country_code, COUNTRY_CODE_LEN, - COUNTRY_CODE_LEN); - } - -done: - LEAVE(); - return ret; -} - /** * @brief Configure MFPC and MFPR for management frame protection * @@ -5318,6 +5162,17 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, case MLAN_OID_MISC_PMFCFG: status = wlan_misc_pmfcfg(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_MULTI_CHAN_CFG: + status = wlan_misc_ioctl_multi_chan_config(pmadapter, + pioctl_req); + break; + case MLAN_OID_MISC_MULTI_CHAN_POLICY: + status = wlan_misc_ioctl_multi_chan_policy(pmadapter, + pioctl_req); + break; + case MLAN_OID_MISC_DRCS_CFG: + status = wlan_misc_ioctl_drcs_config(pmadapter, pioctl_req); + break; #ifdef RX_PACKET_COALESCE case MLAN_OID_MISC_RX_PACKET_COALESCE: status = wlan_misc_ioctl_rx_pkt_coalesce_config(pmadapter, @@ -5579,13 +5434,6 @@ static mlan_status wlan_scan_ioctl(pmlan_adapter pmadapter, return status; } - if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { - PRINTM(MINFO, - "Scan is blocked in Channel Specified Network Monitor mode...\n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } - if (pmadapter->scan_block && pioctl_req->action == MLAN_ACT_SET) { PRINTM(MERROR, "Scan is blocked during association...\n"); LEAVE(); @@ -5792,6 +5640,18 @@ mlan_status wlan_find_bss(mlan_private *pmpriv, pmlan_ioctl_req pioctl_req) memcpy_ext(pmadapter, (t_u8 *)&bss->param.ssid_bssid.bssid, (t_u8 *)&pbss_desc->mac_address, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + if (pbss_desc->owe_transition_mode) { + bss->param.ssid_bssid.owe_transition_mode = + pbss_desc->owe_transition_mode; + memcpy_ext(pmadapter, &bss->param.ssid_bssid.trans_ssid, + &pbss_desc->trans_ssid, + sizeof(mlan_802_11_ssid), + sizeof(mlan_802_11_ssid)); + memcpy_ext(pmadapter, + (t_u8 *)&bss->param.ssid_bssid.trans_bssid, + (t_u8 *)&pbss_desc->trans_mac_address, + MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + } bss->param.ssid_bssid.rssi = pbss_desc->rssi; bss->param.ssid_bssid.channel = (t_u16)pbss_desc->channel; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c index adadf87..bb9920a 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_rx.c @@ -42,17 +42,6 @@ Change log: Local Variables ********************************************************/ -/** Ethernet II header */ -typedef struct { - /** Ethernet II header destination address */ - t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH]; - /** Ethernet II header source address */ - t_u8 src_addr[MLAN_MAC_ADDR_LENGTH]; - /** Ethernet II header length */ - t_u16 ethertype; - -} EthII_Hdr_t; - /** IPv4 ARP request header */ typedef MLAN_PACK_START struct { /** Hardware type */ @@ -614,8 +603,10 @@ mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num, prx_pd->priority); if (pmadapter->enable_net_mon) { - pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; - goto mon_process; + if (prx_pd->rx_pkt_type == PKT_TYPE_802DOT11) { + pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; + goto mon_process; + } } #ifdef DRV_EMBEDDED_SUPPLICANT diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c index f73f288..49ff34d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sta_tx.c @@ -256,6 +256,12 @@ mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags) ret = MLAN_STATUS_FAILURE; goto done; } +#if defined(USB) + if (!wlan_is_port_ready(pmadapter, priv->port_index)) { + ret = MLAN_STATUS_FAILURE; + goto done; + } +#endif pmbuf = wlan_alloc_mlan_buffer(pmadapter, data_len, 0, MOAL_MALLOC_BUFFER); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_txrx.c b/mxm_wifiex/wlan_src/mlan/mlan_txrx.c index c937e78..c55c145 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_txrx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_txrx.c @@ -315,7 +315,28 @@ t_void wlan_add_buf_bypass_txqueue(mlan_adapter *pmadapter, pmlan_buffer pmbuf) */ INLINE t_u8 wlan_bypass_tx_list_empty(mlan_adapter *pmadapter) { - return (pmadapter->bypass_pkt_count) ? MFALSE : MTRUE; +#if defined(USB) + if (IS_USB(pmadapter->card_type)) { + pmlan_callbacks pcb = &pmadapter->callbacks; + pmlan_private priv; + int j = 0; + for (j = 0; j < pmadapter->priv_num; ++j) { + priv = pmadapter->priv[j]; + if (priv) { + if (!wlan_is_port_ready(pmadapter, + priv->port_index)) + continue; + if (util_peek_list(pmadapter->pmoal_handle, + &priv->bypass_txq, + pcb->moal_spin_lock, + pcb->moal_spin_unlock)) + return MFALSE; + } + } + return MTRUE; + } else +#endif + return (pmadapter->bypass_pkt_count) ? MFALSE : MTRUE; } /** @@ -364,6 +385,11 @@ t_void wlan_process_bypass_tx(pmlan_adapter pmadapter) for (j = 0; j < pmadapter->priv_num; ++j) { priv = pmadapter->priv[j]; if (priv) { +#if defined(USB) + if (!wlan_is_port_ready(pmadapter, + priv->port_index)) + continue; +#endif pmbuf = (pmlan_buffer)util_dequeue_list( pmadapter->pmoal_handle, &priv->bypass_txq, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index 982b7e6..f1e224f 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -2293,6 +2293,11 @@ static mlan_status wlan_uap_ret_cmd_ap_config(pmlan_private pmpriv, bss->param.bss_config.wpa_cfg .pairwise_cipher_wpa2 = tlv_pwk_cipher->pairwise_cipher; + if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) & + PROTOCOL_OWE) + bss->param.bss_config.wpa_cfg + .pairwise_cipher_wpa2 = + tlv_pwk_cipher->pairwise_cipher; if (wlan_le16_to_cpu(tlv_pwk_cipher->protocol) & PROTOCOL_WPA3_SAE) bss->param.bss_config.wpa_cfg @@ -2670,6 +2675,7 @@ static mlan_status wlan_uap_ret_sys_config(pmlan_private pmpriv, chan_band_tlv->bandcfg; bss->param.ap_channel.channel = chan_band_tlv->channel; + bss->param.ap_channel.center_chan = 0; bss->param.ap_channel.is_11n_enabled = pmpriv->is_11n_enabled; pmpriv->uap_channel = @@ -3816,6 +3822,7 @@ static void wlan_check_uap_capability(pmlan_private priv, pmlan_buffer pevent) priv->is_11n_enabled = MFALSE; priv->is_11ac_enabled = MFALSE; priv->is_11ax_enabled = MFALSE; + event->event_id = 0; while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) { tlv_type = wlan_le16_to_cpu(tlv->type); @@ -4788,6 +4795,17 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_WMM_QUEUE_CONFIG: ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf); break; + case HostCmd_CMD_MULTI_CHAN_CONFIG: + ret = wlan_cmd_multi_chan_cfg(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_MULTI_CHAN_POLICY: + ret = wlan_cmd_multi_chan_policy(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; + case HostCmd_CMD_DRCS_CONFIG: + ret = wlan_cmd_drcs_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); + break; #ifdef RX_PACKET_COALESCE case HostCmd_CMD_RX_PKT_COALESCE_CFG: ret = wlan_cmd_rx_pkt_coalesce_cfg(pmpriv, cmd_ptr, cmd_action, @@ -5108,6 +5126,10 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: wlan_set_tx_pause_flag(pmpriv, MFALSE); +#if defined(USB) + if (IS_USB(pmadapter->card_type)) + wlan_resync_usb_port(pmadapter); +#endif pmadapter->tx_buf_size = (t_u16)wlan_le16_to_cpu(resp->params.tx_buf.buff_size); @@ -5217,6 +5239,15 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_WMM_QUEUE_CONFIG: ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_MULTI_CHAN_CONFIG: + ret = wlan_ret_multi_chan_cfg(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_MULTI_CHAN_POLICY: + ret = wlan_ret_multi_chan_policy(pmpriv, resp, pioctl_buf); + break; + case HostCmd_CMD_DRCS_CONFIG: + ret = wlan_ret_drcs_cfg(pmpriv, resp, pioctl_buf); + break; #ifdef RX_PACKET_COALESCE case HostCmd_CMD_RX_PKT_COALESCE_CFG: ret = wlan_ret_rx_pkt_coalesce_cfg(pmpriv, resp, pioctl_buf); @@ -5772,6 +5803,10 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL); pevent->event_id = MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED; break; + case EVENT_MULTI_CHAN_INFO: + PRINTM(MEVENT, "EVENT: MULTI_CHAN_INFO\n"); + wlan_handle_event_multi_chan_info(pmpriv, pmbuf); + break; case EVENT_FW_DEBUG_INFO: memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c index ad6d51b..4887842 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c @@ -83,7 +83,8 @@ static t_bool wlan_can_radar_det_skip(mlan_private *priv) * is off then 11n_radar detection is not required for subsequent BSSes * since they will follow the primary bss. */ - if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)) { + if (!priv->adapter->mc_policy && + (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)) { memset(pmadapter, priv_list, 0x00, sizeof(priv_list)); pcount = wlan_get_privs_by_cond(pmadapter, wlan_is_intf_active, priv_list); @@ -285,13 +286,6 @@ static mlan_status wlan_uap_bss_ioctl_start(pmlan_adapter pmadapter, ENTER(); - if (pmadapter->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { - PRINTM(MINFO, - "BSS start is blocked in Channel Specified Network Monitor mode...\n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } - bss = (mlan_ds_bss *)pioctl_req->pbuf; pmpriv->uap_host_based = bss->param.host_based; if (!pmpriv->intf_state_11h.is_11h_host && @@ -2165,6 +2159,17 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) if (misc->sub_command == MLAN_OID_MISC_SOFT_RESET) status = wlan_uap_misc_ioctl_soft_reset(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_WARM_RESET) { + PRINTM(MCMND, "Request UAP WARM RESET\n"); + util_enqueue_list_tail( + pmadapter->pmoal_handle, + &pmadapter->ioctl_pending_q, + (pmlan_linked_list)pioctl_req, + pmadapter->callbacks.moal_spin_lock, + pmadapter->callbacks.moal_spin_unlock); + pmadapter->pending_ioctl = MTRUE; + status = MLAN_STATUS_PENDING; + } if (misc->sub_command == MLAN_OID_MISC_HOST_CMD) status = wlan_misc_ioctl_host_cmd(pmadapter, pioctl_req); @@ -2192,6 +2197,15 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) if (misc->sub_command == MLAN_OID_MISC_MAC_CONTROL) status = wlan_misc_ioctl_mac_control(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_MULTI_CHAN_CFG) + status = wlan_misc_ioctl_multi_chan_config(pmadapter, + pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_MULTI_CHAN_POLICY) + status = wlan_misc_ioctl_multi_chan_policy(pmadapter, + pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_DRCS_CFG) + status = wlan_misc_ioctl_drcs_config(pmadapter, + pioctl_req); #ifdef RX_PACKET_COALESCE if (misc->sub_command == MLAN_OID_MISC_RX_PACKET_COALESCE) status = wlan_misc_ioctl_rx_pkt_coalesce_config( @@ -2303,6 +2317,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) if (misc->sub_command == MLAN_OID_MISC_WACP_MODE) status = wlan_misc_ioctl_wacp_mode(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_COUNTRY_CODE) + status = wlan_misc_ioctl_country_code(pmadapter, + pioctl_req); break; case MLAN_IOCTL_POWER_CFG: power = (mlan_ds_power_cfg *)pioctl_req->pbuf; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c index efb0176..d2aaa9a 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_txrx.c @@ -420,6 +420,7 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf) pmadapter->ops.data_complete(pmadapter, pmbuf, ret); goto done; } + if (rx_pkt_type != PKT_TYPE_BAR) { priv->rxpd_rate = prx_pd->rx_rate; priv->rxpd_rate_info = prx_pd->rate_info; @@ -465,6 +466,11 @@ mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf) #endif pmbuf->priority |= prx_pd->priority; + if (pmadapter->enable_net_mon && + (prx_pd->rx_pkt_type == PKT_TYPE_802DOT11)) { + 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 ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID)) { @@ -675,8 +681,10 @@ mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf) MAC2STR(prx_pkt->eth803_hdr.dest_addr)); if (pmadapter->enable_net_mon) { - pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; - goto upload; + if (prx_pd->rx_pkt_type == PKT_TYPE_802DOT11) { + pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR; + goto upload; + } } /* don't do packet forwarding in disconnected state */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_usb.c b/mxm_wifiex/wlan_src/mlan/mlan_usb.c index c5f2c9e..48be972 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_usb.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_usb.c @@ -688,7 +688,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter, } if (pmbuf_aggr && pmbuf_aggr->data_len) { - pmadapter->data_sent = MTRUE; + wlan_update_port_status(pmadapter, pusb_tx_aggr->port, MTRUE); + pmadapter->data_sent = wlan_usb_data_sent(pmadapter); ret = pmadapter->callbacks.moal_write_data_async( pmadapter->pmoal_handle, pmbuf_aggr, pusb_tx_aggr->port); @@ -710,6 +711,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter, wlan_write_data_complete(pmadapter, pmbuf_aggr, ret); break; case MLAN_STATUS_FAILURE: + wlan_update_port_status(pmadapter, pusb_tx_aggr->port, + MFALSE); pmadapter->data_sent = MFALSE; PRINTM(MERROR, "Error: moal_write_data_async failed: 0x%X\n", @@ -719,6 +722,8 @@ static inline t_void wlan_usb_tx_send_aggr(pmlan_adapter pmadapter, wlan_write_data_complete(pmadapter, pmbuf_aggr, ret); break; case MLAN_STATUS_PENDING: + wlan_update_port_status(pmadapter, pusb_tx_aggr->port, + MFALSE); pmadapter->data_sent = MFALSE; break; case MLAN_STATUS_SUCCESS: @@ -964,13 +969,16 @@ t_void wlan_usb_tx_aggr_timeout_func(t_void *function_context) { usb_tx_aggr_params *pusb_tx_aggr = (usb_tx_aggr_params *)function_context; + t_u8 port_index = 0; pmlan_adapter pmadapter = (mlan_adapter *)pusb_tx_aggr->phandle; pmlan_callbacks pcb = &pmadapter->callbacks; ENTER(); pcb->moal_spin_lock(pmadapter->pmoal_handle, pusb_tx_aggr->paggr_lock); pusb_tx_aggr->aggr_hold_timer_is_set = MFALSE; - if (pusb_tx_aggr->pmbuf_aggr && !pmadapter->data_sent && + port_index = wlan_get_port_index(pmadapter, pusb_tx_aggr->port); + if (pusb_tx_aggr->pmbuf_aggr && + wlan_is_port_ready(pmadapter, port_index) && !wlan_is_port_tx_paused(pmadapter, pusb_tx_aggr)) wlan_usb_tx_send_aggr(pmadapter, pusb_tx_aggr); pcb->moal_spin_unlock(pmadapter->pmoal_handle, @@ -1135,6 +1143,98 @@ mlan_status wlan_usb_host_to_card_aggr(pmlan_adapter pmadapter, return ret; } +/** + * @brief This function used to check if any USB port still available + * + * @param pmadapter A pointer to mlan_adapter + * + * @return MTRUE--non of the port is available. + * MFALSE -- still have port available. + */ +inline t_u8 wlan_usb_data_sent(pmlan_adapter pmadapter) +{ + int i; + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { + if (pmadapter->pcard_usb->usb_port_status[i] == MFALSE) + return MFALSE; + } + return MTRUE; +} + +/** + * @brief This function resync the USB tx port + * + * @param pmadapter A pointer to mlan_adapter + * + * @return N/A + */ +void wlan_resync_usb_port(pmlan_adapter pmadapter) +{ + t_u32 active_port = pmadapter->usb_tx_ports[0]; + int i; + /* MC is enabled */ + if (pmadapter->mc_status) { + for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM); + i++) { + if (pmadapter->priv[i]) { + if (((GET_BSS_ROLE(pmadapter->priv[i]) == + MLAN_BSS_ROLE_UAP) && + !pmadapter->priv[i]->uap_bss_started) || + ((GET_BSS_ROLE(pmadapter->priv[i]) == + MLAN_BSS_ROLE_STA) && + !pmadapter->priv[i]->media_connected)) { + PRINTM(MINFO, + "Set deactive interface to default EP\n"); + pmadapter->priv[i]->port = + pmadapter->usb_tx_ports[0]; + ; + pmadapter->priv[i]->port_index = 0; + } + } + } + /** Enable all the ports */ + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) + pmadapter->pcard_usb->usb_port_status[i] = MFALSE; + } else { + /* Get active port from connected interface */ + for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM); + i++) { + if (pmadapter->priv[i]) { + if (((GET_BSS_ROLE(pmadapter->priv[i]) == + MLAN_BSS_ROLE_UAP) && + pmadapter->priv[i]->uap_bss_started) || + ((GET_BSS_ROLE(pmadapter->priv[i]) == + MLAN_BSS_ROLE_STA) && + pmadapter->priv[i]->media_connected)) { + active_port = pmadapter->priv[i]->port; + PRINTM(MEVENT, "active port=%d\n", + active_port); + break; + } + } + } + /** set all the interface to the same port */ + for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM); + i++) { + if (pmadapter->priv[i]) { + pmadapter->priv[i]->port = active_port; + pmadapter->priv[i]->port_index = + wlan_get_port_index(pmadapter, + active_port); + } + } + for (i = 0; i < MAX_USB_TX_PORT_NUM; i++) { + if (active_port == pmadapter->usb_tx_ports[i]) + pmadapter->pcard_usb->usb_port_status[i] = + MFALSE; + else + pmadapter->pcard_usb->usb_port_status[i] = + MTRUE; + } + } + return; +} + /** * @brief This function wakes up the card. * @@ -1214,7 +1314,9 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type, ret = wlan_usb_host_to_card_aggr(pmadapter, pmbuf, tx_param, pusb_tx_aggr); } else { - pmadapter->data_sent = MTRUE; + pmadapter->pcard_usb->usb_port_status[pmpriv->port_index] = + MTRUE; + pmadapter->data_sent = wlan_usb_data_sent(pmadapter); ret = pmadapter->callbacks.moal_write_data_async( pmadapter->pmoal_handle, pmbuf, pmpriv->port); switch (ret) { @@ -1225,9 +1327,13 @@ static mlan_status wlan_usb_host_to_card(pmlan_private pmpriv, t_u8 type, break; case MLAN_STATUS_FAILURE: + pmadapter->pcard_usb + ->usb_port_status[pmpriv->port_index] = MFALSE; pmadapter->data_sent = MFALSE; break; case MLAN_STATUS_PENDING: + pmadapter->pcard_usb + ->usb_port_status[pmpriv->port_index] = MFALSE; pmadapter->data_sent = MFALSE; break; case MLAN_STATUS_SUCCESS: diff --git a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c index 6883401..c8aab0f 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_wmm.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_wmm.c @@ -661,6 +661,18 @@ static raListTbl *wlan_wmm_get_highest_priolist_ptr(pmlan_adapter pmadapter, /* Ignore data pkts from a BSS if tx pause */ goto next_intf; } +#if defined(USB) + if (!wlan_is_port_ready(pmadapter, + priv_tmp->port_index)) { + PRINTM(MINFO, + "get_highest_prio_ptr(): " + "usb port is busy,Ignore pkts from BSS%d\n", + priv_tmp->bss_index); + /* Ignore data pkts from a BSS if usb port is + * busy */ + goto next_intf; + } +#endif pmadapter->callbacks.moal_spin_lock( pmadapter->pmoal_handle, @@ -1945,6 +1957,10 @@ int wlan_wmm_lists_empty(pmlan_adapter pmadapter) } if (priv->tx_pause) continue; +#if defined(USB) + if (!wlan_is_port_ready(pmadapter, priv->port_index)) + continue; +#endif if (util_scalar_read( pmadapter->pmoal_handle, diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index 70e970a..8544bc4 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 "366.p5" +#define MLAN_RELEASE_VERSION "368" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -1747,6 +1747,15 @@ typedef struct { t_u32 time_usec; } wifi_timeval; +#define timeval_to_msec(timeval) \ + (t_u64)((t_u64)(timeval.time_sec) * 1000 + \ + (t_u64)(timeval.time_usec) / 1000) +#define timeval_to_usec(timeval) \ + (t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \ + (t_u64)(timeval.time_usec)) +#define is_zero_timeval(timeval) \ + ((timeval.time_sec == 0) && (timeval.time_usec == 0)) + #define MAX_NUM_RATE 32 #define MAX_RADIO 2 #define MAX_NUM_CHAN 1 @@ -1828,15 +1837,6 @@ typedef struct { t_u32 cca_busy_time; } wifi_channel_stat; -#define timeval_to_msec(timeval) \ - (t_u64)((t_u64)(timeval.time_sec) * 1000 + \ - (t_u64)(timeval.time_usec) / 1000) -#define timeval_to_usec(timeval) \ - (t_u64)((t_u64)(timeval.time_sec) * 1000 * 1000 + \ - (t_u64)(timeval.time_usec)) -#define is_zero_timeval(timeval) \ - ((timeval.time_sec == 0) && (timeval.time_usec == 0)) - /** radio statistics */ typedef struct { /** wifi radio (if multiple radio supported) */ @@ -2322,6 +2322,8 @@ typedef struct _mlan_device { t_u8 indication_gpio; /** Dynamic MIMO-SISO switch for hscfg*/ t_u8 hs_mimo_switch; + /** channel time and mode for DRCS*/ + t_u32 drcs_chantime_mode; #ifdef USB /** Tx CMD endpoint address */ t_u8 tx_cmd_ep; @@ -2332,6 +2334,8 @@ typedef struct _mlan_device { t_u8 rx_data_ep; /** Tx data endpoint address */ t_u8 tx_data_ep; + /** Tx data second endpoint address */ + t_u8 tx_data2_ep; #endif /** passive to active scan */ t_u8 passive_to_active_scan; diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h index d9a2ce7..cf2ef85 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h @@ -1939,6 +1939,11 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END wlan_bgscan_cfg; #endif /* STA_SUPPORT */ +/** The open AP in OWE transmition Mode */ +#define OWE_TRANS_MODE_OPEN 1 +/** The security AP in OWE trsnsition Mode */ +#define OWE_TRANS_MODE_OWE 2 + #ifdef PRAGMA_PACK #pragma pack(pop) #endif @@ -1953,6 +1958,15 @@ typedef struct _BSSDescriptor_t { /** SSID */ mlan_802_11_ssid ssid; + /** Transition MAC address */ + mlan_802_11_mac_addr trans_mac_address; + + /** Transition SSID */ + mlan_802_11_ssid trans_ssid; + + /** OWE Transition mode */ + t_u8 owe_transition_mode; + /** WEP encryption requirement */ t_u32 privacy; diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index b09307d..be6d8ed 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -293,6 +293,8 @@ enum _mlan_ioctl_req_id { #if defined(STA_SUPPORT) MLAN_OID_MISC_PMFCFG = 0x00200022, #endif + MLAN_OID_MISC_MULTI_CHAN_CFG = 0x00200023, + MLAN_OID_MISC_MULTI_CHAN_POLICY = 0x00200024, #ifdef WIFI_DIRECT_SUPPORT MLAN_OID_MISC_WIFI_DIRECT_CONFIG = 0x00200025, #endif @@ -319,6 +321,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_GET_CHAN_REGION_CFG = 0x00200046, MLAN_OID_MISC_CLOUD_KEEP_ALIVE = 0x00200048, MLAN_OID_MISC_OPER_CLASS_CHECK = 0x00200049, + MLAN_OID_MISC_DRCS_CFG = 0x00200050, MLAN_OID_MISC_CWMODE_CTRL = 0x00200051, MLAN_OID_MISC_AGGR_CTRL = 0x00200052, @@ -766,6 +769,11 @@ typedef struct _mlan_ssid_bssid { t_u8 host_mlme; /** assoicate resp frame/ie from firmware */ mlan_ds_misc_assoc_rsp assoc_rsp; + t_u8 owe_transition_mode; + /** Transition SSID */ + mlan_802_11_ssid trans_ssid; + /** Transition BSSID */ + mlan_802_11_mac_addr trans_bssid; } mlan_ssid_bssid, *pmlan_ssid_bssid; /** Data structure of WMM ECW */ @@ -911,6 +919,8 @@ typedef struct _mlan_deauth_param { #define PROTOCOL_WAPI 0x80 /** WPA3 SAE */ #define PROTOCOL_WPA3_SAE 0x100 +/** OWE */ +#define PROTOCOL_OWE 0x200 /** Key_mgmt_psk */ #define KEY_MGMT_NONE 0x04 @@ -2592,6 +2602,7 @@ enum _mlan_auth_mode { MLAN_AUTH_MODE_SHARED = 0x01, MLAN_AUTH_MODE_FT = 0x02, MLAN_AUTH_MODE_SAE = 0x03, + MLAN_AUTH_MODE_OWE = 0x04, MLAN_AUTH_MODE_NETWORKEAP = 0x80, MLAN_AUTH_MODE_AUTO = 0xFF, }; @@ -2604,6 +2615,7 @@ typedef enum { AssocAgentAuth_FastBss_Skip, AssocAgentAuth_Network_EAP, AssocAgentAuth_Wpa3Sae = 6, + AssocAgentAuth_Owe = 7, AssocAgentAuth_Auto, } AssocAgentAuthType_e; @@ -4065,10 +4077,19 @@ typedef struct _mlan_ds_11ax_txop_cmd { } mlan_ds_11ax_txop_cmd, *pmlan_ds_11ax_txop_cmd; /** Type definition of mlan_ds_11ax_htc_cmd for MLAN_OID_11AX_CMD_CFG */ -typedef struct _mlan_ds_11ax_txomi_cmd { +typedef struct MLAN_PACK_START_mlan_ds_11ax_txomi_cmd { /* 11ax spec 9.2.4.6a.2 OM Control 12 bits. Bit 0 to bit 11 */ t_u16 omi; -} mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd; + /* tx option + * 0: send OMI in QoS NULL; 1: send OMI in QoS data; 0xFF: set OMI in + * both + */ + t_u8 tx_option; + /* if OMI is sent in QoS data, specify the number of consecutive data + * packets containing the OMI + */ + t_u8 num_data_pkts; +} MLAN_PACK_END mlan_ds_11ax_txomi_cmd, *pmlan_ds_11ax_txomi_cmd; /** Type definition of mlan_ds_11ax_toltime_cmd for MLAN_OID_11AX_CMD_CFG */ typedef struct _mlan_ds_11ax_toltime_cmd { @@ -4471,12 +4492,13 @@ enum _mlan_func_cmd { MLAN_FUNC_SHUTDOWN, }; -/** Net monitor filter: management frame */ -#define MLAN_NETMON_MANAGEMENT_FRAME MBIT(0) -/** Net monitor filter: control frame */ -#define MLAN_NETMON_CONTROL_FRAME MBIT(1) -/** Net monitor filter: data frame */ -#define MLAN_NETMON_DATA_FRAME MBIT(2) +/* Net monitor filters: */ +/* management frame */ +#define MLAN_NETMON_MANAGEMENT MBIT(0) +/* control frame */ +#define MLAN_NETMON_CONTROL MBIT(1) +/* data frame */ +#define MLAN_NETMON_DATA MBIT(2) typedef struct _mlan_ds_misc_net_monitor { /** Enable/disable network monitor */ @@ -4912,6 +4934,31 @@ typedef struct _mlan_ds_misc_pmfcfg { } mlan_ds_misc_pmfcfg; #endif +typedef MLAN_PACK_START struct _mlan_ds_multi_chan_cfg { + /** Channel Time */ + t_u32 channel_time; + /** Buffer Weight */ + t_u8 buffer_weight; + /** tlv len */ + t_u16 tlv_len; + /** TLV buffer */ + t_u8 tlv_buf[]; +} MLAN_PACK_END mlan_ds_multi_chan_cfg; + +typedef MLAN_PACK_START struct _mlan_ds_drcs_cfg { + /** Channel Index*/ + t_u16 chan_idx; + /** Channel time (in TU) for chan_idx */ + t_u8 chantime; + /** Channel swith time (in TU) for chan_idx */ + t_u8 switchtime; + /** Undoze time (in TU) for chan_idx */ + t_u8 undozetime; + /** Rx traffic control scheme when channel switch*/ + /** only valid for GC/STA interface*/ + t_u8 mode; +} MLAN_PACK_END mlan_ds_drcs_cfg; + #define MAX_SSID_NUM 16 #define MAX_AP_LIST 8 #define RETRY_UNLIMITED_TIME 0xFF @@ -5627,7 +5674,7 @@ struct MLAN_PACK_START mfg_Cmd_HE_TBTx_t { /** AXQ Mu Timer */ t_u16 axq_mu_timer; /** Tx Power */ - t_u16 tx_power; + t_s16 tx_power; } MLAN_PACK_END; typedef struct _mlan_ds_misc_chnrgpwr_cfg { @@ -5684,6 +5731,7 @@ typedef struct _mlan_ds_ch_load { t_s16 noise; t_u16 rx_quality; t_u16 duration; + t_u16 cca_th; } mlan_ds_ch_load; /** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ @@ -5770,6 +5818,13 @@ typedef struct _mlan_ds_misc_cfg { #if defined(STA_SUPPORT) mlan_ds_misc_pmfcfg pmfcfg; #endif + /** Multi-channel config for MLAN_OID_MISC_MULTI_CHAN_CFG */ + mlan_ds_multi_chan_cfg multi_chan_cfg; + /** Multi-channel policy for MLAN_OID_MISC_MULTI_CHAN_POLICY */ + t_u16 multi_chan_policy; + /** channel drcs time slicing config for MLAN_OID_MISC_DRCS_CFG + */ + mlan_ds_drcs_cfg drcs_cfg[2]; #ifdef WIFI_DIRECT_SUPPORT mlan_ds_wifi_direct_config p2p_config; #endif diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c index 3d26746..3c076a1 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c @@ -169,7 +169,8 @@ extern const struct net_device_ops woal_netdev_ops; ********************************************************/ #ifdef UAP_SUPPORT #if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0) -int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg); +int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg, + t_u8 wait_option); #endif #endif @@ -1483,7 +1484,7 @@ fail: */ #endif int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index, @@ -1542,7 +1543,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, */ #endif int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index, @@ -1601,7 +1602,7 @@ int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, #endif int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index @@ -1636,7 +1637,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy, #if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index) @@ -1650,7 +1651,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, #if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index) @@ -3572,9 +3573,10 @@ static t_u16 woal_filter_beacon_ies(moal_private *priv, const t_u8 *ie, int len, "Retrieve 11ax cfg by channel=%d band=%d\n", priv->channel, he_cfg.band); - if (0 == woal_11ax_cfg(priv, - MLAN_ACT_GET, - &he_cfg)) { + if (0 == + woal_11ax_cfg(priv, MLAN_ACT_GET, + &he_cfg, + MOAL_IOCTL_WAIT)) { hecap_ie = (IEEEtypes_HECap_t *)&he_cfg .he_cap.len; @@ -4041,7 +4043,8 @@ int woal_cfg80211_mgmt_frame_ie( if ((beacon_ies && beacon_ies_len && beacon_ies_data->ie_length) || (beacon_ies_data->mgmt_subtype_mask == - MLAN_CUSTOM_IE_DELETE_MASK)) { + MLAN_CUSTOM_IE_DELETE_MASK && + beacon_vendor_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK)) { if (MLAN_STATUS_FAILURE == woal_cfg80211_custom_ie( priv, beacon_ies_data, &beacon_vendor_index, @@ -4501,7 +4504,6 @@ done: } #endif -#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE /* =============== 11AX CAP for uAP @@ -4655,6 +4657,7 @@ static void woal_uap_update_11ax_ie(t_u8 band, mlan_ds_11ax_he_capa *hecap_ie) return; } +#if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE /** * @brief Sets up the CFG802.11 specific HE capability fields * with default * values @@ -4745,7 +4748,71 @@ void woal_cfg80211_setup_he_cap(moal_private *priv, done: LEAVE(); } +#else +/** + * @brief setup uap he_cap based on FW he_cap + * + * @param priv A pointer to moal private structure + * @param wait_option wait_option + * + * @return N/A + */ +void woal_cfg80211_setup_uap_he_cap(moal_private *priv, t_u8 wait_option) +{ + mlan_ds_11ax_he_capa *phe_cap = NULL; + mlan_ds_11ax_he_cfg he_cfg; + t_u8 hw_hecap_len; + mlan_fw_info fw_info; +#ifdef UAP_SUPPORT + int ret = 0; +#endif + woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info); + + // Enable 2G 11AX on UAP + if (fw_info.fw_bands & BAND_GAX) { + memset(&he_cfg, 0, sizeof(he_cfg)); + phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_2g_he_cap; + hw_hecap_len = fw_info.hw_2g_hecap_len; + if (hw_hecap_len) { + woal_uap_update_11ax_ie(BAND_2GHZ, phe_cap); + he_cfg.band = MBIT(0); + moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap, + hw_hecap_len, + sizeof(mlan_ds_11ax_he_capa)); + DBG_HEXDUMP(MCMD_D, "2G HE_CFG ", (t_u8 *)&he_cfg, + sizeof(he_cfg)); +#ifdef UAP_SUPPORT + ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, + wait_option); + if (ret) + PRINTM(MERROR, "Fail to set 2G HE CAP\n"); +#endif + } + } + // Enable 5G 11AX on UAP + if (fw_info.fw_bands & BAND_AAX) { + memset(&he_cfg, 0, sizeof(he_cfg)); + phe_cap = (mlan_ds_11ax_he_capa *)fw_info.hw_he_cap; + hw_hecap_len = fw_info.hw_hecap_len; + if (hw_hecap_len) { + woal_uap_update_11ax_ie(BAND_5GHZ, phe_cap); + he_cfg.band = MBIT(1); + moal_memcpy_ext(priv->phandle, &he_cfg.he_cap, phe_cap, + hw_hecap_len, + sizeof(mlan_ds_11ax_he_capa)); + DBG_HEXDUMP(MCMD_D, "5G HE_CFG ", (t_u8 *)&he_cfg, + sizeof(he_cfg)); +#ifdef UAP_SUPPORT + ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, + wait_option); + if (ret) + PRINTM(MERROR, "Fail to set 5G HE CAP\n"); +#endif + } + } + return; +} #endif /** diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h index 6e7eaf0..d9ca184 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h @@ -128,7 +128,7 @@ int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, int woal_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index, @@ -138,7 +138,7 @@ int woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, const t_u8 *mac_addr, struct key_params *params); int woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index, @@ -213,7 +213,7 @@ int woal_cfg80211_set_channel(struct wiphy *wiphy, #if KERNEL_VERSION(2, 6, 37) < CFG80211_VERSION_CODE int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index, bool ucast, bool mcast); @@ -225,7 +225,7 @@ int woal_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *dev, #if KERNEL_VERSION(2, 6, 30) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index); @@ -234,7 +234,7 @@ int woal_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, #if KERNEL_VERSION(5, 10, 0) <= CFG80211_VERSION_CODE int woal_cfg80211_set_default_beacon_key(struct wiphy *wiphy, struct net_device *netdev, -#if (CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || IMX_ANDROID_13) +#if ((KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE) || IMX_ANDROID_13) int link_id, #endif t_u8 key_index); @@ -514,6 +514,8 @@ mlan_status woal_chandef_create(moal_private *priv, #if KERNEL_VERSION(4, 20, 0) <= CFG80211_VERSION_CODE void woal_cfg80211_setup_he_cap(moal_private *priv, struct ieee80211_supported_band *band); +#else +void woal_cfg80211_setup_uap_he_cap(moal_private *priv, t_u8 wait_option); #endif void woal_cfg80211_free_bands(struct wiphy *wiphy); @@ -542,4 +544,7 @@ void woal_clear_wiphy_dfs_state(struct wiphy *wiphy); void woal_update_channel_dfs_state(t_u8 channel, t_u8 dfs_state); int woal_get_wiphy_chan_dfs_state(struct wiphy *wiphy, mlan_ds_11h_chan_dfs_state *ch_dfs_state); + +mlan_status woal_reset_wifi(moal_handle *handle, t_u8 cnt, char *reason); + #endif /* _MOAL_CFG80211_H_ */ diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c index 667f209..0b885aa 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c @@ -616,6 +616,7 @@ static int woal_cfg80211_subcmd_get_fw_version(struct wiphy *wiphy, char end_c = '\0'; int ret = 0; char fw_ver[32] = {0}; + t_u8 hotfix_ver = 0; union { t_u32 l; t_u8 c[4]; @@ -623,9 +624,15 @@ static int woal_cfg80211_subcmd_get_fw_version(struct wiphy *wiphy, ENTER(); + hotfix_ver = priv->phandle->fw_hotfix_version; ver.l = priv->phandle->fw_release_number; - snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u%c", ver.c[2], ver.c[1], - ver.c[0], ver.c[3], end_c); + if (hotfix_ver) { + snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u.%u%c", ver.c[2], + ver.c[1], ver.c[0], ver.c[3], hotfix_ver, end_c); + } else { + snprintf(fw_ver, sizeof(fw_ver), "%u.%u.%u.p%u%c", ver.c[2], + ver.c[1], ver.c[0], ver.c[3], end_c); + } reply_len = strlen(fw_ver) + 1; /** Allocate skb for cmd reply*/ @@ -2851,7 +2858,7 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy, * 24days. */ if (inter_msec > max_msec) { - PRINTM(MMSG, + PRINTM(MINFO, "Out of range, set inter_msec=%llu to max_msec=%llu\n", inter_msec, max_msec); inter_msec = max_msec; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index 51014bb..f7e6a6c 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -56,6 +56,9 @@ Change log: #include "moal_cfg80211_util.h" #endif #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) +#include +#endif /******************************************************** Local Variables @@ -439,7 +442,7 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf, int ret = 0; mlan_status status = MLAN_STATUS_SUCCESS; int header_len = 0, user_data_len = 0; - int data[3] = {0}; + int data[4] = {0}; ENTER(); req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ax_cmd_cfg)); @@ -459,7 +462,7 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf, PRINTM(MINFO, "data_len=%d,data=%d,%d,%d\n", user_data_len, data[0], data[1], data[2]); - if (user_data_len > 3 || user_data_len == 0) { + if (user_data_len > 4 || user_data_len == 0) { PRINTM(MERROR, "Invalid parameters\n"); ret = -EFAULT; goto done; @@ -496,6 +499,8 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf, case MLAN_11AXCMD_CFG_ID_TX_OMI: cfg->sub_id = MLAN_11AXCMD_TXOMI_SUBID; cfg->param.txomi_cfg.omi = data[1]; + cfg->param.txomi_cfg.tx_option = data[2]; + cfg->param.txomi_cfg.num_data_pkts = data[3]; break; case MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME: cfg->sub_id = MLAN_11AXCMD_OBSS_TOLTIME_SUBID; @@ -3660,6 +3665,53 @@ done: return ret; } +/** + * @brief Get country code + * + * @param priv A pointer to moal_private structure + * @param country A pointer to country string + * + * @return 0--success, otherwise failure + */ +static int woal_get_countrycode(moal_private *priv, t_u8 *country) +{ + int ret = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *pcfg_misc = NULL; + mlan_ds_misc_country_code *country_code = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + /* 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 */ + pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf; + country_code = &pcfg_misc->param.country_code; + pcfg_misc->sub_command = MLAN_OID_MISC_COUNTRY_CODE; + req->req_id = MLAN_IOCTL_MISC_CFG; + req->action = MLAN_ACT_GET; + + /* Send IOCTL request to MLAN */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + moal_memcpy_ext(priv->phandle, country, country_code->country_code, + COUNTRY_CODE_LEN, COUNTRY_CODE_LEN); +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + + LEAVE(); + return ret; +} + /** * @brief Get cfp information * @@ -8247,6 +8299,216 @@ done: return ret; } +/** + * @brief Set/Get channel time and buffer weight + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_multi_chan_config(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfg = NULL; + t_u8 *data_ptr; + int ret = 0; + int user_data_len = 0, header_len = 0; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + data_ptr = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_CFG); + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_CFG); + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + user_data_len = sizeof(mlan_ds_multi_chan_cfg); + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + cfg = (mlan_ds_misc_cfg *)req->pbuf; + cfg->sub_command = MLAN_OID_MISC_MULTI_CHAN_CFG; + req->req_id = MLAN_IOCTL_MISC_CFG; + + if (user_data_len == 0) { + req->action = MLAN_ACT_GET; + } else { + req->action = MLAN_ACT_SET; + moal_memcpy_ext(priv->phandle, &cfg->param.multi_chan_cfg, + data_ptr, sizeof(mlan_ds_multi_chan_cfg), + sizeof(mlan_ds_multi_chan_cfg)); + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + moal_memcpy_ext(priv->phandle, respbuf, + (mlan_ds_multi_chan_cfg *)&cfg->param.multi_chan_cfg, + req->buf_len, respbuflen); + ret = req->buf_len; + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief Set/Get multi_channel policy setting + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_multi_chan_policy(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int ret = 0; + int user_data_len = 0, header_len = 0; + int data = 0; + t_u16 enable; + t_u8 action; + + ENTER(); + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MULTI_CHAN_POLICY); + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, &data, 1, &user_data_len); + } + + if (user_data_len > 1) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto done; + } + + if (user_data_len == 0) { + action = MLAN_ACT_GET; + } else { + action = MLAN_ACT_SET; + enable = (t_u16)data; + } + + if (MLAN_STATUS_SUCCESS != + woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, action)) { + ret = -EFAULT; + goto done; + } + moal_memcpy_ext(priv->phandle, respbuf, &enable, sizeof(t_u16), + respbuflen); + ret = sizeof(t_u16); + +done: + LEAVE(); + return ret; +} + +/** + * @brief Set/Get drcs time slicing parameters + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_drcs_time_slicing_cfg(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfg = NULL; + mlan_ds_drcs_cfg *drcs_cfg = NULL; + t_u8 *data_ptr; + int ret = 0; + int user_data_len = 0, header_len = 0; + int data[8]; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + data_ptr = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_DRCS_CFG); + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DRCS_CFG); + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *)data, 0, sizeof(data)); + parse_arguments(data_ptr, data, ARRAY_SIZE(data), + &user_data_len); + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + cfg = (mlan_ds_misc_cfg *)req->pbuf; + cfg->sub_command = MLAN_OID_MISC_DRCS_CFG; + req->req_id = MLAN_IOCTL_MISC_CFG; + + if (user_data_len == 0) { + req->action = MLAN_ACT_GET; + } else { + req->action = MLAN_ACT_SET; + drcs_cfg = (mlan_ds_drcs_cfg *)&cfg->param.drcs_cfg[0]; + drcs_cfg->chantime = (t_u8)data[0]; + drcs_cfg->switchtime = (t_u8)data[1]; + drcs_cfg->undozetime = (t_u8)data[2]; + drcs_cfg->mode = (t_u8)data[3]; + /* Set the same parameters for two channels*/ + if (user_data_len < (int)ARRAY_SIZE(data)) + drcs_cfg->chan_idx = 0x03; + else { + /* Set the different parameters for two channels*/ + drcs_cfg->chan_idx = 0x1; + drcs_cfg = (mlan_ds_drcs_cfg *)&cfg->param.drcs_cfg[1]; + drcs_cfg->chan_idx = 0x2; + drcs_cfg->chantime = (t_u8)data[4]; + drcs_cfg->switchtime = (t_u8)data[5]; + drcs_cfg->undozetime = (t_u8)data[6]; + drcs_cfg->mode = (t_u8)data[7]; + } + } + + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.drcs_cfg, + req->buf_len, respbuflen); + ret = req->buf_len; + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + #ifdef RX_PACKET_COALESCE /** * @brief Set/Get RX packet coalesceing setting @@ -9286,7 +9548,7 @@ static int woal_priv_auth_type(moal_private *priv, t_u8 *respbuf, if (user_data_len == 1) { PRINTM(MINFO, "SET: auth_type %d\n", auth_type); if (((auth_type < MLAN_AUTH_MODE_OPEN) || - (auth_type > MLAN_AUTH_MODE_SAE)) && + (auth_type > MLAN_AUTH_MODE_OWE)) && (auth_type != MLAN_AUTH_MODE_AUTO)) { ret = -EINVAL; goto done; @@ -10851,27 +11113,20 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf, /* SET operation */ parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), &user_data_len); - if (user_data_len == 1 || user_data_len == 4 || - user_data_len == 5) { - if (data[0] != MFALSE && - data[0] != CHANNEL_SPEC_SNIFFER_MODE) { + if (user_data_len == 1 || user_data_len == 2 || + user_data_len == 4 || user_data_len == 5) { + if (data[0] != MTRUE && data[0] != MFALSE) { PRINTM(MERROR, - "NET_MON: Activity should be enable(=1/2)/disable(=0)\n"); - ret = -EINVAL; - goto done; - } - if ((data[0] == MFALSE && user_data_len != 1) || - (data[0] == CHANNEL_SPEC_SNIFFER_MODE && - (user_data_len != 4 && user_data_len != 5))) { - PRINTM(MERROR, - "NET_MON: Sniffer activity not match with user_data_len\n"); + "NET_MON: Activity should be enable(=1)/" + "disable(=0)\n"); ret = -EINVAL; goto done; } net_mon->enable_net_mon = data[0]; - if (data[0] == CHANNEL_SPEC_SNIFFER_MODE) { + if (data[0] == MTRUE) { int i; - if (user_data_len != 4 && user_data_len != 5) { + if (user_data_len != 2 && user_data_len != 4 && + user_data_len != 5) { PRINTM(MERROR, "NET_MON: Invalid number of args!\n"); ret = -EINVAL; @@ -10879,9 +11134,9 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf, } /* Supported filter flags */ if (!data[1] || - data[1] & ~(MLAN_NETMON_DATA_FRAME | - MLAN_NETMON_MANAGEMENT_FRAME | - MLAN_NETMON_CONTROL_FRAME)) { + data[1] & ~(MLAN_NETMON_DATA | + MLAN_NETMON_MANAGEMENT | + MLAN_NETMON_CONTROL)) { PRINTM(MERROR, "NET_MON: Invalid filter flag\n"); ret = -EINVAL; @@ -10962,8 +11217,7 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf, if (req->action == MLAN_ACT_SET) { if (data[0]) { /** Enable sniffer mode: 1/2 */ if (!handle->mon_if) { - mon_if = woal_prepare_mon_if(priv, "rtap", 0, - data[0]); + mon_if = woal_prepare_mon_if(priv, "rtap", 0); if (!mon_if) { PRINTM(MFATAL, "Prepare mon_if fail.\n"); @@ -10988,6 +11242,7 @@ static int woal_priv_net_monitor_ioctl(moal_private *priv, t_u8 *respbuf, net_mon->channel; handle->mon_if->band_chan_cfg.chan_bandwidth = net_mon->chan_bandwidth; + handle->mon_if->flag = net_mon->filter_flag; } else { /** Disable sniffer mode: 0 */ if (handle->mon_if) { ndev = handle->mon_if->mon_ndev; @@ -11017,69 +11272,6 @@ done: } #endif -#if defined(STA_CFG80211) && defined(UAP_CFG80211) -/** - * @brief Set/Get monitor mode - * - * @param priv A pointer to moal_private structure - * @param respbuf A pointer to response buffer - * @param respbuflen Available length of response buffer - * - * @return 0 --success, otherwise fail - */ -static int woal_priv_set_get_monitor_mode(moal_private *priv, t_u8 *respbuf, - t_u32 respbuflen) -{ - int ret = 0; - int data = 0; - int user_data_len = 0, header_len = 0; - t_u32 action = MLAN_ACT_GET; - - ENTER(); - - header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MONITOR_MODE); - - if ((int)strlen(respbuf) == header_len) { - /* GET operation */ - user_data_len = 0; - action = MLAN_ACT_GET; - } else { - /* SET operation */ - parse_arguments(respbuf + header_len, &data, - sizeof(data) / sizeof(int), &user_data_len); - action = MLAN_ACT_SET; - } - - if (sizeof(int) * user_data_len > sizeof(data)) { - PRINTM(MERROR, "Too many arguments\n"); - ret = -EINVAL; - goto done; - } - - if (action == MLAN_ACT_SET) { - if (data == 1) { - priv->phandle->wiphy->interface_modes |= - MBIT(NL80211_IFTYPE_MONITOR); - } else if (data == 0) { - priv->phandle->wiphy->interface_modes &= - ~(MBIT(NL80211_IFTYPE_MONITOR)); - } else { - PRINTM(MERROR, "Invalid input arguments\n"); - ret = -EINVAL; - goto done; - } - } - data = !!(priv->phandle->wiphy->interface_modes & - MBIT(NL80211_IFTYPE_MONITOR)); - - ret = sprintf(respbuf, "Monitor mode: %d\n", data) + 1; - -done: - LEAVE(); - return ret; -} -#endif - /** * @brief This function get nop list. * @@ -12266,6 +12458,8 @@ static void woal_auto_uap_channel_switch(moal_private *priv, t_u8 channel) moal_handle *ref_handle; t_u8 band_width = CHANNEL_BW_20MHZ; + memset(&chaninfo, 0, sizeof(chaninfo)); + pmpriv = woal_get_active_uap_interface(priv->phandle); if (!pmpriv) { ref_handle = (moal_handle *)priv->phandle->pref_mac; @@ -12430,6 +12624,18 @@ static int woal_priv_do_dfs_cac(moal_private *priv, t_u8 *respbuf, } priv->chan_rpt_pending = MFALSE; } +#ifdef UAP_CFG80211 +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + if (!data[0] && priv->chan_rpt_req.chanNum) { + woal_update_channels_dfs_state( + priv, + priv->chan_rpt_req.chanNum, + priv->chan_rpt_req.bandcfg + .chanWidth, + DFS_USABLE); + } +#endif +#endif memset(&priv->chan_rpt_req, 0, sizeof(mlan_ds_11h_chan_rep_req)); PRINTM(MCMND, "DFS: Stop Radar detect\n"); @@ -13055,6 +13261,7 @@ static int woal_priv_get_ch_load(moal_private *priv, t_u8 *respbuf, misc->param.ch_load.noise = cl_cfg->noise; misc->param.ch_load.rx_quality = cl_cfg->rx_quality; misc->param.ch_load.duration = cl_cfg->duration; + misc->param.ch_load.cca_th = cl_cfg->cca_th; status = woal_request_ioctl(priv, ioctl_req, MOAL_NO_WAIT); if (status != MLAN_STATUS_SUCCESS && status != MLAN_STATUS_PENDING) { ret = -EFAULT; @@ -19422,6 +19629,26 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_region_code(priv, buf, priv_cmd.total_len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DRCS_CFG, + strlen(PRIV_CMD_DRCS_CFG)) == 0) { + /* DRCS configuration for mc_cfg_ext*/ + len = woal_priv_drcs_time_slicing_cfg( + priv, buf, priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_MULTI_CHAN_CFG, + strlen(PRIV_CMD_MULTI_CHAN_CFG)) == 0) { + /* Channel time and buffer weight configuration */ + len = woal_priv_multi_chan_config(priv, buf, + priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_MULTI_CHAN_POLICY, + strlen(PRIV_CMD_MULTI_CHAN_POLICY)) == 0) { + /* Multi-channel Policy enable/disable */ + len = woal_priv_multi_chan_policy(priv, buf, + priv_cmd.total_len); + goto handled; } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_FWMACADDR, strlen(PRIV_CMD_FWMACADDR)) == 0) { /* Set FW MAC address */ @@ -19668,20 +19895,6 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_net_monitor_ioctl(priv, buf, priv_cmd.total_len); goto handled; -#endif -#if defined(STA_CFG80211) && defined(UAP_CFG80211) - } else if (strnicmp(buf + strlen(CMD_NXP), - PRIV_CMD_MONITOR_MODE, - strlen(PRIV_CMD_MONITOR_MODE)) == 0) { - if (IS_STA_CFG80211(cfg80211_wext)) { - /* Set/Get monitor mode */ - len = woal_priv_set_get_monitor_mode( - priv, buf, priv_cmd.total_len); - } else - len = sprintf(buf, - "CFG80211 is not enabled\n") + - 1; - goto handled; #endif } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_TESTING, strlen(PRIV_CMD_DFS_TESTING)) == 0) { @@ -20158,6 +20371,14 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) } #endif len = sprintf(buf, "OK\n") + 1; + } else if (strncmp(buf, "COUNTRYCODE", strlen("COUNTRYCODE")) == 0) { + memset(country_code, 0, sizeof(country_code)); + if (MLAN_STATUS_SUCCESS != + woal_get_countrycode(priv, country_code)) { + ret = -EFAULT; + goto done; + } + len = sprintf(buf, "%s\n", country_code) + 1; } else if (strncmp(buf, "COUNTRY", strlen("COUNTRY")) == 0) { copy_len = strlen(buf) - strlen("COUNTRY") - 1; if (copy_len > COUNTRY_CODE_LEN || copy_len <= 0) { @@ -20180,14 +20401,16 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) } #ifdef STA_CFG80211 if (IS_STA_CFG80211(cfg80211_wext)) { - PRINTM(MIOCTL, "Notify country code=%s\n", - country_code); if (!moal_extflg_isset(priv->phandle, - EXT_DISABLE_REGD_BY_DRIVER)) + EXT_DISABLE_REGD_BY_DRIVER)) { + PRINTM(MIOCTL, "Notify country code=%s\n", + country_code); + regulatory_hint(priv->wdev->wiphy, country_code); - len = sprintf(buf, "OK\n") + 1; - goto done; + len = sprintf(buf, "OK\n") + 1; + goto done; + } } #endif if (MLAN_STATUS_SUCCESS != @@ -20788,9 +21011,11 @@ int woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) ENTER(); +#ifdef CONFIG_COMPAT #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) if (in_compat_syscall()) /* not implemented yet */ return -EOPNOTSUPP; +#endif #endif PRINTM(MINFO, "woal_do_ioctl: ioctl cmd = 0x%x\n", cmd); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index d7bfdb1..424a0c6 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -215,9 +215,6 @@ typedef struct _chan_stats { #endif #define PRIV_CMD_SLEEP_PARAMS "sleepparams" #define PRIV_CMD_NET_MON "netmon" -#if defined(STA_CFG80211) && defined(UAP_CFG80211) -#define PRIV_CMD_MONITOR_MODE "monitormode" -#endif #define PRIV_CMD_DFS_TESTING "dfstesting" #define PRIV_CMD_CLEAR_NOP "clear_nop" #define PRIV_CMD_NOP_LIST "nop_list" @@ -241,6 +238,9 @@ typedef struct _chan_stats { #ifdef RX_PACKET_COALESCE #define PRIV_CMD_RX_COAL_CFG "rxpktcoal_cfg" #endif +#define PRIV_CMD_MULTI_CHAN_CFG "mc_cfg" +#define PRIV_CMD_MULTI_CHAN_POLICY "mc_policy" +#define PRIV_CMD_DRCS_CFG "mc_cfg_ext" #ifdef WIFI_DIRECT_SUPPORT #if defined(UAP_CFG80211) #define PRIV_CMD_CFG_NOA "cfg_noa" diff --git a/mxm_wifiex/wlan_src/mlinux/moal_init.c b/mxm_wifiex/wlan_src/mlinux/moal_init.c index 95d694d..cdc57a3 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_init.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_init.c @@ -42,6 +42,7 @@ static char *mod_para; /** Mfg mode */ int mfg_mode; #endif +int rf_test_mode; #if defined(SDIO) /** SDIO interrupt mode (0: INT_MODE_SDIO, 1: INT_MODE_GPIO) */ @@ -59,6 +60,7 @@ static int country_ie_ignore; static int beacon_hints; #endif #endif +static int cfg80211_drcs; #if defined(STA_CFG80211) || defined(UAP_CFG80211) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) @@ -68,6 +70,8 @@ static int host_mlme = 1; static int roamoffload_in_hs; +static int drcs_chantime_mode; + /** Auto deep sleep */ static int auto_ds; @@ -131,6 +135,23 @@ static int slew_rate = 3; #endif int tx_work = 0; +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) +/** + * RPS to steer packets to specific CPU + * Default value of 0 keeps rps disabled by default + */ +static int rps = 0; + +/** + * rps cpu mask + * rps can be configure to any value between 0x1 - 0xf + * ex: value of 0x3(0011) indicates to use cpu-0 and cpu-1 + */ +#define RPS_CPU_MASK 0xf +#endif +#endif + static int tx_skb_clone = 0; #ifdef IMX_SUPPORT static int pmqos = 1; @@ -647,7 +668,15 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, PRINTM(MMSG, "mfg_mode = %d\n", params->mfg_mode); } #endif - else if (strncmp(line, "drv_mode", strlen("drv_mode")) == 0) { + else if (strncmp(line, "rf_test_mode", + strlen("rf_test_mode")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + params->rf_test_mode = out_data; + PRINTM(MMSG, "rf_test_mode = %d\n", + params->rf_test_mode); + } else if (strncmp(line, "drv_mode", strlen("drv_mode")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; @@ -1179,8 +1208,22 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, PRINTM(MMSG, "tx_work %s\n", moal_extflg_isset(handle, EXT_TX_WORK) ? "on" : "off"); - } else if (strncmp(line, "tx_skb_clone", - strlen("tx_skb_clone")) == 0) { + } +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + else if (strncmp(line, "rps", strlen("rps")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + + handle->params.rps = out_data & RPS_CPU_MASK; + PRINTM(MMSG, "rps set to %x from cfg\n", + handle->params.rps); + } +#endif +#endif + else if (strncmp(line, "tx_skb_clone", + strlen("tx_skb_clone")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; @@ -1220,8 +1263,29 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, "off"); } #endif - else if (strncmp(line, "roamoffload_in_hs", - strlen("roamoffload_in_hs")) == 0) { + else if (strncmp(line, "cfg80211_drcs", + strlen("cfg80211_drcs")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + if (out_data) + moal_extflg_set(handle, EXT_CFG80211_DRCS); + else + moal_extflg_clear(handle, EXT_CFG80211_DRCS); + PRINTM(MMSG, "cfg80211_drcs %s\n", + moal_extflg_isset(handle, EXT_CFG80211_DRCS) ? + "on" : + "off"); + } else if (strncmp(line, "drcs_chantime_mode", + strlen("drcs_chantime_mode")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + params->drcs_chantime_mode = out_data; + PRINTM(MMSG, "drcs_chantime_mode=%d\n", + params->drcs_chantime_mode); + } else if (strncmp(line, "roamoffload_in_hs", + strlen("roamoffload_in_hs")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) goto err; @@ -1417,6 +1481,10 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (params) handle->params.mfg_mode = params->mfg_mode; #endif + handle->params.rf_test_mode = rf_test_mode; + if (params) + handle->params.rf_test_mode = params->rf_test_mode; + handle->params.drv_mode = drv_mode; if (params) handle->params.drv_mode = params->drv_mode; @@ -1625,6 +1693,13 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (tx_work) moal_extflg_set(handle, EXT_TX_WORK); +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + handle->params.rps = rps & RPS_CPU_MASK; + PRINTM(MMSG, "rps set to %x from module param\n", handle->params.rps); +#endif +#endif + if (tx_skb_clone) moal_extflg_set(handle, EXT_TX_SKB_CLONE); if (pmqos) @@ -1645,6 +1720,11 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) moal_extflg_set(handle, EXT_HOST_MLME); #endif #endif + if (cfg80211_drcs) + moal_extflg_set(handle, EXT_CFG80211_DRCS); + handle->params.drcs_chantime_mode = drcs_chantime_mode; + if (params) + handle->params.drcs_chantime_mode = params->drcs_chantime_mode; #if defined(STA_CFG80211) || defined(UAP_CFG80211) if (disable_regd_by_driver) moal_extflg_set(handle, EXT_DISABLE_REGD_BY_DRIVER); @@ -1853,8 +1933,19 @@ void woal_init_from_dev_tree(void) PRINTM(MIOCTL, "tx_work=0x%x\n", data); tx_work = data; } - } else if (!strncmp(prop->name, "tx_skb_clone", - strlen("tx_skb_clone"))) { + } +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + else if (!strncmp(prop->name, "rps", strlen("rps"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + PRINTM(MIOCTL, "rps=0x%x\n", data); + rps = data; + } + } +#endif +#endif + else if (!strncmp(prop->name, "tx_skb_clone", + strlen("tx_skb_clone"))) { if (!of_property_read_u32(dt_node, prop->name, &data)) { PRINTM(MIOCTL, "tx_skb_clone=0x%x\n", data); tx_skb_clone = data; @@ -1878,7 +1969,14 @@ void woal_init_from_dev_tree(void) } } #endif - else if (!strncmp(prop->name, "mac_addr", strlen("mac_addr"))) { + else if (!strncmp(prop->name, "rf_test_mode", + strlen("rf_test_mode"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + PRINTM(MIOCTL, "rf_test_mode=0x%x\n", data); + rf_test_mode = data; + } + } else if (!strncmp(prop->name, "mac_addr", + strlen("mac_addr"))) { if (!of_property_read_string(dt_node, prop->name, &string_data)) { mac_addr = (char *)string_data; @@ -1965,6 +2063,12 @@ void woal_init_from_dev_tree(void) PRINTM(MIOCTL, "max_vir_bss=0x%x\n", data); max_vir_bss = data; } + } else if (!strncmp(prop->name, "cfg80211_drcs", + strlen("cfg80211_drcs"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + PRINTM(MIOCTL, "cfg80211_drcs=0x%x\n", data); + cfg80211_drcs = data; + } } #endif #endif @@ -2069,6 +2173,13 @@ void woal_init_from_dev_tree(void) indrstcfg = data; PRINTM(MIOCTL, "indrstcfg=%d\n", indrstcfg); } + } else if (!strncmp(prop->name, "drcs_chantime_mode", + strlen("drcs_chantime_mode"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + drcs_chantime_mode = data; + PRINTM(MIOCTL, "drcs_chantime_mode=%d\n", + drcs_chantime_mode); + } } else if (!strncmp(prop->name, "fixed_beacon_buffer", strlen("fixed_beacon_buffer"))) { if (!of_property_read_u32(dt_node, prop->name, &data)) { @@ -2383,6 +2494,10 @@ module_param(mfg_mode, int, 0660); MODULE_PARM_DESC(mfg_mode, "0: Download normal firmware; 1: Download MFG firmware"); #endif /* MFG_CMD_SUPPORT */ +module_param(rf_test_mode, int, 0660); +MODULE_PARM_DESC( + rf_test_mode, + "0: Download normal firmware; 1: Download RF_TEST_MODE firmware"); module_param(drv_mode, int, 0660); MODULE_PARM_DESC(drv_mode, "Bit 0: STA; Bit 1: uAP; Bit 2: WIFIDIRECT; Bit 7: ZERO_DFS"); @@ -2466,6 +2581,14 @@ MODULE_PARM_DESC( #endif module_param(tx_work, uint, 0660); MODULE_PARM_DESC(tx_work, "1: Enable tx_work; 0: Disable tx_work"); +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) +module_param(rps, uint, 0660); +MODULE_PARM_DESC( + rps, + "bit0-bit4(0x1 - 0xf): Enables rps on specific cpu ; 0: Disables rps"); +#endif +#endif module_param(tx_skb_clone, uint, 0660); MODULE_PARM_DESC(tx_skb_clone, "1: Enable tx_skb_clone; 0: Disable tx_skb_clone"); @@ -2616,6 +2739,14 @@ module_param(dfs_offload, int, 0); MODULE_PARM_DESC(dfs_offload, "1: enable dfs offload; 0: disable dfs offload."); #endif +module_param(drcs_chantime_mode, int, 0); +MODULE_PARM_DESC( + drcs_chantime_mode, + "0: use default value;Bit31~Bit24:Channel time for channel index0;Bit23~Bit16:mode for channel index0;Bit15~Bit8:Channel time for channel index1;Bit7~Bit0:mode for channel index1; mode:0--PM1,1--Null2Self."); +module_param(cfg80211_drcs, int, 0); +MODULE_PARM_DESC(cfg80211_drcs, + "1: Enable DRCS support; 0: Disable DRCS support"); + module_param(roamoffload_in_hs, int, 0); MODULE_PARM_DESC( roamoffload_in_hs, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index d48a709..f9bcc70 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -267,6 +267,7 @@ t_u8 woal_get_second_channel_offset(moal_private *priv, int chan) t_u8 chan2Offset = SEC_CHAN_NONE; mlan_bss_info bss_info; + memset(&bss_info, 0, sizeof(bss_info)); /* Special Case: 20Mhz-only Channel */ woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); if (bss_info.region_code != COUNTRY_CODE_US && chan == 165) @@ -1029,6 +1030,202 @@ done: } #endif +#ifdef UAP_SUPPORT +/** + * @brief Check current uap/go connection status + * Need handle channel switch if current channel is DFS channel + * + * @param priv A pointer to moal_private structure + * @param wait_option Wait option + * @param new channel new channel + * @return N/A + */ +static void woal_check_uap_dfs_status(moal_private *priv, t_u8 wait_option, + t_u8 new_channel) +{ + chan_band_info channel; + mlan_bss_info bss_info; +#if defined(UAP_SUPPORT) + IEEEtypes_ChanSwitchAnn_t *chan_switch = NULL; + IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL; + custom_ie *pcust_chansw_ie = NULL; + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + t_u8 bw = 0, oper_class = 0; +#endif + + /* Get BSS information */ + if (MLAN_STATUS_SUCCESS != + woal_get_bss_info(priv, wait_option, &bss_info)) + goto done; + if (MLAN_STATUS_SUCCESS != + woal_set_get_ap_channel(priv, MLAN_ACT_GET, wait_option, &channel)) + goto done; + PRINTM(MCMND, "is_11h_active=%d dfs_check_channel=%d\n", + bss_info.is_11h_active, bss_info.dfs_check_channel); + PRINTM(MCMND, "uap current channel=%d new_channel=%d\n", + channel.channel, new_channel); +#if defined(UAP_SUPPORT) + if (new_channel == channel.channel) + goto done; + if (bss_info.is_11h_active && + (bss_info.dfs_check_channel == channel.channel)) { + if (new_channel < MAX_BG_CHANNEL) { + bw = 20; + } else { + switch (channel.bandcfg.chanWidth) { + case CHAN_BW_20MHZ: + bw = 20; + break; + case CHAN_BW_40MHZ: + bw = 40; + break; + case CHAN_BW_80MHZ: + bw = 80; + break; + default: + break; + } + } + woal_priv_get_nonglobal_operclass_by_bw_channel( + priv, bw, new_channel, &oper_class); + PRINTM(MCMND, + "Switch the uap channel from %d to %d, oper_class=%d bw=%d\n", + channel.channel, new_channel, oper_class, bw); + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req) { + misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_CUSTOM_IE; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + ioctl_req->action = MLAN_ACT_SET; + misc->param.cust_ie.type = TLV_TYPE_MGMT_IE; + misc->param.cust_ie.len = + sizeof(custom_ie) - MAX_IE_SIZE; + pcust_chansw_ie = (custom_ie *)&misc->param.cust_ie + .ie_data_list[0]; + pcust_chansw_ie->ie_index = 0xffff; /*Auto index */ + if (!oper_class) { + pcust_chansw_ie->ie_length = + sizeof(IEEEtypes_ChanSwitchAnn_t); + pcust_chansw_ie->mgmt_subtype_mask = + MGMT_MASK_BEACON | + MGMT_MASK_PROBE_RESP; /*Add IE for + BEACON/probe + resp*/ + chan_switch = + (IEEEtypes_ChanSwitchAnn_t *) + pcust_chansw_ie->ie_buffer; + chan_switch->element_id = CHANNEL_SWITCH_ANN; + chan_switch->len = + sizeof(IEEEtypes_ChanSwitchAnn_t) - + sizeof(IEEEtypes_Header_t); + chan_switch->chan_switch_mode = 1; /* STA should + not + transmit + */ + chan_switch->new_channel_num = new_channel; + chan_switch->chan_switch_count = + DEF_CHAN_SWITCH_COUNT; + DBG_HEXDUMP(MCMD_D, "CSA IE", + (t_u8 *)pcust_chansw_ie->ie_buffer, + pcust_chansw_ie->ie_length); + } else { + pcust_chansw_ie->ie_length = + sizeof(IEEEtypes_ExtChanSwitchAnn_t); + pcust_chansw_ie->mgmt_subtype_mask = + MGMT_MASK_BEACON | + MGMT_MASK_PROBE_RESP; /*Add IE for + BEACON/probe + resp*/ + ext_chan_switch = + (IEEEtypes_ExtChanSwitchAnn_t *) + pcust_chansw_ie->ie_buffer; + ext_chan_switch->element_id = + EXTEND_CHANNEL_SWITCH_ANN; + ext_chan_switch->len = + sizeof(IEEEtypes_ExtChanSwitchAnn_t) - + sizeof(IEEEtypes_Header_t); + ext_chan_switch->chan_switch_mode = + 1; /* STA should not transmit */ + ext_chan_switch->new_channel_num = new_channel; + ext_chan_switch->chan_switch_count = + DEF_CHAN_SWITCH_COUNT; + ext_chan_switch->new_oper_class = oper_class; + DBG_HEXDUMP(MCMD_D, "ECSA IE", + (t_u8 *)pcust_chansw_ie->ie_buffer, + pcust_chansw_ie->ie_length); + } + status = woal_request_ioctl(priv, ioctl_req, + wait_option); + if (status != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "Failed to set CSA IE\n"); + goto done; + } + PRINTM(MCMND, "CSA/ECSA ie index=%d\n", + pcust_chansw_ie->ie_index); + priv->phandle->chsw_wait_q_woken = MFALSE; + /* wait for channel switch to complete */ + wait_event_interruptible_timeout( + priv->phandle->chsw_wait_q, + priv->phandle->chsw_wait_q_woken, + (u32)HZ * (DEF_CHAN_SWITCH_COUNT + 2) * 110 / + 1000); + + pcust_chansw_ie->ie_index = 0xffff; + pcust_chansw_ie->mgmt_subtype_mask = + MLAN_CUSTOM_IE_DELETE_MASK; + status = woal_request_ioctl(priv, ioctl_req, + MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "Failed to clear CSA/ECSA IE\n"); + } + } + } +#endif +done: +#if defined(UAP_SUPPORT) + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); +#endif + return; +} + +/** + * @brief Check current multi-channel connections + * + * @param priv A pointer to moal_private structure + * @param wait_option Wait option + * @param new channel new channel + * + * @return N/A + */ +void woal_check_mc_connection(moal_private *priv, t_u8 wait_option, + t_u8 new_channel) +{ + moal_handle *handle = priv->phandle; +#ifdef UAP_SUPPORT + int i; +#endif + t_u16 enable = 0; + + woal_mc_policy_cfg(priv, &enable, wait_option, MLAN_ACT_GET); + if (!enable) + return; +#ifdef UAP_SUPPORT + for (i = 0; i < handle->priv_num; i++) { + if (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_UAP) { + if (handle->priv[i]->bss_started == MTRUE) + woal_check_uap_dfs_status(handle->priv[i], + wait_option, + new_channel); + } + } +#endif + return; +} +#endif + /** * @brief Send bss_start command to MLAN * @@ -1045,6 +1242,9 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option, mlan_ioctl_req *req = NULL; mlan_ds_bss *bss = NULL; mlan_status status; +#ifdef UAP_SUPPORT + mlan_ssid_bssid temp_ssid_bssid; +#endif ENTER(); @@ -1054,6 +1254,18 @@ mlan_status woal_bss_start(moal_private *priv, t_u8 wait_option, if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } +#ifdef UAP_SUPPORT + if (!ssid_bssid) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } + moal_memcpy_ext(priv->phandle, &temp_ssid_bssid, ssid_bssid, + sizeof(mlan_ssid_bssid), sizeof(mlan_ssid_bssid)); + if (MLAN_STATUS_SUCCESS == + woal_find_best_network(priv, wait_option, &temp_ssid_bssid)) + woal_check_mc_connection(priv, wait_option, + temp_ssid_bssid.channel); +#endif /* Allocate an IOCTL request buffer */ req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss)); @@ -2941,6 +3153,7 @@ done: return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) /** * @brief Enable IPv6 Neighbor Solicitation offload * @@ -3016,6 +3229,7 @@ done: LEAVE(); return ret; } +#endif /** * @brief Set auto arp resp @@ -4546,6 +4760,10 @@ int woal_11h_channel_check_ioctl(moal_private *priv, t_u8 wait_option) mlan_ioctl_req *req = NULL; mlan_ds_11h_cfg *ds_11hcfg = NULL; mlan_status status = MLAN_STATUS_SUCCESS; +#ifdef UAP_SUPPORT + chan_band_info chan; + chan_band_info uapchan; +#endif ENTER(); @@ -4566,6 +4784,41 @@ int woal_11h_channel_check_ioctl(moal_private *priv, t_u8 wait_option) } if (woal_is_any_interface_active(priv->phandle)) { +#ifdef UAP_SUPPORT + /* When any other interface is active + * Get rid of CAC timer when drcs is disabled */ + t_u16 enable = 0; + if (priv->phandle->card_info->drcs) + ret = woal_mc_policy_cfg(priv, &enable, wait_option, + MLAN_ACT_GET); + if (!enable) { + LEAVE(); + return ret; + } else { + woal_get_active_intf_channel(priv, &chan); + woal_set_get_ap_channel(priv, MLAN_ACT_GET, + MOAL_IOCTL_WAIT, &uapchan); + if (chan.channel != uapchan.channel) { + if (uapchan.is_dfs_chan) { + PRINTM(MERROR, + "DFS channel is not allowed when another connection exists on different channel\n"); + PRINTM(MERROR, + "Another connection's channel=%d, dfs channel=%d\n", + chan.channel, uapchan.channel); + return -EINVAL; + } else { + // check if we need move first uap0 from + // DFS channel to new non dfs channel + woal_check_mc_connection( + priv, wait_option, + uapchan.channel); + } + } + } +#else + LEAVE(); + return status; +#endif } req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); @@ -7274,6 +7527,50 @@ done: } #endif +/** + * @brief Set/Get configure multi-channel policy + * + * @param priv A pointer to moal_private structure + * @param enable A pointer to enable + * @param wait_option wait_option of ioctl + * @param action action of ioctl + * + * @return MLAN_STATUS_SUCCESS -- success, otherwise fail + */ +mlan_status woal_mc_policy_cfg(moal_private *priv, t_u16 *enable, + t_u8 wait_option, t_u8 action) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *cfg = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + + 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->sub_command = MLAN_OID_MISC_MULTI_CHAN_POLICY; + req->req_id = MLAN_IOCTL_MISC_CFG; + req->action = action; + if (MLAN_ACT_SET == action) + cfg->param.multi_chan_policy = *enable; + status = woal_request_ioctl(priv, req, wait_option); + if (status != MLAN_STATUS_SUCCESS) + goto done; + if (MLAN_ACT_GET == action) + *enable = cfg->param.multi_chan_policy; + +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return status; +} + /** * @brief Set hotspot configuration value to mlan layer * @@ -7354,7 +7651,7 @@ mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option, net_mon->enable_net_mon = enable; if (net_mon->enable_net_mon) { net_mon->filter_flag = filter; - if (net_mon->enable_net_mon == CHANNEL_SPEC_SNIFFER_MODE) { + if (band_chan_cfg && band_chan_cfg->channel) { net_mon->band = band_chan_cfg->band; net_mon->channel = band_chan_cfg->channel; net_mon->chan_bandwidth = band_chan_cfg->chan_bandwidth; @@ -7367,6 +7664,14 @@ mlan_status woal_set_net_monitor(moal_private *priv, t_u8 wait_option, goto done; } + /* update chan band values from response in band_chan_cfg */ + if (net_mon->enable_net_mon) { + if (band_chan_cfg) { + band_chan_cfg->band = net_mon->band; + band_chan_cfg->channel = net_mon->channel; + band_chan_cfg->chan_bandwidth = net_mon->chan_bandwidth; + } + } done: if (status != MLAN_STATUS_PENDING) kfree(req); @@ -7541,15 +7846,16 @@ static int parse_radio_mode_string(const char *s, size_t len, return ret; } +#ifdef SD9177 /* - * @brief PoweLevelToDUT11Bits + * @brief PowerLevelToDUT11Bits * * @param Pwr A user txpwr values of type int * @param PowerLevel A Pointer of uint32 type for converted txpwr vals * @return nothing just exit */ -static void PoweLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel) +static void PowerLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel) { int Z = 0; @@ -7564,6 +7870,7 @@ static void PoweLevelToDUT11Bits(int Pwr, t_u32 *PowerLevel) return; } +#endif /* * @brief Parse mfg cmd tx pwr string @@ -7583,9 +7890,11 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len, char *tmp = NULL; char *pos = NULL; gfp_t flag; +#ifdef SD9177 t_u32 tx_pwr_converted = 0xffffffff; int tx_pwr_local = 0; t_u8 fc_card = MFALSE; +#endif ENTER(); if (!s || !d) { @@ -7611,13 +7920,16 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len, /* tx power value */ pos = strsep(&string, " \t"); +#ifdef SD9177 if (fc_card && pos) { /* for sd9177 we need to convert user power vals including -ve * vals as per labtool */ tx_pwr_local = woal_string_to_number(pos); - PoweLevelToDUT11Bits(tx_pwr_local, &tx_pwr_converted); + PowerLevelToDUT11Bits(tx_pwr_local, &tx_pwr_converted); d->data1 = tx_pwr_converted; - } else if (pos) { + } else +#endif + if (pos) { d->data1 = (t_u32)woal_string_to_number(pos); } /* modulation */ @@ -7630,7 +7942,11 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len, if (pos) d->data3 = (t_u32)woal_string_to_number(pos); +#ifdef SD9177 if (((!fc_card) && (d->data1 > 24)) || (d->data2 > 2)) +#else + if ((d->data1 > 24) || (d->data2 > 2)) +#endif ret = -EINVAL; kfree(tmp); @@ -8184,7 +8500,7 @@ mlan_status woal_process_rf_test_mode_cmd(moal_handle *handle, t_u32 cmd, handle->rf_data->he_tb_tx[2] = misc->param.mfg_he_power.aid; handle->rf_data->he_tb_tx[3] = misc->param.mfg_he_power.axq_mu_timer; - handle->rf_data->he_tb_tx[4] = + handle->rf_data->he_tb_tx_power[0] = misc->param.mfg_he_power.tx_power; break; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.c b/mxm_wifiex/wlan_src/mlinux/moal_main.c index 7dcdef6..4c9945a 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -1284,8 +1284,7 @@ static int woal_netdevice_event(struct notifier_block *nb, unsigned long event, sizeof(priv->ip_addr)); priv->ip_addr_type = IPADDR_TYPE_IPV4; #ifdef STA_CFG80211 - if (!moal_extflg_isset(priv->phandle, EXT_HW_TEST) && - priv->roaming_enabled) { + if (!moal_extflg_isset(priv->phandle, EXT_HW_TEST)) { snprintf(rssi_low, sizeof(rssi_low), "%d", priv->rssi_low); if (MLAN_STATUS_SUCCESS != @@ -2085,6 +2084,7 @@ mlan_status woal_init_sw(moal_handle *handle) device.rx_cmd_ep = cardp->rx_cmd_ep; device.tx_data_ep = cardp->tx_data_ep; device.rx_data_ep = cardp->rx_data_ep; + device.tx_data2_ep = cardp->tx_data2_ep; } #endif #ifdef MFG_CMD_SUPPORT @@ -2104,6 +2104,7 @@ mlan_status woal_init_sw(moal_handle *handle) device.cfg_11d = (t_u32)handle->params.cfg_11d; #endif device.indrstcfg = (t_u32)handle->params.indrstcfg; + device.drcs_chantime_mode = (t_u32)handle->params.drcs_chantime_mode; #ifdef PCIE if (IS_PCIE(handle->card_type)) device.ring_size = handle->params.ring_size; @@ -3433,6 +3434,87 @@ done: return status; } +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) +static ssize_t woal_set_rps_map(struct netdev_rx_queue *queue, const char *buf, + size_t len) +{ + struct rps_map *old_map, *map; + cpumask_var_t mask; + int err, cpu, i; + static DEFINE_MUTEX(local_rps_map_mutex); + + if (!queue || !queue->dev) { + PRINTM(MERROR, "%s: queue=%px or queue->dev is NULL\n", + __func__, queue); + return -EINVAL; + } + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) { + PRINTM(MERROR, "%s: alloc_cpumask_var fail.\n", __func__); + return -ENOMEM; + } + + err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits); + if (err) { + PRINTM(MERROR, "%s: bitmap_parse fail err=%d.\n", __func__, + err); + free_cpumask_var(mask); + return err; + } + + map = kzalloc(max_t(unsigned int, RPS_MAP_SIZE(cpumask_weight(mask)), + L1_CACHE_BYTES), + GFP_KERNEL); + if (!map) { + PRINTM(MERROR, "%s: kzalloc map fail.\n", __func__); + free_cpumask_var(mask); + return -ENOMEM; + } + + i = 0; + for_each_cpu_and (cpu, mask, cpu_online_mask) { + PRINTM(MCMND, "map->cpus[%d]=%d\n", i, cpu); + map->cpus[i++] = cpu; + } + + if (i) { + map->len = i; + PRINTM(MCMND, "map->len=%d\n", map->len); + } else { + kfree(map); + map = NULL; + } + + mutex_lock(&local_rps_map_mutex); + old_map = rcu_dereference_protected( + queue->rps_map, mutex_is_locked(&local_rps_map_mutex)); + rcu_assign_pointer(queue->rps_map, map); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + if (map) + static_branch_inc(&rps_needed); + if (old_map) + static_branch_dec(&rps_needed); +#else + if (map) + static_key_slow_inc(&rps_needed); + if (old_map) + static_key_slow_dec(&rps_needed); + +#endif + mutex_unlock(&local_rps_map_mutex); + + if (old_map) + kfree_rcu(old_map, rcu); + + PRINTM(MMSG, "%s on %s: buf=%s(%u) (%d i=%d)\n", __func__, + queue->dev->name, buf, (t_u32)len, nr_cpumask_bits, i); + free_cpumask_var(mask); + return len; +} +#endif +#endif + /** * @brief Add interfaces DPC * @@ -3446,6 +3528,13 @@ static mlan_status woal_add_card_dpc(moal_handle *handle) int i; char str_buf[MLAN_MAX_VER_STR_LEN]; +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + moal_private *priv_rps = NULL; + t_u8 rps_buf[2]; +#endif +#endif + ENTER(); #if defined(USB) @@ -3563,6 +3652,28 @@ static mlan_status woal_add_card_dpc(moal_handle *handle) #endif #endif +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + if (handle->params.rps) { + priv_rps = woal_get_priv_bss_type(handle, MLAN_BSS_TYPE_STA); + sprintf(rps_buf, "%x", handle->params.rps); + if (priv_rps) { + PRINTM(MCMND, + "num_rx_queues=%u real_num_rx_queues=%u\n", + priv_rps->netdev->num_rx_queues, + priv_rps->netdev->real_num_rx_queues); + for (i = 0; + i < (int)MIN(priv_rps->netdev->num_rx_queues, + priv_rps->netdev->real_num_rx_queues); + i++) { + woal_set_rps_map(&(priv_rps->netdev->_rx[i]), + rps_buf, strlen(rps_buf)); + } + } + } +#endif +#endif + #ifdef MFG_CMD_SUPPORT done: #endif @@ -4534,13 +4645,11 @@ static void woal_mon_if_setup(struct net_device *dev) * @param priv A pointer to moal_private * @param name Virtual interface name * @param name_assign_type Interface name assignment type - * @param sniffer_mode Sniffer mode * * @return A pointer to monitor_iface */ monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, - unsigned char name_assign_type, - int sniffer_mode) + unsigned char name_assign_type) { int ret = 0; moal_handle *handle = priv->phandle; @@ -4549,19 +4658,6 @@ monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, ENTER(); - if (sniffer_mode != CHANNEL_SPEC_SNIFFER_MODE) { - PRINTM(MERROR, "Sniffer mode is not valid\n"); - ret = -EFAULT; - goto fail; - } - if ((sniffer_mode == CHANNEL_SPEC_SNIFFER_MODE) && - woal_is_any_interface_active(handle)) { - PRINTM(MERROR, - "Cannot start channel specified net monitor when Interface Active\n"); - ret = -EFAULT; - goto fail; - } - #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) @@ -4601,7 +4697,6 @@ monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, mon_if->priv = priv; mon_if->mon_ndev = ndev; mon_if->base_ndev = priv->netdev; - mon_if->sniffer_mode = sniffer_mode; mon_if->radiotap_enabled = 1; mon_if->flag = 1; @@ -5799,6 +5894,20 @@ int woal_close(struct net_device *dev) woal_flush_tx_stat_queue(priv); + if ((priv->media_connected == MTRUE) +#ifdef UAP_SUPPORT + || (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) +#endif + ) { + if (MLAN_STATUS_SUCCESS != + woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL, + DEF_DEAUTH_REASON_CODE)) { + PRINTM(MERROR, "%s: woal_disconnect failed \n", + __func__); + } + priv->media_connected = MFALSE; + } + #ifdef STA_SUPPORT #ifdef STA_CFG80211 if (IS_STA_CFG80211(cfg80211_wext)) @@ -6703,7 +6812,7 @@ static void woal_tdls_check_tx(moal_private *priv, struct sk_buff *skb) { struct tdls_peer *peer = NULL; unsigned long flags; - t_u8 ra[MLAN_MAC_ADDR_LENGTH]; + t_u8 ra[MLAN_MAC_ADDR_LENGTH] = {0}; ENTER(); moal_memcpy_ext(priv->phandle, ra, skb->data, MLAN_MAC_ADDR_LENGTH, sizeof(ra)); @@ -7090,29 +7199,6 @@ static int woal_process_tcp_ack(moal_private *priv, mlan_buffer *pmbuf) return ret; } } -#if 0 - /* Might have race conditions with woal_tcp_ack_timer_func - * Causing kernel panic, ageout handler will free tcp_sess - * for now. - */ - else if((*((t_u8 *)tcph + 13) & 0x11) == 0x11){ - /* TCP ACK + Fin */ - spin_lock_irqsave(&priv->tcp_sess_lock, flags); - tcp_session = woal_get_tcp_sess(priv, (__force t_u32)iph->saddr, (__force t_u16)tcph->source, - (__force t_u32)iph->daddr, (__force t_u16)tcph->dest); - if (tcp_session) { - PRINTM(MDATA,"wlan: delete TCP seesion %p\n",tcp_session); - list_del(&tcp_session->link); - if (atomic_read(&tcp_session->is_timer_set)) - woal_cancel_timer(&tcp_session->ack_timer); - skb = (struct sk_buff *)tcp_session->ack_skb; - if (skb) - dev_kfree_skb_any(skb); - kfree(tcp_session); - } - spin_unlock_irqrestore(&priv->tcp_sess_lock, flags); - } -#endif done: LEAVE(); @@ -7194,6 +7280,7 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb) #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) index = skb_get_queue_mapping(skb); + index = MIN(index, 3); #endif if (is_zero_timeval(priv->phandle->tx_time_start)) { @@ -9237,6 +9324,8 @@ static int woal_dump_moal_drv_info(moal_handle *phandle, t_u8 *buf) atomic_read(&cardp->tx_cmd_urb_pending)); ptr += sprintf(ptr, "tx_data_urb_pending = %d\n", atomic_read(&cardp->tx_data_urb_pending)); + ptr += sprintf(ptr, "tx_data2_urb_pending = %d\n", + atomic_read(&cardp->tx_data2_urb_pending)); #ifdef USB_CMD_DATA_EP ptr += sprintf(ptr, "rx_cmd_urb_pending = %d\n", atomic_read(&cardp->rx_cmd_urb_pending)); @@ -9632,7 +9721,7 @@ done: int woal_save_dump_info_to_buf(moal_handle *phandle, t_u8 *src, t_u32 len, t_u32 type) { - mem_dump_header header; + mem_dump_header header = {0}; t_u32 left_len = 0; t_u32 len_to_copy = 0; int total_len = 0; @@ -9734,6 +9823,8 @@ void woal_moal_debug_info(moal_private *priv, moal_handle *handle, u8 flag) atomic_read(&cardp->tx_cmd_urb_pending)); PRINTM(MERROR, "tx_data_urb_pending = %d\n", atomic_read(&cardp->tx_data_urb_pending)); + PRINTM(MERROR, "tx_data2_urb_pending = %d\n", + atomic_read(&cardp->tx_data2_urb_pending)); #ifdef USB_CMD_DATA_EP PRINTM(MERROR, "rx_cmd_urb_pending = %d\n", atomic_read(&cardp->rx_cmd_urb_pending)); @@ -10735,10 +10826,11 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, #define NAPI_BUDGET 64 if (moal_extflg_isset(handle, EXT_NAPI)) { init_dummy_netdev(&handle->napi_dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) netif_napi_add(&handle->napi_dev, &handle->napi_rx, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) woal_netdev_poll_rx); #else + netif_napi_add(&handle->napi_dev, &handle->napi_rx, woal_netdev_poll_rx, NAPI_BUDGET); #endif napi_enable(&handle->napi_rx); @@ -11358,8 +11450,10 @@ static void woal_post_reset(moal_handle *handle) mlan_ioctl_req *req = NULL; mlan_ds_misc_cfg *misc = NULL; int intf_num; -#if defined(STA_CFG80211) || defined(UAP_CFG80211) + char str_buf[MLAN_MAX_VER_STR_LEN]; + mlan_fw_info fw_info; moal_private *priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); +#if defined(STA_CFG80211) || defined(UAP_CFG80211) t_u8 country_code[COUNTRY_CODE_LEN]; #endif #ifdef WIFI_DIRECT_SUPPORT @@ -11396,9 +11490,16 @@ static void woal_post_reset(moal_handle *handle) handle->fw_dump_status = MFALSE; handle->driver_status = MFALSE; handle->hardware_status = HardwareStatusReady; + handle->remain_on_channel = MFALSE; #ifdef STA_CFG80211 handle->scan_timeout = SCAN_TIMEOUT_25S; #endif + if (MLAN_STATUS_SUCCESS != + woal_request_get_fw_info(priv, MOAL_IOCTL_WAIT, &fw_info)) { + PRINTM(MERROR, "%s: get_fw_info failed \n", __func__); + } + woal_get_version(handle, str_buf, sizeof(str_buf) - 1); + PRINTM(MMSG, "wlan: version = %s\n", str_buf); if (!handle->wifi_hal_flag) { PRINTM(MMSG, "wlan: post_reset remove/add interface\n"); handle->surprise_removed = MTRUE; @@ -11434,6 +11535,9 @@ static void woal_post_reset(moal_handle *handle) PRINTM(MMSG, "wlan: post_reset remove/add interface done\n"); goto done; } + + PRINTM(MMSG, "wlan: start interfaces reset\n"); + /* Reset all interfaces */ woal_reset_intf(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), MOAL_IOCTL_WAIT, MTRUE); @@ -11831,8 +11935,11 @@ static void woal_cleanup_module(void) /** cancel dfs monitor on deinit */ if (handle->priv[i] && handle->priv[i]->bss_type == MLAN_BSS_TYPE_DFS) { - woal_11h_cancel_chan_report_ioctl( - handle->priv[i], MOAL_IOCTL_WAIT); + if (woal_11h_cancel_chan_report_ioctl( + handle->priv[i], MOAL_IOCTL_WAIT)) + PRINTM(MERROR, + "%s: woal_11h_cancel_chan_report_ioctl failed \n", + __func__); continue; } #ifdef STA_SUPPORT diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.h b/mxm_wifiex/wlan_src/mlinux/moal_main.h index a5e2b30..a434b36 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -306,6 +306,9 @@ extern int fw_reload; extern int mfg_mode; #endif +/** rf_test mode */ +extern int rf_test_mode; + #if defined(STA_CFG80211) || defined(UAP_CFG80211) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) extern int fw_region; @@ -860,6 +863,9 @@ mlan_status woal_do_dfs_cac(moal_private *priv, /** Custom event : Channel Switch Announcment */ #define CUS_EVT_CHANNEL_SWITCH_ANN "EVENT=CHANNEL_SWITCH_ANN" +/** Custom event : Channel Switch complete */ +#define CUS_EVT_CHAN_SWITCH_COMPLETE "EVENT=CHANNEL_SWITCH_COMPLETE" + /** Custom indiciation message sent to the application layer for WMM changes */ #define WMM_CONFIG_CHANGE_INDICATION "WMM_CONFIG_CHANGE.indication" @@ -1329,7 +1335,8 @@ struct rf_test_mode_data { /* Tx frame config values */ t_u32 tx_frame_data[20]; /* HE TB Tx values */ - t_u32 he_tb_tx[5]; + t_u32 he_tb_tx[4]; + t_s32 he_tb_tx_power[1]; /* BSSID */ t_u8 bssid[ETH_ALEN]; }; @@ -1633,6 +1640,10 @@ struct _moal_private { t_u8 auth_flag; /** flag for auth algorithm */ t_u16 auth_alg; + /** auth tx cnt */ + t_u8 auth_tx_cnt; + /** deauth evt cnt */ + t_u8 deauth_evt_cnt; #endif #ifdef CONFIG_PROC_FS /** Proc entry */ @@ -2046,11 +2057,6 @@ typedef struct _monitor_iface { /* The priv data of interface on which the monitor iface is based */ moal_private *priv; struct wireless_dev wdev; - /** 0 - Disabled - * 1 - Channel Specified sniffer mode - * 2 - In-Channel sniffer mode - */ - int sniffer_mode; int radiotap_enabled; /* The net_device on which the monitor iface is based. */ struct net_device *base_ndev; @@ -2119,6 +2125,7 @@ enum ext_mod_params { #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) EXT_DFS_OFFLOAD, #endif + EXT_CFG80211_DRCS, EXT_DISABLE_REGD_BY_DRIVER, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) EXT_COUNTRY_IE_IGNORE, @@ -2149,6 +2156,7 @@ typedef struct _moal_mod_para { #ifdef MFG_CMD_SUPPORT int mfg_mode; #endif /* MFG_CMD_SUPPORT */ + int rf_test_mode; char *hw_name; int drv_mode; #ifdef DEBUG_LEVEL1 @@ -2224,10 +2232,17 @@ typedef struct _moal_mod_para { int gtk_rekey_offload; t_u16 multi_dtim; t_u16 inact_tmo; + int drcs_chantime_mode; char *reg_alpha2; int dfs53cfg; t_u8 mcs32; +#if defined(CONFIG_RPS) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + /* rps module param */ + int rps; +#endif +#endif int keep_previous_scan; } moal_mod_para; @@ -3827,6 +3842,12 @@ void woal_remove_mcast_node(moal_private *priv, t_u8 *mcast_addr); t_u8 woal_find_mcast_node_tx(moal_private *priv, struct sk_buff *skb); mlan_status woal_request_country_power_table(moal_private *priv, char *region); +mlan_status woal_mc_policy_cfg(moal_private *priv, t_u16 *enable, + t_u8 wait_option, t_u8 action); +#ifdef UAP_SUPPORT +void woal_check_mc_connection(moal_private *priv, t_u8 wait_option, + t_u8 new_channel); +#endif #ifdef RX_PACKET_COALESCE mlan_status woal_rx_pkt_coalesce_cfg(moal_private *priv, t_u16 *enable, t_u8 wait_option, t_u8 action); @@ -3877,8 +3898,7 @@ mlan_status woal_init_aggr_ctrl(moal_handle *handle, t_u8 wait_option); #if defined(STA_CFG80211) && defined(UAP_CFG80211) monitor_iface *woal_prepare_mon_if(moal_private *priv, const char *name, - unsigned char name_assign_type, - int sniffer_mode); + unsigned char name_assign_type); #endif #if defined(STA_CFG80211) || defined(UAP_CFG80211) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_pcie.c b/mxm_wifiex/wlan_src/mlinux/moal_pcie.c index c0bfbc9..97664d4 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_pcie.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_pcie.c @@ -1285,7 +1285,7 @@ static mlan_status woal_pcie_init(pcie_service_card *card) goto err_iomap2; } - PRINTM(MINFO, + PRINTM(MMSG, "PCI memory map Virt0: %p PCI memory map Virt2: " "%p\n", card->pci_mmap, card->pci_mmap1); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_priv.c b/mxm_wifiex/wlan_src/mlinux/moal_priv.c index 1afc77e..fdab5cd 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_priv.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_priv.c @@ -691,7 +691,7 @@ done: */ static int woal_11n_tx_cfg(moal_private *priv, struct iwreq *wrq) { - int data[2], copy_len; + int data[2] = {0}, copy_len; mlan_ioctl_req *req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; int ret = 0; @@ -794,7 +794,7 @@ done: */ static int woal_11n_prio_tbl(moal_private *priv, struct iwreq *wrq) { - int data[MAX_NUM_TID * 2], i, j, copy_len; + int data[MAX_NUM_TID * 2] = {0}, i, j, copy_len; mlan_ioctl_req *req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; int ret = 0; @@ -968,7 +968,7 @@ error: */ static int woal_addba_para_updt(moal_private *priv, struct iwreq *wrq) { - int data[5], ret = 0, copy_len; + int data[5] = {0}, ret = 0, copy_len; mlan_ioctl_req *req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; int data_length = wrq->u.data.length; @@ -1848,10 +1848,9 @@ static int woal_net_monitor_ioctl(moal_private *priv, struct iwreq *wrq) goto done; } /* Supported filter flags */ - if (!data[1] || - data[1] & ~(MLAN_NETMON_DATA_FRAME | - MLAN_NETMON_MANAGEMENT_FRAME | - MLAN_NETMON_CONTROL_FRAME)) { + if (!data[1] || data[1] & ~(MLAN_NETMON_DATA | + MLAN_NETMON_MANAGEMENT | + MLAN_NETMON_CONTROL)) { PRINTM(MERROR, "NET_MON: Invalid filter flag\n"); ret = -EINVAL; @@ -6433,7 +6432,7 @@ done: */ static int woal_ind_rst_ioctl(moal_private *priv, struct iwreq *wrq) { - int data[2], data_length = wrq->u.data.length, copy_len; + int data[2] = {0}, data_length = wrq->u.data.length, copy_len; int ret = 0; mlan_ds_misc_cfg *misc = NULL; mlan_ioctl_req *req = NULL; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_proc.c b/mxm_wifiex/wlan_src/mlinux/moal_proc.c index 4d082e1..080fac1 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_proc.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_proc.c @@ -409,6 +409,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func, { int ret = MLAN_STATUS_SUCCESS; char *string = NULL; + char *tmp; char *pos = NULL; gfp_t flag; @@ -420,6 +421,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func, moal_memcpy_ext(NULL, string, buffer + strlen("sdcmd52rw="), len - strlen("sdcmd52rw="), CMD52_STR_LEN - 1); + tmp = string; string = strstrip(string); *func = -1; @@ -440,7 +442,7 @@ static int parse_cmd52_string(const char *buffer, size_t len, int *func, pos = strsep(&string, " \t"); if (pos) *val = woal_string_to_number(pos); - kfree(string); + kfree(tmp); LEAVE(); return ret; } @@ -785,7 +787,8 @@ static int woal_config_read(struct seq_file *sfp, void *data) seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[1]); seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[2]); seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[3]); - seq_printf(sfp, " %u", handle->rf_data->he_tb_tx[4]); + seq_printf(sfp, " %d", + handle->rf_data->he_tb_tx_power[0]); } seq_printf(sfp, "\n"); } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sdio.h b/mxm_wifiex/wlan_src/mlinux/moal_sdio.h index 87c760f..139a45e 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sdio.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_sdio.h @@ -157,6 +157,9 @@ Change log: #define SDUART9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sduart_nw61x_v1.bin" #define SDSD9177_DEFAULT_COMBO_V1_FW_NAME "nxp/sdsd_nw61x_v1.bin" #define SD9177_DEFAULT_WLAN_V1_FW_NAME "nxp/sd_w61x_v1.bin" +#define SDUART9177_DEFAULT_RFTM_COMBO_V1_FW_NAME "nxp/sduart_nw61x_rftm_v1.bin" +#define SDSD9177_DEFAULT_RFTM_COMBO_V1_FW_NAME "nxp/sdsd_nw61x_rftm_v1.bin" +#define SD9177_DEFAULT_RFTM_WLAN_V1_FW_NAME "nxp/sd_w61x_rftm_v1.bin" #endif /* SD9177 */ /******************************************************** diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c b/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c index 373904a..28b1267 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c @@ -1564,15 +1564,32 @@ static mlan_status woal_sdiommc_get_fw_name(moal_handle *handle) break; case SD9177_A1: if (magic == CHIP_MAGIC_VALUE) { - if (strap == CARD_TYPE_SD9177_UART) - strcpy(handle->card_info->fw_name, - SDUART9177_DEFAULT_COMBO_V1_FW_NAME); - else - strcpy(handle->card_info->fw_name, - SDSD9177_DEFAULT_COMBO_V1_FW_NAME); + if (strap == CARD_TYPE_SD9177_UART) { + if (handle->params.rf_test_mode) + strcpy(handle->card_info + ->fw_name, + SDUART9177_DEFAULT_RFTM_COMBO_V1_FW_NAME); + else + strcpy(handle->card_info + ->fw_name, + SDUART9177_DEFAULT_COMBO_V1_FW_NAME); + } else { + if (handle->params.rf_test_mode) + strcpy(handle->card_info + ->fw_name, + SDSD9177_DEFAULT_RFTM_COMBO_V1_FW_NAME); + else + strcpy(handle->card_info + ->fw_name, + SDSD9177_DEFAULT_COMBO_V1_FW_NAME); + } } - strcpy(handle->card_info->fw_name_wlan, - SD9177_DEFAULT_WLAN_V1_FW_NAME); + if (handle->params.rf_test_mode) + strcpy(handle->card_info->fw_name, + SD9177_DEFAULT_RFTM_WLAN_V1_FW_NAME); + else + strcpy(handle->card_info->fw_name_wlan, + SD9177_DEFAULT_WLAN_V1_FW_NAME); break; default: break; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/mxm_wifiex/wlan_src/mlinux/moal_shim.c index afc8e93..aef5e73 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -1953,12 +1953,16 @@ mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf) skb_put(skb, pmbuf->data_len); } ethh = (struct ethhdr *)(skb->data); - if (ntohs(ethh->h_proto) == ETH_P_PAE) + if (ntohs(ethh->h_proto) == ETH_P_PAE) { PRINTM(MEVENT, "wlan: %s Rx EAPOL pkt from " MACSTR "\n", priv->netdev->name, MAC2STR(ethh->h_source)); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + priv->deauth_evt_cnt = 0; +#endif + } if (!netdev) netdev = priv->netdev; skb->dev = netdev; @@ -2810,6 +2814,9 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #ifdef STA_WEXT if (IS_STA_WEXT(cfg80211_wext)) woal_send_iwevcustom_event(priv, CUS_EVT_PORT_RELEASE); +#endif +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) + priv->deauth_evt_cnt = 0; #endif woal_broadcast_event(priv, CUS_EVT_PORT_RELEASE, strlen(CUS_EVT_PORT_RELEASE)); @@ -3293,7 +3300,9 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) wake_up_interruptible(&priv->phandle->chsw_wait_q); } #endif - + snprintf(event_buf, sizeof(event_buf) - 1, "%s %d", + CUS_EVT_CHAN_SWITCH_COMPLETE, pchan_info->channel); + woal_broadcast_event(priv, event_buf, strlen(event_buf)); if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) { PRINTM(MMSG, "CSA/ECSA: Switch to new channel %d complete!\n", @@ -3757,6 +3766,7 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) ((struct ieee80211_mgmt *) pkt) ->frame_control)) { + priv->auth_tx_cnt = 0; PRINTM(MEVENT, "HostMlme %s: Received auth frame type = 0x%x\n", priv->netdev->name, @@ -3801,6 +3811,27 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) "HostMlme: Drop deauth/disassociate, current_bss = null\n"); break; } + + if (ieee80211_is_deauth( + ((struct ieee80211_mgmt + *)pkt) + ->frame_control)) { + /* subtype 12 deauth + * packet */ + priv->deauth_evt_cnt++; +#define MAX_DEAUTH_COUNTER 5 + if (priv->deauth_evt_cnt >= + MAX_DEAUTH_COUNTER) { + if (woal_reset_wifi( + priv->phandle, + priv->deauth_evt_cnt, + "EAPOL timeout") == + MLAN_STATUS_SUCCESS) { + priv->deauth_evt_cnt = + 0; + } + } + } priv->cfg_disconnect = MTRUE; woal_mgmt_frame_register( priv, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index f13f641..95acf12 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -606,7 +606,12 @@ static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy, ret = 0; goto done; } - + if (woal_is_any_interface_active(handle)) { + PRINTM(MERROR, + "Cannot change monitor channel for an active" + " interface\n"); + goto done; + } memset(&band_chan_cfg, 0x00, sizeof(band_chan_cfg)); /* Set channel */ band_chan_cfg.channel = ieee80211_frequency_to_channel( @@ -637,8 +642,8 @@ static int woal_cfg80211_set_monitor_channel(struct wiphy *wiphy, band_chan_cfg.chan_bandwidth = bandwidth; if (MLAN_STATUS_SUCCESS != - woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, - CHANNEL_SPEC_SNIFFER_MODE, 0x7, + woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MTRUE, + handle->mon_if->flag, &band_chan_cfg)) { PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__); @@ -1468,6 +1473,35 @@ static int woal_cfg80211_set_auth(moal_private *priv, int encrypt_mode, return ret; } +/** + * @brief Reset the wifi + * + * @param handle A pointer to moal_handle structure + * @param cnt wifi reset count + * @param reason wifi reset reason + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING + */ +mlan_status woal_reset_wifi(moal_handle *handle, t_u8 cnt, char *reason) +{ + static wifi_timeval reset_time; + wifi_timeval ts; + t_u64 diff; + +#define MAX_WIFI_RESET_INTERVAL 15 * 60 * 1000000 // 15 minute + woal_get_monotonic_time(&ts); + diff = (t_u64)(timeval_to_usec(ts) - timeval_to_usec(reset_time)); + PRINTM(MERROR, "WiFi Reset diff %lld\n", diff); + if (reset_time.time_sec == 0 || diff >= MAX_WIFI_RESET_INTERVAL) { + reset_time = ts; + PRINTM(MERROR, "WiFi Reset due to %s cnt %d\n", reason, cnt); + /* Do wifi independent reset */ + woal_process_hang(handle); + return MLAN_STATUS_SUCCESS; + } + return MLAN_STATUS_PENDING; +} + /** * @brief Informs the CFG802.11 subsystem of a new BSS connection. * @@ -1952,6 +1986,10 @@ static void woal_save_assoc_params(moal_private *priv, sizeof(priv->conn_ssid)); priv->conn_ssid_len = ssid_bssid->ssid.ssid_len; } + if (priv->sinfo) + memset(priv->sinfo, 0, sizeof(struct station_info)); + else + priv->sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); LEAVE(); } @@ -2423,6 +2461,15 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, case MLAN_STATUS_PENDING: atomic_inc(&priv->phandle->tx_pending); queue_work(priv->phandle->workqueue, &priv->phandle->main_work); +#define MAX_AUTH_COUNTER 5 + priv->auth_tx_cnt++; + if (priv->auth_tx_cnt >= MAX_AUTH_COUNTER) { + if (woal_reset_wifi(priv->phandle, priv->auth_tx_cnt, + "auth timeout") == + MLAN_STATUS_SUCCESS) { + priv->auth_tx_cnt = 0; + } + } break; case MLAN_STATUS_SUCCESS: woal_free_mlan_buffer(priv->phandle, pmbuf); @@ -4323,6 +4370,9 @@ static t_u8 woal_is_uap_scan_result_expired(moal_private *priv) mlan_scan_resp scan_resp; wifi_timeval t; ENTER(); + + memset(&scan_resp, 0, sizeof(scan_resp)); + if (MLAN_STATUS_SUCCESS != woal_get_scan_table(priv, MOAL_IOCTL_WAIT, &scan_resp)) { LEAVE(); @@ -4355,6 +4405,7 @@ t_u8 wlan_check_scan_table_ageout(moal_private *priv) mlan_scan_resp scan_resp; wifi_timeval t; ENTER(); + memset(&scan_resp, 0, sizeof(scan_resp)); if (MLAN_STATUS_SUCCESS != woal_get_scan_table(priv, MOAL_IOCTL_WAIT, &scan_resp)) { LEAVE(); @@ -5230,6 +5281,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (bss_info.mdid == ssid_bssid->ft_md && bss_info.ft_cap == ssid_bssid->ft_cap) { ret = woal_start_ft_roaming(priv, ssid_bssid); + kfree(ssid_bssid); LEAVE(); return 0; } @@ -5243,6 +5295,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (!assoc_rsp) { PRINTM(MERROR, "Failed to allocate memory for assoc_rsp\n"); ret = -ENOMEM; + kfree(ssid_bssid); LEAVE(); return ret; } @@ -5459,11 +5512,8 @@ static int woal_cfg80211_deauthenticate(struct wiphy *wiphy, struct cfg80211_deauth_request *req) { int ret = 0; -#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0) - moal_private *pmpriv = (moal_private *)woal_get_netdev_priv(dev); -#endif -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) if (priv->host_mlme) { priv->host_mlme = MFALSE; priv->auth_flag = 0; @@ -5476,10 +5526,12 @@ static int woal_cfg80211_deauthenticate(struct wiphy *wiphy, ret = woal_cfg80211_disconnect(wiphy, dev, req->reason_code); #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0) - if (pmpriv->wdev->iftype == NL80211_IFTYPE_STATION || - pmpriv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) - cfg80211_disconnected(pmpriv->netdev, 0, NULL, 0, GFP_KERNEL); + if (priv->wdev->iftype == NL80211_IFTYPE_STATION || + priv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) + cfg80211_disconnected(priv->netdev, 0, NULL, 0, GFP_KERNEL); #endif + if (priv->media_connected) + woal_send_disconnect_to_system(priv, DEF_DEAUTH_REASON_CODE); return ret; } @@ -5501,11 +5553,8 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy, struct cfg80211_disassoc_request *req) { int ret = 0; -#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0) - moal_private *pmpriv = (moal_private *)woal_get_netdev_priv(dev); -#endif -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) if (priv->host_mlme) { priv->host_mlme = MFALSE; priv->auth_flag = 0; @@ -5518,10 +5567,13 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy, ret = woal_cfg80211_disconnect(wiphy, dev, req->reason_code); #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 11, 0) - if (pmpriv->wdev->iftype == NL80211_IFTYPE_STATION || - pmpriv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) - cfg80211_disconnected(pmpriv->netdev, 0, NULL, 0, GFP_KERNEL); + if (priv->wdev->iftype == NL80211_IFTYPE_STATION || + priv->wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) + cfg80211_disconnected(priv->netdev, 0, NULL, 0, GFP_KERNEL); #endif + if (priv->media_connected) + woal_send_disconnect_to_system(priv, DEF_DEAUTH_REASON_CODE); + return ret; } #endif @@ -9460,10 +9512,11 @@ static int woal_cfg80211_probe_client(struct wiphy *wiphy, void woal_host_mlme_disconnect(moal_private *priv, u16 reason_code, u8 *sa) { t_u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - t_u8 frame_buf[26]; + t_u8 frame_buf[100]; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame_buf; ENTER(); + memset(frame_buf, 0, sizeof(frame_buf)); mgmt->frame_control = (__force __le16)IEEE80211_STYPE_DEAUTH; mgmt->duration = 0; mgmt->seq_ctrl = 0; @@ -9629,6 +9682,9 @@ static mlan_status woal_cfg80211_init_wiphy(moal_private *priv, t_u32 hw_dev_cap; #ifdef UAP_SUPPORT pmlan_uap_bss_param sys_cfg = NULL; +#endif +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) + t_u16 enable = 0; #endif int mcs_supp = 0; @@ -9793,6 +9849,17 @@ static mlan_status woal_cfg80211_init_wiphy(moal_private *priv, if (frag_thr < MLAN_RTS_MIN_VALUE || frag_thr > MLAN_RTS_MAX_VALUE) frag_thr = MLAN_FRAG_RTS_DISABLED; wiphy->frag_threshold = (t_u32)frag_thr; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) + /* Enable multi-channel by default if multi-channel is supported */ + if (cfg80211_iface_comb_ap_sta.num_different_channels > 1) { + if (priv->phandle->card_info->drcs && + moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS)) { + enable = 1; + ret = woal_mc_policy_cfg(priv, &enable, wait_option, + MLAN_ACT_SET); + } + } +#endif done: LEAVE(); @@ -9968,6 +10035,14 @@ mlan_status woal_register_cfg80211(moal_private *priv) #endif #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) + if ((moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS) && + priv->phandle->card_info->drcs) || + IS_CARD9098(priv->phandle->card_type)) { + cfg80211_iface_comb_ap_sta.num_different_channels = 2; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) + cfg80211_iface_comb_ap_sta.radar_detect_widths = 0; +#endif + } /* Initialize interface combinations */ wiphy->iface_combinations = &cfg80211_iface_comb_ap_sta; wiphy->n_iface_combinations = 1; @@ -10178,8 +10253,6 @@ mlan_status woal_register_cfg80211(moal_private *priv) goto err_wiphy; } - wiphy->interface_modes &= ~(MBIT(NL80211_IFTYPE_MONITOR)); - #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) if (fw_info.force_reg) { PRINTM(MCMND, "FW region_code=%d force_reg=%d\n", diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.c b/mxm_wifiex/wlan_src/mlinux/moal_uap.c index 6075bdc..8a033ba 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.c @@ -35,6 +35,9 @@ Change log: #if defined(STA_CFG80211) && defined(UAP_CFG80211) #include "moal_cfg80211.h" #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) +#include +#endif /******************************************************** Local Variables @@ -3690,10 +3693,12 @@ done: * @param priv A pointer to moal_private structure * @param action MLAN_ACT_SET or MLAN_ACT_GET * @param he_cfg a pointer to mlan_ds_11ax_he_cfg + * @param wait_option wait_option * * @return 0--success, otherwise failure */ -int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg) +int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg, + t_u8 wait_option) { int ret = 0; mlan_status status = MLAN_STATUS_SUCCESS; @@ -3711,14 +3716,12 @@ int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg) moal_memcpy_ext(priv->phandle, &cfg_11ax->param.he_cfg, he_cfg, sizeof(mlan_ds_11ax_he_cfg), sizeof(mlan_ds_11ax_he_cfg)); - status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); - if (status != MLAN_STATUS_SUCCESS) { - ret = -EFAULT; - goto done; + status = woal_request_ioctl(priv, req, wait_option); + if (status == MLAN_STATUS_SUCCESS) { + moal_memcpy_ext(priv->phandle, he_cfg, &cfg_11ax->param.he_cfg, + sizeof(mlan_ds_11ax_he_cfg), + sizeof(mlan_ds_11ax_he_cfg)); } - moal_memcpy_ext(priv->phandle, he_cfg, &cfg_11ax->param.he_cfg, - sizeof(mlan_ds_11ax_he_cfg), - sizeof(mlan_ds_11ax_he_cfg)); done: if (status != MLAN_STATUS_PENDING) kfree(req); @@ -3762,7 +3765,7 @@ int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band, ret = -EFAULT; goto done; } - if (woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg)) { + if (woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg, MOAL_IOCTL_WAIT)) { PRINTM(MERROR, "Fail to get 11ax cfg!\n"); ret = -EFAULT; goto done; @@ -3792,7 +3795,7 @@ int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band, } } DBG_HEXDUMP(MCMD_D, "HE_CFG ", (t_u8 *)&he_cfg, sizeof(he_cfg)); - ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg); + ret = woal_11ax_cfg(priv, MLAN_ACT_SET, &he_cfg, MOAL_IOCTL_WAIT); done: LEAVE(); return ret; @@ -4482,9 +4485,11 @@ int woal_uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) int ret = 0; ENTER(); +#ifdef CONFIG_COMPAT #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) if (in_compat_syscall()) /* not implemented yet */ return -EOPNOTSUPP; +#endif #endif switch (cmd) { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap.h b/mxm_wifiex/wlan_src/mlinux/moal_uap.h index 06415f4..8f5b699 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap.h @@ -592,7 +592,8 @@ int woal_uap_set_ap_cfg(moal_private *priv, t_u8 *data, int len); 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); +int woal_11ax_cfg(moal_private *priv, t_u8 action, mlan_ds_11ax_he_cfg *he_cfg, + t_u8 wait_option); int woal_uap_set_11ax_status(moal_private *priv, t_u8 action, t_u8 band, IEEEtypes_HECap_t *hecap_ie); int woal_set_uap_ht_tx_cfg(moal_private *priv, Band_Config_t bandcfg, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c index 90841a2..c7fac4a 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c @@ -581,7 +581,7 @@ static t_u8 woal_check_11ax_capability(moal_private *priv, t_u8 band, he_cfg.band = MBIT(1); else if (band == BAND_2GHZ) he_cfg.band = MBIT(0); - if (0 == woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg)) { + if (0 == woal_11ax_cfg(priv, MLAN_ACT_GET, &he_cfg, MOAL_IOCTL_WAIT)) { if (he_cfg.he_cap.len && (he_cfg.he_cap.ext_id == HE_CAPABILITY)) { if (memcmp(he_cfg.he_cap.he_txrx_mcs_support, @@ -1003,6 +1003,7 @@ static int woal_cfg80211_beacon_config(moal_private *priv, #endif if (priv->channel) { + woal_check_mc_connection(priv, MOAL_IOCTL_WAIT, priv->channel); memset(sys_config->rates, 0, sizeof(sys_config->rates)); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) @@ -1513,8 +1514,7 @@ static int woal_cfg80211_add_mon_if(struct wiphy *wiphy, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) name_assign_type_tmp = name_assign_type; #endif - mon_if = woal_prepare_mon_if(priv, name, name_assign_type_tmp, - CHANNEL_SPEC_SNIFFER_MODE); + mon_if = woal_prepare_mon_if(priv, name, name_assign_type_tmp); if (!mon_if) { PRINTM(MFATAL, "Prepare mon_if fail.\n"); goto fail; @@ -1536,24 +1536,44 @@ static int woal_cfg80211_add_mon_if(struct wiphy *wiphy, mon_if->wdev.wiphy = wiphy; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) - /* Set default band channel config */ - mon_if->band_chan_cfg.band = BAND_B | BAND_G; - mon_if->band_chan_cfg.band |= BAND_GN; - mon_if->band_chan_cfg.channel = 1; - mon_if->band_chan_cfg.chan_bandwidth = CHANNEL_BW_20MHZ; memset(&chan_info, 0x00, sizeof(chan_info)); - chan_info.channel = 1; - chan_info.is_11n_enabled = MTRUE; - if (MLAN_STATUS_FAILURE == - woal_chandef_create(priv, &mon_if->chandef, &chan_info)) { + mon_if->band_chan_cfg.channel = 0; + if (!woal_is_any_interface_active(handle)) { + /* Set default band channel config */ + mon_if->band_chan_cfg.band = BAND_B | BAND_G; + mon_if->band_chan_cfg.band |= BAND_GN; + mon_if->band_chan_cfg.channel = 1; + mon_if->band_chan_cfg.chan_bandwidth = CHANNEL_BW_20MHZ; + memset(&chan_info, 0x00, sizeof(chan_info)); + chan_info.channel = 1; + chan_info.is_11n_enabled = MTRUE; + } + mon_if->flag = 0x7; + if (MLAN_STATUS_SUCCESS != + woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MTRUE, mon_if->flag, + &mon_if->band_chan_cfg)) { + PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__); ret = -EFAULT; goto fail; } - if (MLAN_STATUS_SUCCESS != - woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, - CHANNEL_SPEC_SNIFFER_MODE, 0x7, - &mon_if->band_chan_cfg)) { - PRINTM(MERROR, "%s: woal_set_net_monitor fail\n", __func__); + if (woal_is_any_interface_active(handle)) { + /* set current band channel config */ + chan_info.bandcfg.chanBand = mon_if->band_chan_cfg.band; + if (mon_if->band_chan_cfg.band & + (BAND_B | BAND_G | BAND_GN | BAND_GAC)) + chan_info.bandcfg.chanBand = BAND_2GHZ; + else + /* TODO: Add support for BAND_4GHZ */ + chan_info.bandcfg.chanBand = BAND_5GHZ; + chan_info.bandcfg.chanWidth = + mon_if->band_chan_cfg.chan_bandwidth; + chan_info.channel = mon_if->band_chan_cfg.channel; + chan_info.is_11n_enabled = MTRUE; + } + if (MLAN_STATUS_FAILURE == + woal_chandef_create(priv, &mon_if->chandef, &chan_info)) { + /* stop monitor mode on error */ + woal_set_net_monitor(priv, MOAL_IOCTL_WAIT, MFALSE, 0, NULL); ret = -EFAULT; goto fail; } @@ -2665,7 +2685,7 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) ENTER(); - if (priv->phandle->driver_status) { + if (priv->phandle->driver_status || priv->phandle->surprise_removed) { PRINTM(MERROR, "Block woal_cfg80211_del_beacon in abnormal driver state\n"); LEAVE(); @@ -2725,6 +2745,9 @@ int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) ret = -EFAULT; goto done; } +#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + woal_cfg80211_setup_uap_he_cap(priv, MOAL_NO_WAIT); +#endif } woal_clear_all_mgmt_ies(priv, MOAL_NO_WAIT); #ifdef STA_SUPPORT @@ -3546,6 +3569,8 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy, mlan_ds_11h_cfg *p11h_cfg = NULL; int ret = 0; mlan_status status = MLAN_STATUS_SUCCESS; + chan_band_info channel; + t_u16 enable = 0; ENTER(); @@ -3568,6 +3593,25 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy, ret = -EBUSY; goto done; } + if (MLAN_STATUS_SUCCESS == + woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, MLAN_ACT_GET)) { + if (enable) { + if (MLAN_STATUS_SUCCESS == + woal_get_active_intf_channel(priv, &channel)) { + if (channel.channel != + chandef->chan->hw_value) { + PRINTM(MERROR, + "DFS channel is not allowed when another connection exists on different channel\n"); + PRINTM(MERROR, + "Another connection's channel=%d, dfs channel=%d\n", + channel.channel, + chandef->chan->hw_value); + ret = -EINVAL; + goto done; + } + } + } + } req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg)); if (NULL == req) { ret = -ENOMEM; @@ -3745,8 +3789,12 @@ mlan_status woal_register_uap_cfg80211(struct net_device *dev, t_u8 bss_type) return MLAN_STATUS_FAILURE; } - if (bss_type == MLAN_BSS_TYPE_UAP) + if (bss_type == MLAN_BSS_TYPE_UAP) { wdev->iftype = NL80211_IFTYPE_AP; +#if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + woal_cfg80211_setup_uap_he_cap(priv, MOAL_IOCTL_WAIT); +#endif + } dev_net_set(dev, wiphy_net(wdev->wiphy)); dev->ieee80211_ptr = wdev; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_usb.c b/mxm_wifiex/wlan_src/mlinux/moal_usb.c index e8cd45f..0f5d3fd 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_usb.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_usb.c @@ -406,6 +406,8 @@ static void woal_usb_tx_complete(struct urb *urb) atomic_dec(&cardp->tx_cmd_urb_pending); else if (context->ep == cardp->tx_data_ep) atomic_dec(&cardp->tx_data_urb_pending); + else if (context->ep == cardp->tx_data2_ep) + atomic_dec(&cardp->tx_data2_urb_pending); queue_work(handle->workqueue, &handle->main_work); @@ -635,6 +637,10 @@ static void woal_usb_unlink_urb(void *card_desc) usb_kill_urb( cardp->tx_data_list[i].urb); } + if (cardp->tx_data2_list[i].urb) { + usb_kill_urb( + cardp->tx_data2_list[i].urb); + } } } } @@ -674,6 +680,10 @@ void woal_usb_free(struct usb_card_rec *cardp) usb_free_urb(cardp->tx_data_list[i].urb); cardp->tx_data_list[i].urb = NULL; } + if (cardp->tx_data2_list[i].urb) { + usb_free_urb(cardp->tx_data2_list[i].urb); + cardp->tx_data2_list[i].urb = NULL; + } } /* Free Tx cmd URB */ if (cardp->tx_cmd.urb) { @@ -1003,6 +1013,24 @@ static int woal_usb_probe(struct usb_interface *intf, (__force int)woal_le16_to_cpu( endpoint->wMaxPacketSize); } + if (usb_endpoint_is_bulk_out(endpoint) && + (usb_endpoint_num(endpoint) == + MLAN_USB_EP_DATA_CH2 || + usb_endpoint_num(endpoint) == + MLAN_USB_EP_DATA_CH2_IF2)) { + /* We found a bulk out data endpoint */ + PRINTM(MCMND, + "Bulk OUT2: max packet size = %d, address = %d\n", + woal_le16_to_cpu( + endpoint->wMaxPacketSize), + endpoint->bEndpointAddress); + usb_cardp->tx_data2_ep = + endpoint->bEndpointAddress; + atomic_set(&usb_cardp->tx_data2_urb_pending, 0); + usb_cardp->tx_data2_maxpktsize = + (__force int)woal_le16_to_cpu( + endpoint->wMaxPacketSize); + } if ((usb_endpoint_is_bulk_out(endpoint) || usb_endpoint_is_int_out(endpoint)) && @@ -1041,6 +1069,14 @@ static int woal_usb_probe(struct usb_interface *intf, __FUNCTION__); goto error; } + if (!usb_cardp->tx_data2_ep) { + PRINTM(MERROR, + "%s: invalid endpoint assignment\n", + __FUNCTION__); + PRINTM(MERROR, + "%s: DATA2 endpoint is not enumarated\n", + __FUNCTION__); + } } usb_cardp->tx_aggr_ctrl.enable = MFALSE; @@ -1254,6 +1290,9 @@ static int woal_usb_suspend(struct usb_interface *intf, pm_message_t message) if (cardp->tx_data_list[i].urb) { usb_kill_urb(cardp->tx_data_list[i].urb); } + if (cardp->tx_data2_list[i].urb) { + usb_kill_urb(cardp->tx_data2_list[i].urb); + } } /* Unlink Tx cmd URB */ if (cardp->tx_cmd.urb) { @@ -1385,6 +1424,15 @@ mlan_status woal_usb_tx_init(moal_handle *handle) ret = MLAN_STATUS_FAILURE; goto init_exit; } + cardp->tx_data2_list[i].handle = handle; + cardp->tx_data2_list[i].ep = cardp->tx_data2_ep; + /* Allocate URB for data */ + cardp->tx_data2_list[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!cardp->tx_data2_list[i].urb) { + PRINTM(MERROR, "Tx data URB allocation failed\n"); + ret = MLAN_STATUS_FAILURE; + goto init_exit; + } } init_exit: @@ -1513,6 +1561,8 @@ static mlan_status woal_usb_write_data_sync(moal_handle *handle, bulk_out_maxpktsize = cardp->tx_cmd_maxpktsize; else if (ep == cardp->tx_data_ep) bulk_out_maxpktsize = cardp->tx_data_maxpktsize; + else if (ep == cardp->tx_data2_ep) + bulk_out_maxpktsize = cardp->tx_data2_maxpktsize; if (length % bulk_out_maxpktsize == 0) length++; @@ -1599,6 +1649,11 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf, (atomic_read(&cardp->tx_data_urb_pending) >= MVUSB_TX_HIGH_WMARK)) { ret = MLAN_STATUS_RESOURCE; goto tx_ret; + } else if ((ep == cardp->tx_data2_ep) && + (atomic_read(&cardp->tx_data2_urb_pending) >= + MVUSB_TX_HIGH_WMARK)) { + ret = MLAN_STATUS_RESOURCE; + goto tx_ret; } PRINTM(MINFO, "woal_write_data_async: ep=%d\n", ep); @@ -1611,6 +1666,11 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf, if (cardp->tx_data_ix >= MVUSB_TX_HIGH_WMARK) cardp->tx_data_ix = 0; context = &cardp->tx_data_list[cardp->tx_data_ix++]; + } else if (ep == cardp->tx_data2_ep) { + bulk_out_maxpktsize = cardp->tx_data2_maxpktsize; + if (cardp->tx_data2_ix >= MVUSB_TX_HIGH_WMARK) + cardp->tx_data2_ix = 0; + context = &cardp->tx_data2_list[cardp->tx_data2_ix++]; } } @@ -1652,6 +1712,8 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf, atomic_inc(&cardp->tx_cmd_urb_pending); else if (ep == cardp->tx_data_ep) atomic_inc(&cardp->tx_data_urb_pending); + else if (ep == cardp->tx_data2_ep) + atomic_inc(&cardp->tx_data2_urb_pending); if (usb_submit_urb(tx_urb, GFP_ATOMIC)) { /* Submit URB failure */ PRINTM(MERROR, "Submit EP %d Tx URB failed: %d\n", ep, ret); @@ -1664,6 +1726,13 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf, cardp->tx_data_ix--; else cardp->tx_data_ix = MVUSB_TX_HIGH_WMARK; + } else if (ep == cardp->tx_data2_ep) { + atomic_dec(&cardp->tx_data2_urb_pending); + if (cardp->tx_data2_ix) + cardp->tx_data2_ix--; + else + cardp->tx_data2_ix = + MVUSB_TX_HIGH_WMARK; } } ret = MLAN_STATUS_FAILURE; @@ -1672,6 +1741,10 @@ mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf, (atomic_read(&cardp->tx_data_urb_pending) == MVUSB_TX_HIGH_WMARK)) ret = MLAN_STATUS_PRESOURCE; + else if (ep == cardp->tx_data2_ep && + (atomic_read(&cardp->tx_data2_urb_pending) == + MVUSB_TX_HIGH_WMARK)) + ret = MLAN_STATUS_PRESOURCE; else ret = MLAN_STATUS_SUCCESS; } diff --git a/mxm_wifiex/wlan_src/mlinux/moal_usb.h b/mxm_wifiex/wlan_src/mlinux/moal_usb.h index 4eff643..5e10133 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_usb.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_usb.h @@ -243,6 +243,16 @@ struct usb_card_rec { t_u8 resubmit_urbs; /** USB card type */ t_u16 card_type; + /** Tx data endpoint address */ + t_u8 tx_data2_ep; + /** Tx data endpoint max pkt size */ + int tx_data2_maxpktsize; + /** Tx data2 URB pending count */ + atomic_t tx_data2_urb_pending; + /** Index to point to next data urb to use */ + int tx_data2_ix; + /** Pre-allocated urb for data */ + urb_context tx_data2_list[MVUSB_TX_HIGH_WMARK]; t_u8 second_mac; }; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_wext.c b/mxm_wifiex/wlan_src/mlinux/moal_wext.c index 7e91899..60697ac 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_wext.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_wext.c @@ -790,30 +790,31 @@ static int woal_get_sens(struct net_device *dev, struct iw_request_info *info, * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure + * @param vwrq A pointer to iwreq_data structure * @param extra A pointer to extra data buf * * @return 0 --success, otherwise fail */ static int woal_set_txpow(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) + union iwreq_data *vwrq, char *extra) { int ret = 0; + struct iw_param *vwrq_ = (struct iw_param *)vwrq; moal_private *priv = (moal_private *)netdev_priv(dev); mlan_power_cfg_t power_cfg; ENTER(); - if (vwrq->disabled) { + if (vwrq_->disabled) { woal_set_radio(priv, 0); goto done; } woal_set_radio(priv, 1); - if (!vwrq->fixed) + if (!vwrq_->fixed) power_cfg.is_power_auto = 1; else { power_cfg.is_power_auto = 0; - power_cfg.power_level = vwrq->value; + power_cfg.power_level = vwrq_->value; } if (MLAN_STATUS_SUCCESS != @@ -832,15 +833,16 @@ done: * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure + * @param vwrq A pointer to iwreq_data structure * @param extra A pointer to extra data buf * * @return 0 --success, otherwise fail */ static int woal_get_txpow(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) + union iwreq_data *vwrq, char *extra) { int ret = 0; + struct iw_param *vwrq_ = (struct iw_param *)vwrq; moal_private *priv = (moal_private *)netdev_priv(dev); mlan_power_cfg_t power_cfg; mlan_bss_info bss_info; @@ -857,16 +859,16 @@ static int woal_get_txpow(struct net_device *dev, struct iw_request_info *info, goto done; } - vwrq->value = power_cfg.power_level; + vwrq_->value = power_cfg.power_level; if (power_cfg.is_power_auto) - vwrq->fixed = 0; + vwrq_->fixed = 0; else - vwrq->fixed = 1; + vwrq_->fixed = 1; if (bss_info.radio_on) { - vwrq->disabled = 0; - vwrq->flags = IW_TXPOW_DBM; + vwrq_->disabled = 0; + vwrq_->flags = IW_TXPOW_DBM; } else { - vwrq->disabled = 1; + vwrq_->disabled = 1; } done: @@ -2586,6 +2588,59 @@ done: return ret; } +/** + * @brief Request scan based on connect parameter + * + * @param priv A pointer to moal_private structure + * @param ssid_bssid A pointer to mlan_ssid_bssid structure + * + * @return 0 -- success, otherwise fail + */ +static int woal_owe_specific_scan(moal_private *priv, + mlan_ssid_bssid *ssid_bssid) +{ + moal_handle *handle = priv->phandle; + int ret = 0; + wlan_user_scan_cfg *scan_req; + ENTER(); + if (handle->scan_pending_on_block == MTRUE) { + PRINTM(MINFO, "scan already in processing...\n"); + LEAVE(); + return ret; + } + scan_req = (wlan_user_scan_cfg *)kmalloc(sizeof(wlan_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + PRINTM(MERROR, "Malloc buffer failed\n"); + LEAVE(); + return -ENOMEM; + } + + priv->report_scan_result = MTRUE; + memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg)); + scan_req->keep_previous_scan = MTRUE; + moal_memcpy_ext(priv->phandle, scan_req->ssid_list[0].ssid, + ssid_bssid->trans_ssid.ssid, + ssid_bssid->trans_ssid.ssid_len, + sizeof(scan_req->ssid_list[0].ssid)); + scan_req->ssid_list[0].max_len = 0; + scan_req->chan_list[0].chan_number = ssid_bssid->channel; + if (ssid_bssid->bss_band == BAND_A) + scan_req->chan_list[0].radio_type = BAND_5GHZ; + else + scan_req->chan_list[0].radio_type = BAND_2GHZ; + scan_req->chan_list[0].scan_time = 0; + // TODO need set to PASSIVE TO ACTIVE on DFS channel + scan_req->chan_list[0].scan_type = MLAN_SCAN_TYPE_ACTIVE; + + moal_memcpy_ext(priv->phandle, scan_req->random_mac, priv->random_mac, + ETH_ALEN, sizeof(scan_req->random_mac)); + ret = woal_request_userscan(priv, MOAL_IOCTL_WAIT, scan_req); + kfree(scan_req); + LEAVE(); + return ret; +} + /** * @brief Set essid * @@ -2603,6 +2658,7 @@ static int woal_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq = &wrqu->data; mlan_802_11_ssid req_ssid; mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *owe_ssid_bssid = NULL; #ifdef REASSOCIATION moal_handle *handle = priv->phandle; mlan_bss_info bss_info; @@ -2740,6 +2796,34 @@ static int woal_set_essid(struct net_device *dev, struct iw_request_info *info, ret = -EFAULT; goto setessid_ret; } + if (ssid_bssid.trans_ssid.ssid_len && + (ssid_bssid.owe_transition_mode == OWE_TRANS_MODE_OPEN)) { + // We need scan for OWE AP + owe_ssid_bssid = (mlan_ssid_bssid *)kmalloc( + sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!owe_ssid_bssid) { + PRINTM(MERROR, "Malloc buffer failed\n"); + ret = -ENOMEM; + goto setessid_ret; + } + woal_owe_specific_scan(priv, &ssid_bssid); + memset(owe_ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + moal_memcpy_ext(priv->phandle, &owe_ssid_bssid->ssid, + &ssid_bssid.trans_ssid, + sizeof(mlan_802_11_ssid), + sizeof(owe_ssid_bssid->ssid)); + moal_memcpy_ext(priv->phandle, &owe_ssid_bssid->bssid, + &ssid_bssid.trans_bssid, + sizeof(mlan_802_11_mac_addr), + sizeof(owe_ssid_bssid->bssid)); + if (MLAN_STATUS_SUCCESS == + woal_find_essid(priv, owe_ssid_bssid, + MOAL_IOCTL_WAIT)) + moal_memcpy_ext(priv->phandle, &ssid_bssid, + owe_ssid_bssid, + sizeof(mlan_ssid_bssid), + sizeof(ssid_bssid)); + } if (MLAN_STATUS_SUCCESS != woal_11d_check_ap_channel(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) { @@ -2793,6 +2877,8 @@ setessid_ret: #ifdef REASSOCIATION MOAL_REL_SEMAPHORE(&handle->reassoc_sem); #endif + if (owe_ssid_bssid) + kfree(owe_ssid_bssid); LEAVE(); return ret; }