diff options
author | Fugang Duan <fugang.duan@nxp.com> | 2020-11-11 17:25:45 +0800 |
---|---|---|
committer | Fugang Duan <fugang.duan@nxp.com> | 2020-11-11 18:02:44 +0800 |
commit | 56bffa9cd6e18bde860875596038622757f58a98 (patch) | |
tree | 6572353619a6f29267d88c2f0c5c5def4ceaac50 | |
parent | 0cd0008697342c4bf1fcd01146c060c1f6e49cf9 (diff) |
MLK-24995 net: wireless: nxp: mxm_wifiex: upgrade to mxm5x16207 release
Upgrade to mxm5x16207 verison:
- Fixed WPA3 SAE pre-cert requirement where there is no assoc
request from DUT, if EX-AP sends the Auth confirm frame
immediately after Auth commit frame.
Reviewed-by: yang.tian <yang.tian@nxp.com>
Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
27 files changed, 902 insertions, 444 deletions
diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11d.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11d.c index 341c6af0cd8e..a9ac930eb2dd 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11d.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11d.c @@ -58,6 +58,7 @@ static region_code_mapping_t region_code_mapping[] = { {"CN ", 0x50}, /* China */ {"JP ", 0xFE}, /* Japan */ {"JP ", 0xFF}, /* Japan special */ + {"NE ", 0x30}, /* New Zeland */ }; /** Universal region code */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c index c62b9cd0a160..9f1869617a21 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c @@ -107,6 +107,14 @@ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_middle_band = {52, static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band = { 100, 11}; +/** U-NII sub-band config : Start Channel = 100, NumChans = 5 */ +static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band_0 = { + 100, 5}; + +/** U-NII sub-band config : Start Channel = 132, NumChans = 3 */ +static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band_1 = { + 132, 3}; + /** U-NII sub-band config : Start Channel = 149, NumChans = 5 */ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_upper_band = {149, 5}; @@ -409,6 +417,23 @@ wlan_11h_set_supp_channels_ie(mlan_private *priv, t_u8 band, psup_chan->subband[num_subbands++] = wlan_11h_unii_upper_band; break; + case 0x7: + /* 36-48 */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_lower_band; + /* 52-64 */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_middle_band; + /* 100-116 */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_mid_upper_band_0; + /* 132-140 */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_mid_upper_band_1; + /* 149-165 */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_upper_band; + break; } } diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cfp.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cfp.c index cd3045ace0c7..6ad3cca77be2 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cfp.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cfp.c @@ -96,6 +96,8 @@ static country_code_mapping_t country_code_mapping[] = { {"RU", 0x30, 0x0f}, /* Russia */ {"IN", 0x10, 0x06}, /* India */ {"MY", 0x30, 0x06}, /* Malaysia */ + {"NZ", 0x30, 0x30}, /* New Zeland */ + {"MX", 0x10, 0x07}, /* Mexico */ }; /** Country code for ETSI */ @@ -103,7 +105,7 @@ static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = { "AL", "AD", "AT", "AU", "BY", "BE", "BA", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "MK", "DE", "GR", "HU", "IS", "IE", "IT", "KR", "LV", "LI", "LT", "LU", "MT", "MD", "MC", "ME", "NL", "NO", "PL", "RO", "RU", - "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB"}; + "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NZ"}; /** * The structure for Channel-Frequency-Power table @@ -423,7 +425,8 @@ static chan_freq_power_t channel_freq_power_JPN_A[] = { {128, 5640, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}, {132, 5660, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}, {136, 5680, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}, - {140, 5700, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}}; + {140, 5700, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}, + {144, 5720, WLAN_TX_PWR_JP_A_DEFAULT, MTRUE}}; /** Band: 'A', Region: China */ static chan_freq_power_t channel_freq_power_CN_A[] = { @@ -498,6 +501,30 @@ static chan_freq_power_t channel_freq_power_RU_A[] = { {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE}, }; +/** Band: 'A', Region: Mexico */ +static chan_freq_power_t channel_freq_power_MX_A[] = { + {36, 5180, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {40, 5200, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {44, 5220, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {48, 5240, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {52, 5260, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {56, 5280, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {60, 5300, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {64, 5320, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {100, 5500, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {104, 5520, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {108, 5540, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {112, 5560, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {116, 5580, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {132, 5660, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {136, 5680, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {140, 5700, WLAN_TX_PWR_EMEA_DEFAULT, MTRUE}, + {149, 5745, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {153, 5765, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {157, 5785, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {161, 5805, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {165, 5825, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}}; + /** Band: 'A', Code: 1, Low band (5150-5250 MHz) channels */ static chan_freq_power_t channel_freq_power_low_band[] = { {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE}, @@ -595,6 +622,12 @@ static cfp_table_t cfp_table_A[] = { channel_freq_power_low_middle_high_band, NELEMENTS(channel_freq_power_low_middle_high_band)}, { + 0x07, /* Mexico */ + channel_freq_power_MX_A, + NELEMENTS(channel_freq_power_MX_A), + }, + + { 0x09, /* SPAIN/Austria/Brazil */ channel_freq_power_SPN2_A, NELEMENTS(channel_freq_power_SPN2_A), @@ -3429,6 +3462,8 @@ mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter, t_u32 cfp_no_bg = 0; chan_freq_power_t *cfp_a = MNULL; t_u32 cfp_no_a = 0; + t_u8 cfp_code_a = pmadapter->region_code; + t_u8 cfp_code_bg = pmadapter->region_code; t_u32 len = 0, size = 0; t_u8 *req_buf, *tmp; mlan_status ret = MLAN_STATUS_SUCCESS; @@ -3446,13 +3481,17 @@ mlan_status wlan_get_cfpinfo(pmlan_adapter pmadapter, size = sizeof(pmadapter->country_code) + sizeof(pmadapter->region_code); /* Add size to store region, country and environment codes */ size += sizeof(t_u32); + if (pmadapter->cfp_code_bg) + cfp_code_bg = pmadapter->cfp_code_bg; /* Get cfp table and its size corresponding to the region code */ - cfp_bg = wlan_get_region_cfp_table(pmadapter, pmadapter->region_code, + cfp_bg = wlan_get_region_cfp_table(pmadapter, cfp_code_bg, BAND_G | BAND_B, &cfp_no_bg); size += cfp_no_bg * sizeof(chan_freq_power_t); - cfp_a = wlan_get_region_cfp_table(pmadapter, pmadapter->region_code, - BAND_A, &cfp_no_a); + if (pmadapter->cfp_code_a) + cfp_code_a = pmadapter->cfp_code_a; + cfp_a = wlan_get_region_cfp_table(pmadapter, cfp_code_a, BAND_A, + &cfp_no_a); size += cfp_no_a * sizeof(chan_freq_power_t); if (pmadapter->otp_region) size += sizeof(pmadapter->otp_region->environment); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c index 3bc6060194fb..f127bbd6c4ec 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c @@ -934,6 +934,8 @@ static t_u16 wlan_get_cmd_timeout(t_u16 cmd_id) case HostCmd_CMD_802_11_SCAN_EXT: timeout = MRVDRV_TIMER_10S * 2; break; + case HostCmd_CMD_FUNC_INIT: + case HostCmd_CMD_FUNC_SHUTDOWN: case HostCmd_CMD_802_11_ASSOCIATE: case HostCmd_CMD_802_11_DEAUTHENTICATE: case HostCmd_CMD_802_11_DISASSOCIATE: @@ -8217,3 +8219,60 @@ mlan_status wlan_ret_get_chan_trpc_config(pmlan_private pmpriv, LEAVE(); return MLAN_STATUS_SUCCESS; } + +/** + * @brief This function prepares command of RANGE_EXT + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status wlan_cmd_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf) +{ + HostCmd_DS_RANGE_EXT *range_ext = &cmd->params.range_ext; + t_u8 mode = *(t_u8 *)pdata_buf; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RANGE_EXT); + cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_RANGE_EXT) + S_DS_GEN); + range_ext->action = wlan_cpu_to_le16(cmd_action); + + if (cmd_action == HostCmd_ACT_GEN_SET) + range_ext->mode = mode; + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** + * @brief This function handles the command response of RANGE_EXT + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to command buffer + * + * @return MLAN_STATUS_SUCCESS + */ +mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf) +{ + mlan_ds_misc_cfg *misc_cfg = MNULL; + HostCmd_DS_RANGE_EXT *range_ext = &resp->params.range_ext; + + ENTER(); + + if (pioctl_buf && + (wlan_le16_to_cpu(range_ext->action) == HostCmd_ACT_GEN_GET)) { + misc_cfg = (mlan_ds_misc_cfg *)pioctl_buf->pbuf; + misc_cfg->param.range_ext_mode = range_ext->mode; + PRINTM(MCMND, "Get range ext mode %d\n", + misc_cfg->param.range_ext_mode); + } + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h index f566e3091996..11e6cd351c6a 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "203" +#define MLAN_RELEASE_VERSION "207" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h index 9612873407a0..4f4d3128cb8c 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -1590,6 +1590,8 @@ typedef MLAN_PACK_START struct _power_table_attr { #define HostCmd_CMD_11AX_CFG 0x0266 /** Host Command ID: 11AX command */ #define HostCmd_CMD_11AX_CMD 0x026d +/** Host Command ID: Range ext command */ +#define HostCmd_CMD_RANGE_EXT 0x0274 /** Host Command ID: TWT cfg command */ #define HostCmd_CMD_TWT_CFG 0x0270 @@ -4612,6 +4614,14 @@ typedef MLAN_PACK_START struct _HostCmd_DS_11AX_CMD_CFG { t_u8 val[]; } MLAN_PACK_END HostCmd_DS_11AX_CMD_CFG; +/** HostCmd_DS_RANGE_EXT */ +typedef MLAN_PACK_START struct _HostCmd_DS_RANGE_EXT { + /** Action */ + t_u16 action; + /** Range ext mode */ + t_u8 mode; +} MLAN_PACK_END HostCmd_DS_RANGE_EXT; + /** Type definition of hostcmd_twt_setup */ typedef struct MLAN_PACK_START _hostcmd_twt_setup { /** Implicit, 0: TWT session is explicit, 1: Session is implicit */ @@ -7297,6 +7307,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND { HostCmd_DS_11AX_CFG axcfg; /** HostCmd_DS_11AX_CMD_CFG */ HostCmd_DS_11AX_CMD_CFG axcmd; + HostCmd_DS_RANGE_EXT range_ext; /** HostCmd_DS_TWT_CFG */ HostCmd_DS_TWT_CFG twtcfg; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index 9523410e6b57..c3a0a495b62c 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -329,6 +329,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_ARB_CONFIG = 0x00200078, MLAN_OID_MISC_BEACON_STUCK = 0x00200079, MLAN_OID_MISC_CFP_TABLE = 0x0020007A, + MLAN_OID_MISC_RANGE_EXT = 0x0020007B, }; /** Sub command size */ @@ -696,8 +697,6 @@ typedef struct _mlan_ssid_bssid { t_u32 channel_flags; /** host mlme flag*/ t_u8 host_mlme; - /* Use management frame protection (IEEE 802.11w) in this association*/ - t_u8 use_mfp; /** assoicate resp frame/ie from firmware */ mlan_ds_misc_assoc_rsp assoc_rsp; } mlan_ssid_bssid, *pmlan_ssid_bssid; @@ -5089,6 +5088,7 @@ typedef struct _mlan_ds_misc_cfg { struct mfg_cmd_tx_frame2 mfg_tx_frame2; mlan_ds_misc_arb_cfg arb_cfg; mlan_ds_misc_cfp_tbl cfp; + t_u8 range_ext_mode; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_join.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_join.c index 81b46d19598e..359e0319a6f8 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_join.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_join.c @@ -547,9 +547,76 @@ static int wlan_cmd_append_osen_ie(mlan_private *priv, t_u8 **ppbuffer) return retlen; } +/** + * @brief This function get the rsn_cap from RSN ie buffer. + * + * @param pmpriv A pointer to mlan_private structure + * + * @param data A pointer to rsn_ie data after IE header + * @param return rsn_cap + */ +t_u16 wlan_get_rsn_cap(t_u8 *data) +{ + t_u16 rsn_cap = 0; + t_u16 *ptr; + t_u16 pairwise_cipher_count = 0; + t_u16 akm_suite_count = 0; + /* rsn_cap = data + 2 bytes version + 4 bytes + * group_cipher_suite + 2 bytes pairwise_cipher_count + + * pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN + 2 bytes + * akm_suite_count + akm_suite_count * AKM_SUITE_LEN + */ + ptr = (t_u16 *)(data + sizeof(t_u16) + 4 * sizeof(t_u8)); + pairwise_cipher_count = wlan_le16_to_cpu(*ptr); + ptr = (t_u16 *)(data + sizeof(t_u16) + 4 * sizeof(t_u8) + + sizeof(t_u16) + + pairwise_cipher_count * PAIRWISE_CIPHER_SUITE_LEN); + akm_suite_count = wlan_le16_to_cpu(*ptr); + ptr = (t_u16 *)(data + 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); + rsn_cap = wlan_le16_to_cpu(*ptr); + PRINTM(MCMND, "rsn_cap=0x%x\n", rsn_cap); + return rsn_cap; +} + +/** + * @brief This function check if we should enable 11w + * + * @param pmpriv A pointer to mlan_private structure + * + * @param BSSDescriptor_t A pointer to BSSDescriptor_t data structure + * @param return MTRUE/MFALSE + */ +t_u8 wlan_use_mfp(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc) +{ + t_u16 ap_rsn_cap = 0; + t_u16 sta_rsn_cap = 0; + t_u8 ap_mfpc, ap_mfpr; + t_u8 sta_mfpc, sta_mfpr; + + if (pmpriv->wpa_ie[0] != RSN_IE) + return 0; + sta_rsn_cap = wlan_get_rsn_cap(pmpriv->wpa_ie + 2); + if (!pbss_desc->prsn_ie) + return 0; + ap_rsn_cap = wlan_get_rsn_cap(pbss_desc->prsn_ie->data); + ap_mfpc = ((ap_rsn_cap & (0x1 << MFPC_BIT)) == (0x1 << MFPC_BIT)); + ap_mfpr = ((ap_rsn_cap & (0x1 << MFPR_BIT)) == (0x1 << MFPR_BIT)); + sta_mfpc = ((sta_rsn_cap & (0x1 << MFPC_BIT)) == (0x1 << MFPC_BIT)); + sta_mfpr = ((sta_rsn_cap & (0x1 << MFPR_BIT)) == (0x1 << MFPR_BIT)); + if (!ap_mfpc && !ap_mfpr) + return MFALSE; + if (!sta_mfpc && !sta_mfpr) + return MFALSE; + return MTRUE; +} + /******************************************************** Global Functions ********************************************************/ + /** * @brief This function updates RSN IE in the association request. * @@ -978,6 +1045,12 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, psecurity_cfg_ie = (MrvlIEtypes_SecurityCfg_t *)pos; psecurity_cfg_ie->header.type = wlan_cpu_to_le16(TLV_TYPE_SECURITY_CFG); + + pmpriv->curr_bss_params.use_mfp = + wlan_use_mfp(pmpriv, pbss_desc); + PRINTM(MCMND, "use_mfp=%d\n", + pmpriv->curr_bss_params.use_mfp); + if (!pmpriv->curr_bss_params.use_mfp) psecurity_cfg_ie->use_mfp = MFALSE; else @@ -985,8 +1058,6 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, psecurity_cfg_ie->header.len = sizeof(t_u8); pos += sizeof(psecurity_cfg_ie->header) + psecurity_cfg_ie->header.len; - PRINTM(MCMND, "use_mfp=%d\n", - pmpriv->curr_bss_params.use_mfp); } #ifdef DRV_EMBEDDED_SUPPLICANT else if (supplicantIsEnabled(pmpriv->psapriv)) { diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h index ddfbfc52c35d..2f145a696313 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -3348,6 +3348,8 @@ mlan_status wlan_ret_mfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); mlan_status wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); +mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); mlan_status wlan_misc_ioctl_arb_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); /* CFP related functions */ @@ -3762,6 +3764,11 @@ mlan_status wlan_ret_set_get_low_power_mode_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf); +mlan_status wlan_cmd_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, + t_u16 cmd_action, t_void *pdata_buf); +mlan_status wlan_ret_range_ext(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, + mlan_ioctl_req *pioctl_buf); + /** * @brief RA based queueing * diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_misc.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_misc.c index 33e51546a5e6..b2013e978e9d 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_misc.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_misc.c @@ -5800,3 +5800,35 @@ done: LEAVE(); return ret; } + +/** + * @brief Range ext mode config + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + + ENTER(); + + if (pioctl_req->action == MLAN_ACT_SET) + cmd_action = HostCmd_ACT_GEN_SET; + else + cmd_action = HostCmd_ACT_GEN_GET; + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RANGE_EXT, cmd_action, 0, + (t_void *)pioctl_req, + &(pmisc->param.range_ext_mode)); + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sdio.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sdio.c index d216caa6acdc..b88c4fdb3ad8 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sdio.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sdio.c @@ -1941,22 +1941,30 @@ mlan_status wlan_sdio_interrupt(t_u16 msg_id, pmlan_adapter pmadapter) pmlan_callbacks pcb = &pmadapter->callbacks; mlan_buffer mbuf; t_u32 sdio_ireg = 0; + t_u8 offset = 0; t_u8 max_mp_regs = pmadapter->pcard_sd->reg->max_mp_regs; t_u8 host_int_status_reg = pmadapter->pcard_sd->reg->host_int_status_reg; ENTER(); - memset(pmadapter, &mbuf, 0, sizeof(mlan_buffer)); - mbuf.pbuf = pmadapter->pcard_sd->mp_regs; - mbuf.data_len = max_mp_regs; + while (max_mp_regs) { + memset(pmadapter, &mbuf, 0, sizeof(mlan_buffer)); + mbuf.pbuf = pmadapter->pcard_sd->mp_regs + offset; + mbuf.data_len = MIN(max_mp_regs, MLAN_SDIO_BLOCK_SIZE); - if (MLAN_STATUS_SUCCESS != - pcb->moal_read_data_sync(pmadapter->pmoal_handle, &mbuf, - REG_PORT | MLAN_SDIO_BYTE_MODE_MASK, 0)) { - PRINTM(MERROR, "moal_read_data_sync: read registers failed\n"); - pmadapter->dbg.num_int_read_failure++; - goto done; + if (MLAN_STATUS_SUCCESS != + pcb->moal_read_data_sync(pmadapter->pmoal_handle, &mbuf, + (REG_PORT + offset) | + MLAN_SDIO_BYTE_MODE_MASK, + 0)) { + PRINTM(MERROR, + "moal_read_data_sync: read registers failed\n"); + pmadapter->dbg.num_int_read_failure++; + goto done; + } + offset += mbuf.data_len; + max_mp_regs -= mbuf.data_len; } DBG_HEXDUMP(MIF_D, "SDIO MP Registers", pmadapter->pcard_sd->mp_regs, diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c index 982988cbb233..0adca3a971e5 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmd.c @@ -2811,6 +2811,10 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_11AX_CMD: ret = wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_RANGE_EXT: + ret = wlan_cmd_range_ext(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; case HostCmd_CMD_TWT_CFG: ret = wlan_cmd_twt_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c index 5e1a5b1a659f..16956af389c8 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c @@ -2675,6 +2675,9 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_11AX_CMD: ret = wlan_ret_11ax_cmd(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_RANGE_EXT: + ret = wlan_ret_range_ext(pmpriv, resp, pioctl_buf); + break; case HostCmd_CMD_TWT_CFG: break; case HostCmd_CMD_RX_ABORT_CFG: diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c index f5acb10cda68..304efa99eceb 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_event.c @@ -25,7 +25,6 @@ Change log: 10/13/2008: initial version ********************************************************/ -#include <linux/types.h> #include "mlan.h" #include "mlan_join.h" #include "mlan_util.h" @@ -982,7 +981,7 @@ mlan_status wlan_ops_sta_process_event(t_void *priv) pevent->bss_index = pmpriv->bss_index; pevent->event_id = MLAN_EVENT_ID_SSU_DUMP_FILE; pevent->event_len = MLAN_SSU_BUF_SIZE; - *(t_u64 *)pevent->event_buf = (uintptr_t)pmadapter->ssu_buf->pbuf + + *(t_u64 *)pevent->event_buf = (t_u64)pmadapter->ssu_buf->pbuf + pmadapter->ssu_buf->data_offset; wlan_recv_event(pmpriv, pevent->event_id, pevent); wlan_free_ssu_pcie_buf(pmadapter); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c index 908e688e37ef..4e4c7cfee59f 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c @@ -1059,8 +1059,6 @@ static mlan_status wlan_bss_ioctl_start(pmlan_adapter pmadapter, "SSID found in scan list ... associating...\n"); pmpriv->curr_bss_params.host_mlme = bss->param.ssid_bssid.host_mlme; - pmpriv->curr_bss_params.use_mfp = - bss->param.ssid_bssid.use_mfp; /* Clear any past association response stored for * application retrieval */ pmpriv->assoc_rsp_size = 0; @@ -5169,6 +5167,8 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, case MLAN_OID_MISC_ARB_CONFIG: status = wlan_misc_ioctl_arb_cfg(pmadapter, pioctl_req); break; + status = wlan_misc_ioctl_range_ext(pmadapter, pioctl_req); + break; default: if (pioctl_req) pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index 45ea63030b9b..53edcc2ac7bb 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -4555,6 +4555,10 @@ mlan_status wlan_ops_uap_prepare_cmd(t_void *priv, t_u16 cmd_no, case HostCmd_CMD_11AX_CMD: ret = wlan_cmd_11ax_cmd(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_RANGE_EXT: + ret = wlan_cmd_range_ext(pmpriv, cmd_ptr, cmd_action, + pdata_buf); + break; case HostCmd_CMD_RX_ABORT_CFG: ret = wlan_cmd_rxabortcfg(pmpriv, cmd_ptr, cmd_action, pdata_buf); @@ -4925,6 +4929,9 @@ mlan_status wlan_ops_uap_process_cmdresp(t_void *priv, t_u16 cmdresp_no, case HostCmd_CMD_11AX_CMD: ret = wlan_ret_11ax_cmd(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_RANGE_EXT: + ret = wlan_ret_range_ext(pmpriv, resp, pioctl_buf); + break; case HostCmd_CMD_RX_ABORT_CFG: ret = wlan_ret_rxabortcfg(pmpriv, resp, pioctl_buf); break; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c index 5f2040ccbbf3..032fb2328395 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c @@ -2100,6 +2100,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) status = wlan_get_rgchnpwr_cfg(pmadapter, pioctl_req); if (misc->sub_command == MLAN_OID_MISC_CFP_TABLE) status = wlan_get_cfp_table(pmadapter, pioctl_req); + if (misc->sub_command == MLAN_OID_MISC_RANGE_EXT) + status = wlan_misc_ioctl_range_ext(pmadapter, + pioctl_req); break; case MLAN_IOCTL_POWER_CFG: power = (mlan_ds_power_cfg *)pioctl_req->pbuf; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index f566e3091996..11e6cd351c6a 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "203" +#define MLAN_RELEASE_VERSION "207" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index 9523410e6b57..c3a0a495b62c 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -329,6 +329,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_ARB_CONFIG = 0x00200078, MLAN_OID_MISC_BEACON_STUCK = 0x00200079, MLAN_OID_MISC_CFP_TABLE = 0x0020007A, + MLAN_OID_MISC_RANGE_EXT = 0x0020007B, }; /** Sub command size */ @@ -696,8 +697,6 @@ typedef struct _mlan_ssid_bssid { t_u32 channel_flags; /** host mlme flag*/ t_u8 host_mlme; - /* Use management frame protection (IEEE 802.11w) in this association*/ - t_u8 use_mfp; /** assoicate resp frame/ie from firmware */ mlan_ds_misc_assoc_rsp assoc_rsp; } mlan_ssid_bssid, *pmlan_ssid_bssid; @@ -5089,6 +5088,7 @@ typedef struct _mlan_ds_misc_cfg { struct mfg_cmd_tx_frame2 mfg_tx_frame2; mlan_ds_misc_arb_cfg arb_cfg; mlan_ds_misc_cfp_tbl cfp; + t_u8 range_ext_mode; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c index 695666f9af5d..0e124c595003 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c @@ -143,10 +143,10 @@ static const struct nla_policy woal_fw_roaming_policy[MRVL_WLAN_VENDOR_ATTR_FW_ROAMING_MAX + 1] = { [MRVL_WLAN_VENDOR_ATTR_FW_ROAMING_CONTROL] = {.type = NLA_U32}, [MRVL_WLAN_VENDOR_ATTR_FW_ROAMING_CONFIG_BSSID] = { - .type = NLA_MIN_LEN, + .type = NLA_BINARY, .len = sizeof(int)}, [MRVL_WLAN_VENDOR_ATTR_FW_ROAMING_CONFIG_SSID] = { - .type = NLA_MIN_LEN, + .type = NLA_BINARY, .len = sizeof(int)}, }; // clang-format on @@ -155,8 +155,7 @@ static const struct nla_policy woal_keep_alive_policy[MKEEP_ALIVE_ATTRIBUTE_MAX + 1] = { [MKEEP_ALIVE_ATTRIBUTE_ID] = {.type = NLA_U8}, [MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE] = {.type = NLA_U16}, - [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = {.type = NLA_MIN_LEN, - .len = 1}, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = {.type = NLA_BINARY, .len = 1}, [MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = {.type = NLA_U16}, [MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = {.type = NLA_STRING, .len = ETH_ALEN}, diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index a677688142f2..8c01f52a3358 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -559,6 +559,88 @@ done: } /** + * @brief Set/get range ext mode + * + * + * @param priv Pointer to the mlan_private driver data struct + * @param respbuf A pointer to response buffer + * @param len length used + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written if successful else negative value + */ +static int woal_setget_priv_range_ext(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + int ret = 0; + int data[1]; + int header_len = 0, user_data_len = 0; + mlan_status status = MLAN_STATUS_SUCCESS; + + ENTER(); + + if (!respbuf) { + PRINTM(MERROR, "response buffer is not available!\n"); + ret = -EINVAL; + goto done; + } + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RANGE_EXT); + user_data_len = strlen(respbuf) - header_len; + + /* Allocate an IOCTL request buffer */ + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + /* Fill request buffer */ + misc = (mlan_ds_misc_cfg *)req->pbuf; + misc->sub_command = MLAN_OID_MISC_RANGE_EXT; + req->req_id = MLAN_IOCTL_MISC_CFG; + if (strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + req->action = MLAN_ACT_GET; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), + &user_data_len); + if (user_data_len != 1) { + PRINTM(MERROR, "Invalid Parameter\n"); + ret = -EFAULT; + goto done; + } + if (data[0] < 0 || data[0] > 2) { + PRINTM(MERROR, + "Invalid Parameter: range_ext mode 0-2\n"); + ret = -EFAULT; + goto done; + } + misc->param.range_ext_mode = (t_u8)data[0]; + req->action = MLAN_ACT_SET; + } + /* Send IOCTL request to MLAN */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + data[0] = misc->param.range_ext_mode; + moal_memcpy_ext(priv->phandle, respbuf, (t_u32 *)data, sizeof(data), + respbuflen); + ret = sizeof(data); +done: + if (status != MLAN_STATUS_PENDING) + kfree(req); + + LEAVE(); + return ret; +} + +/** * @brief Custom IE setting * * @param priv A pointer to moal_private structure @@ -10412,6 +10494,418 @@ done: } /** + * @brief determine the center frquency center index for bandwidth + * of 80 MHz and 160 MHz + * + ** @param priv Pointer to moal_private structure + * @param band band + * @param pri_chan primary channel + * @param chan_bw channel bandwidth + * + * @return channel center frequency center, if found; O, otherwise + */ + +t_u8 woal_get_center_freq_idx(moal_private *priv, t_u8 band, t_u32 pri_chan, + t_u8 chan_bw) +{ + t_u8 center_freq_idx = 0; + + if (band & BAND_AAC) { + switch (pri_chan) { + case 36: + case 40: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 38; + break; + } + /* fall through */ + case 44: + case 48: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 46; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 42; + break; + } + /* fall through */ + case 52: + case 56: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 54; + break; + } + /* fall through */ + case 60: + case 64: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 62; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 58; + break; + } else if (chan_bw == CHANNEL_BW_160MHZ) { + center_freq_idx = 50; + break; + } + /* fall through */ + case 68: + case 72: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 70; + break; + } + /* fall through */ + case 76: + case 80: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 78; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 74; + break; + } + /* fall through */ + case 84: + case 88: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 86; + break; + } + /* fall through */ + case 92: + case 96: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 94; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 90; + break; + } + /* fall through */ + case 100: + case 104: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 102; + break; + } + /* fall through */ + case 108: + case 112: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 110; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 106; + break; + } + /* fall through */ + case 116: + case 120: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 118; + break; + } + /* fall through */ + case 124: + case 128: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 126; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 122; + } else if (chan_bw == CHANNEL_BW_160MHZ) { + center_freq_idx = 114; + } + break; + case 132: + case 136: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 134; + break; + } + /* fall through */ + case 140: + case 144: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 126; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 138; + } + break; + case 149: + case 153: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 151; + break; + } + /* fall through */ + case 157: + case 161: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 159; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 155; + break; + } + /* fall through */ + case 165: + case 169: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 167; + break; + } + /* fall through */ + case 173: + case 177: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 175; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 171; + break; + } + /* fall through */ + case 184: + case 188: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 186; + break; + } + /* fall through */ + case 192: + case 196: + if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || + chan_bw == CHANNEL_BW_40MHZ_BELOW) { + center_freq_idx = 194; + break; + } else if (chan_bw == CHANNEL_BW_80MHZ) { + center_freq_idx = 190; + break; + } + /* fall through */ + default: /* error. go to the default */ + center_freq_idx = 42; + } + } + return center_freq_idx; +} + +/** + * @brief determine the center frquency center index for bandwidth + * of 80 MHz and 160 MHz + * + ** @param priv Pointer to moal_private structure + * @param block_tx 0-no need block traffic 1- need block traffic + * @param oper_class oper_class + * @param channel channel + * @param switch count how many csa/ecsa beacon will send out + * @param band_width 1-40Mhz above, 3-40Mhz below, 4-80Mhz, 5-160Mhz + * @param ecsa MTRUE/MFALSE; + * + * @return channel center frequency center, if found; O, otherwise + */ + +static int woal_channel_switch(moal_private *priv, t_u8 block_tx, + t_u8 oper_class, t_u8 channel, t_u8 switch_count, + t_u8 band_width, t_u8 ecsa) +{ + IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL; + IEEEtypes_ChanSwitchAnn_t *chan_switch = NULL; + custom_ie *pcust_chansw_ie = NULL; + t_u8 center_freq_idx = 0; + IEEEtypes_Header_t *pChanSwWrap_ie = NULL; + IEEEtypes_WideBWChanSwitch_t *pbwchansw_ie = NULL; + IEEEtypes_VhtTpcEnvelope_t *pvhttpcEnv_ie = NULL; + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_status status = MLAN_STATUS_SUCCESS; + t_u8 bw; + t_u8 new_oper_class = oper_class; + int ret = 0; + + ENTER(); + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + 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 */ + 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 = 3; + chan_switch->chan_switch_mode = block_tx; + chan_switch->new_channel_num = channel; + chan_switch->chan_switch_count = switch_count; + DBG_HEXDUMP(MCMD_D, "CSA IE", (t_u8 *)pcust_chansw_ie->ie_buffer, + pcust_chansw_ie->ie_length); + switch (band_width) { + case CHANNEL_BW_40MHZ_ABOVE: + case CHANNEL_BW_40MHZ_BELOW: + bw = 40; + break; + case CHANNEL_BW_80MHZ: + bw = 80; + break; + case CHANNEL_BW_160MHZ: + bw = 160; + break; + default: + bw = 20; + break; + } + if (!new_oper_class && ecsa) + woal_priv_get_nonglobal_operclass_by_bw_channel( + priv, bw, channel, &new_oper_class); + if (new_oper_class) { + pcust_chansw_ie->ie_length += + sizeof(IEEEtypes_ExtChanSwitchAnn_t); + ext_chan_switch = + (IEEEtypes_ExtChanSwitchAnn_t + *)(pcust_chansw_ie->ie_buffer + + sizeof(IEEEtypes_ChanSwitchAnn_t)); + ext_chan_switch->element_id = EXTEND_CHANNEL_SWITCH_ANN; + ext_chan_switch->len = 4; + ext_chan_switch->chan_switch_mode = block_tx; + ext_chan_switch->new_oper_class = new_oper_class; + ext_chan_switch->new_channel_num = channel; + ext_chan_switch->chan_switch_count = switch_count; + DBG_HEXDUMP(MCMD_D, "ECSA IE", + (t_u8 *)(pcust_chansw_ie->ie_buffer + + sizeof(IEEEtypes_ChanSwitchAnn_t)), + pcust_chansw_ie->ie_length - + sizeof(IEEEtypes_ChanSwitchAnn_t)); + } + /* bandwidth 40/80/160 should set channel switch wrapper ie for 11ac 5G + * channel*/ + if (band_width && channel > 14) { + pChanSwWrap_ie = + (IEEEtypes_Header_t *)(pcust_chansw_ie->ie_buffer + + pcust_chansw_ie->ie_length); + pChanSwWrap_ie->element_id = EXT_POWER_CONSTR; + pChanSwWrap_ie->len = sizeof(IEEEtypes_WideBWChanSwitch_t); + + pbwchansw_ie = (IEEEtypes_WideBWChanSwitch_t + *)((t_u8 *)pChanSwWrap_ie + + sizeof(IEEEtypes_Header_t)); + pbwchansw_ie->ieee_hdr.element_id = BW_CHANNEL_SWITCH; + pbwchansw_ie->ieee_hdr.len = + sizeof(IEEEtypes_WideBWChanSwitch_t) - + sizeof(IEEEtypes_Header_t); + + center_freq_idx = woal_get_center_freq_idx(priv, BAND_AAC, + channel, band_width); + if (band_width == CHANNEL_BW_40MHZ_ABOVE || + band_width == CHANNEL_BW_40MHZ_BELOW) { + pbwchansw_ie->new_channel_width = 0; + pbwchansw_ie->new_channel_center_freq0 = + center_freq_idx; + } else if (band_width == CHANNEL_BW_80MHZ) { + pbwchansw_ie->new_channel_width = 1; + pbwchansw_ie->new_channel_center_freq0 = + center_freq_idx - 4; + pbwchansw_ie->new_channel_center_freq1 = + center_freq_idx + 4; + } else if (band_width == CHANNEL_BW_160MHZ) { + pbwchansw_ie->new_channel_width = 2; + pbwchansw_ie->new_channel_center_freq0 = + center_freq_idx - 8; + pbwchansw_ie->new_channel_center_freq1 = + center_freq_idx + 8; + } else + PRINTM(MERROR, + "Invalid bandwidth.Support value 1/3/4/5 for 40+/40-/80/160MHZ\n"); + + /*prepare the VHT Transmit Power Envelope IE*/ + pvhttpcEnv_ie = + (IEEEtypes_VhtTpcEnvelope_t + *)((t_u8 *)pChanSwWrap_ie + + sizeof(IEEEtypes_Header_t) + + sizeof(IEEEtypes_WideBWChanSwitch_t)); + pvhttpcEnv_ie->ieee_hdr.element_id = VHT_TX_POWER_ENV; + pvhttpcEnv_ie->ieee_hdr.len = + sizeof(IEEEtypes_VhtTpcEnvelope_t) - + sizeof(IEEEtypes_Header_t); + /* Local Max TX Power Count= 3, + * Local TX Power Unit Inter=EIP(0) */ + pvhttpcEnv_ie->tpc_info = 3; + pvhttpcEnv_ie->local_max_tp_20mhz = 0xff; + pvhttpcEnv_ie->local_max_tp_40mhz = 0xff; + pvhttpcEnv_ie->local_max_tp_80mhz = 0xff; + pChanSwWrap_ie->len += sizeof(IEEEtypes_VhtTpcEnvelope_t); + pcust_chansw_ie->ie_length += + pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t); + DBG_HEXDUMP(MCMD_D, "Channel switch wrapper IE", + (t_u8 *)pChanSwWrap_ie, + pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t)); + } + if (block_tx) { + if (netif_carrier_ok(priv->netdev)) + netif_carrier_off(priv->netdev); + woal_stop_queue(priv->netdev); + priv->uap_tx_blocked = MTRUE; + } + + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "Failed to set ECSA IE\n"); + ret = -EFAULT; + goto done; + } + + 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 * (switch_count + 2) * 110 / 1000); + + pcust_chansw_ie->ie_index = 0xffff; /*Auto index */ + pcust_chansw_ie->mgmt_subtype_mask = 0; + status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_SUCCESS) { + PRINTM(MERROR, "Failed to clear ECSA IE\n"); + } +done: + if (status != MLAN_STATUS_PENDING) + kfree(ioctl_req); + + LEAVE(); + return ret; +} + +/** * @brief Set/Get CFP table codes * * @param priv Pointer to moal_private structure @@ -13007,223 +13501,6 @@ done: } /** - * @brief determine the center frquency center index for bandwidth - * of 80 MHz and 160 MHz - * - ** @param priv Pointer to moal_private structure - * @param band band - * @param pri_chan primary channel - * @param chan_bw channel bandwidth - * - * @return channel center frequency center, if found; O, otherwise - */ - -t_u8 woal_get_center_freq_idx(moal_private *priv, t_u8 band, t_u32 pri_chan, - t_u8 chan_bw) -{ - t_u8 center_freq_idx = 0; - - if (band & BAND_AAC) { - switch (pri_chan) { - case 36: - case 40: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 38; - break; - } - /* fall through */ - case 44: - case 48: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 46; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 42; - break; - } - /* fall through */ - case 52: - case 56: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 54; - break; - } - /* fall through */ - case 60: - case 64: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 62; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 58; - break; - } else if (chan_bw == CHANNEL_BW_160MHZ) { - center_freq_idx = 50; - break; - } - /* fall through */ - case 68: - case 72: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 70; - break; - } - /* fall through */ - case 76: - case 80: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 78; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 74; - break; - } - /* fall through */ - case 84: - case 88: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 86; - break; - } - /* fall through */ - case 92: - case 96: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 94; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 90; - break; - } - /* fall through */ - case 100: - case 104: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 102; - break; - } - /* fall through */ - case 108: - case 112: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 110; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 106; - break; - } - /* fall through */ - case 116: - case 120: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 118; - break; - } - /* fall through */ - case 124: - case 128: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 126; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 122; - } else if (chan_bw == CHANNEL_BW_160MHZ) { - center_freq_idx = 114; - } - break; - case 132: - case 136: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 134; - break; - } - /* fall through */ - case 140: - case 144: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 126; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 138; - } - break; - case 149: - case 153: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 151; - break; - } - /* fall through */ - case 157: - case 161: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 159; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 155; - break; - } - /* fall through */ - case 165: - case 169: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 167; - break; - } - /* fall through */ - case 173: - case 177: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 175; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 171; - break; - } - /* fall through */ - case 184: - case 188: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 186; - break; - } - /* fall through */ - case 192: - case 196: - if (chan_bw == CHANNEL_BW_40MHZ_ABOVE || - chan_bw == CHANNEL_BW_40MHZ_BELOW) { - center_freq_idx = 194; - break; - } else if (chan_bw == CHANNEL_BW_80MHZ) { - center_freq_idx = 190; - break; - } - /* fall through */ - default: /* error. go to the default */ - center_freq_idx = 42; - } - } - return center_freq_idx; -} - -/** ** @brief Set extended channel switch ie ** ** @param priv Pointer to moal_private structure @@ -13238,17 +13515,6 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, int ret = 0; int user_data_len = 0; int data[5] = {0}; - IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL; - IEEEtypes_ChanSwitchAnn_t *chan_switch = NULL; - custom_ie *pcust_chansw_ie = NULL; - t_u8 center_freq_idx = 0; - IEEEtypes_Header_t *pChanSwWrap_ie = NULL; - IEEEtypes_WideBWChanSwitch_t *pbwchansw_ie = NULL; - IEEEtypes_VhtTpcEnvelope_t *pvhttpcEnv_ie = NULL; - mlan_ioctl_req *ioctl_req = NULL; - mlan_ds_misc_cfg *misc = NULL; - mlan_status status = MLAN_STATUS_SUCCESS; - ENTER(); if (!priv || !priv->phandle || (priv->bss_role != MLAN_BSS_ROLE_UAP) || @@ -13272,154 +13538,17 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, return ret; } - ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); - if (ioctl_req == NULL) { - ret = -ENOMEM; - goto done; - } - - 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 */ - 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 = 3; - chan_switch->chan_switch_mode = data[0]; - chan_switch->new_channel_num = data[2]; - chan_switch->chan_switch_count = data[3]; - DBG_HEXDUMP(MCMD_D, "CSA IE", (t_u8 *)pcust_chansw_ie->ie_buffer, - pcust_chansw_ie->ie_length); - - if (data[1] != 0) { - pcust_chansw_ie->ie_length += - sizeof(IEEEtypes_ExtChanSwitchAnn_t); - ext_chan_switch = - (IEEEtypes_ExtChanSwitchAnn_t - *)(pcust_chansw_ie->ie_buffer + - sizeof(IEEEtypes_ChanSwitchAnn_t)); - ext_chan_switch->element_id = EXTEND_CHANNEL_SWITCH_ANN; - ext_chan_switch->len = 4; - ext_chan_switch->chan_switch_mode = data[0]; - ext_chan_switch->new_oper_class = data[1]; - ext_chan_switch->new_channel_num = data[2]; - ext_chan_switch->chan_switch_count = data[3]; + if (data[1]) { if (woal_check_valid_channel_operclass(priv, data[2], data[1])) { PRINTM(MERROR, "Wrong channel switch parameters!\n"); ret = -EINVAL; goto done; } - DBG_HEXDUMP(MCMD_D, "ECSA IE", - (t_u8 *)(pcust_chansw_ie->ie_buffer + - sizeof(IEEEtypes_ChanSwitchAnn_t)), - pcust_chansw_ie->ie_length - - sizeof(IEEEtypes_ChanSwitchAnn_t)); - } - /* bandwidth 40/80/160 should set channel switch wrapper ie for 11ac 5G - * channel*/ - if (data[4] && data[2] > 14) { - pChanSwWrap_ie = - (IEEEtypes_Header_t *)(pcust_chansw_ie->ie_buffer + - pcust_chansw_ie->ie_length); - pChanSwWrap_ie->element_id = EXT_POWER_CONSTR; - pChanSwWrap_ie->len = sizeof(IEEEtypes_WideBWChanSwitch_t); - - pbwchansw_ie = (IEEEtypes_WideBWChanSwitch_t - *)((t_u8 *)pChanSwWrap_ie + - sizeof(IEEEtypes_Header_t)); - pbwchansw_ie->ieee_hdr.element_id = BW_CHANNEL_SWITCH; - pbwchansw_ie->ieee_hdr.len = - sizeof(IEEEtypes_WideBWChanSwitch_t) - - sizeof(IEEEtypes_Header_t); - - center_freq_idx = woal_get_center_freq_idx(priv, BAND_AAC, - data[2], data[4]); - if (data[4] == CHANNEL_BW_40MHZ_ABOVE || - data[4] == CHANNEL_BW_40MHZ_BELOW) { - pbwchansw_ie->new_channel_width = 0; - pbwchansw_ie->new_channel_center_freq0 = - center_freq_idx; - } else if (data[4] == CHANNEL_BW_80MHZ) { - pbwchansw_ie->new_channel_width = 1; - pbwchansw_ie->new_channel_center_freq0 = - center_freq_idx - 4; - pbwchansw_ie->new_channel_center_freq1 = - center_freq_idx + 4; - } else if (data[4] == CHANNEL_BW_160MHZ) { - pbwchansw_ie->new_channel_width = 2; - pbwchansw_ie->new_channel_center_freq0 = - center_freq_idx - 8; - pbwchansw_ie->new_channel_center_freq1 = - center_freq_idx + 8; - } else - PRINTM(MERROR, - "Invalid bandwidth.Support value 1/3/4/5 for 40+/40-/80/160MHZ\n"); - - /*prepare the VHT Transmit Power Envelope IE*/ - pvhttpcEnv_ie = - (IEEEtypes_VhtTpcEnvelope_t - *)((t_u8 *)pChanSwWrap_ie + - sizeof(IEEEtypes_Header_t) + - sizeof(IEEEtypes_WideBWChanSwitch_t)); - pvhttpcEnv_ie->ieee_hdr.element_id = VHT_TX_POWER_ENV; - pvhttpcEnv_ie->ieee_hdr.len = - sizeof(IEEEtypes_VhtTpcEnvelope_t) - - sizeof(IEEEtypes_Header_t); - /* Local Max TX Power Count= 3, - * Local TX Power Unit Inter=EIP(0) */ - pvhttpcEnv_ie->tpc_info = 3; - pvhttpcEnv_ie->local_max_tp_20mhz = 0xff; - pvhttpcEnv_ie->local_max_tp_40mhz = 0xff; - pvhttpcEnv_ie->local_max_tp_80mhz = 0xff; - pChanSwWrap_ie->len += sizeof(IEEEtypes_VhtTpcEnvelope_t); - pcust_chansw_ie->ie_length += - pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t); - DBG_HEXDUMP(MCMD_D, "Channel switch wrapper IE", - (t_u8 *)pChanSwWrap_ie, - pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t)); - } - - if (data[0]) { - if (netif_carrier_ok(priv->netdev)) - netif_carrier_off(priv->netdev); - woal_stop_queue(priv->netdev); - priv->uap_tx_blocked = MTRUE; - } - - status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); - if (status != MLAN_STATUS_SUCCESS) { - PRINTM(MERROR, "Failed to set ECSA IE\n"); - ret = -EFAULT; - goto done; - } - - 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 * (data[3] + 2) * 110 / 1000); - - pcust_chansw_ie->ie_index = 0xffff; /*Auto index */ - pcust_chansw_ie->mgmt_subtype_mask = 0; - status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT); - if (status != MLAN_STATUS_SUCCESS) { - PRINTM(MERROR, "Failed to clear ECSA IE\n"); } + woal_channel_switch(priv, data[0], data[1], data[2], data[3], data[4], + MFALSE); done: - if (status != MLAN_STATUS_PENDING) - kfree(ioctl_req); - LEAVE(); return ret; } @@ -14727,6 +14856,11 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) MOAL_IOCTL_WAIT); len += strlen(CMD_NXP) + strlen(PRIV_CMD_11AXCMDCFG); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_RANGE_EXT, + strlen(PRIV_CMD_RANGE_EXT)) == 0) { + len = woal_setget_priv_range_ext(priv, buf, + priv_cmd.total_len); + goto handled; } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HTTXCFG, strlen(PRIV_CMD_HTTXCFG)) == 0) { /* Set/Get HT Tx configuration */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index 3630a2e2836e..df5172694e39 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -346,6 +346,8 @@ typedef struct _ssu_params_cfg { #define PRIV_CMD_11AXCFG "11axcfg" /** Private command: 11AX Cmd */ #define PRIV_CMD_11AXCMDCFG "11axcmd" +/** Private command: Range ext Cmd */ +#define PRIV_CMD_RANGE_EXT "range_ext" /** Private command: TWT Setup Cfg */ #define PRIV_CMD_TWT_SETUP "twt_setup" /** Private command: TWT Teardown Cfg */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index 98b7afa45ba2..796eb36e4041 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -88,6 +88,8 @@ static region_code_mapping_t region_code_mapping[] = { {"RU", 0x0f}, /* Russia */ {"IN", 0x06}, /* India */ {"MY", 0x06}, /* Malaysia */ + {"MX", 0x07}, /* Mexico */ + {"NE", 0x30}, /* New Zeland */ }; /** EEPROM Region code mapping table */ @@ -107,7 +109,7 @@ static t_u8 eu_country_code_table[][COUNTRY_CODE_LEN] = { "AL", "AD", "AT", "AU", "BY", "BE", "BA", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "MK", "DE", "GR", "HU", "IS", "IE", "IT", "KR", "LV", "LI", "LT", "LU", "MT", "MD", "MC", "ME", "NL", "NO", "PL", "RO", "RU", - "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB"}; + "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", "UA", "UK", "GB", "NE"}; /******************************************************** Global Variables diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h index 425f1b03f58a..60e667162341 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -1319,6 +1319,8 @@ struct _moal_private { t_u8 host_mlme; /** flag for auth */ t_u8 auth_flag; + /** flag for auth algorithm */ + t_u16 auth_alg; #endif #ifdef CONFIG_PROC_FS /** Proc entry */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c index f61c3fa327de..19a0e4a4e968 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c @@ -40,9 +40,11 @@ Change log: ********************************************************/ #define DRV_NAME "NXP mdriver PCIe" +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) static struct pm_qos_request woal_pcie_pm_qos_req; #endif +#endif /* PCIE resume handler */ static int woal_pcie_resume(struct pci_dev *pdev); @@ -1344,17 +1346,21 @@ mlan_status woal_pcie_bus_register(void) mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) pm_qos_add_request(&woal_pcie_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); #endif +#endif request_bus_freq(BUS_FREQ_HIGH); /* API registers the NXP PCIE driver */ if (pci_register_driver(&wlan_pcie)) { PRINTM(MFATAL, "PCIE Driver Registration Failed \n"); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) pm_qos_remove_request(&woal_pcie_pm_qos_req); #endif +#endif ret = MLAN_STATUS_FAILURE; } @@ -1374,9 +1380,11 @@ void woal_pcie_bus_unregister(void) release_bus_freq(BUS_FREQ_HIGH); /* PCIE Driver Unregistration */ pci_unregister_driver(&wlan_pcie); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) pm_qos_remove_request(&woal_pcie_pm_qos_req); #endif +#endif LEAVE(); } @@ -1480,7 +1488,7 @@ int woal_pcie_dump_reg_info(moal_handle *phandle, t_u8 *buffer) drv_ptr += sprintf(drv_ptr, "reg:0x%x value=0x%x\n", reg, value); - mdelay(100); + msleep(100); } drv_ptr += sprintf(drv_ptr, @@ -1619,7 +1627,7 @@ static void woal_pcie_reg_dbg(moal_handle *phandle) woal_pcie_read_reg(phandle, reg, &value); PRINTM(MERROR, "reg:0x%x value=0x%x\n", reg, value); - mdelay(100); + msleep(100); } PRINTM(MMSG, "Interface registers dump from offset 0x%x to 0x%x\n", dump_start_reg, dump_end_reg); @@ -1824,7 +1832,11 @@ rdwr_status woal_pcie_rdwr_firmware(moal_handle *phandle, t_u8 doneflag) return RDWR_STATUS_FAILURE; } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + usleep_range(99, 100); +#else udelay(100); +#endif } if (ctrl_data == debug_host_ready) { PRINTM(MERROR, "Fail to pull ctrl_data\n"); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c index a18c7cfbf1b9..72f0e994ef5e 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -1655,6 +1655,7 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) priv->auth_flag = 0; priv->host_mlme = MFALSE; + priv->auth_alg = 0xFFFF; #endif #endif #ifdef STA_WEXT @@ -2413,6 +2414,7 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) (priv->auth_flag & HOST_MLME_AUTH_PENDING)) { priv->auth_flag = 0; priv->host_mlme = MFALSE; + priv->auth_alg = 0xFFFF; } priv->phandle->remain_on_channel = MFALSE; if (priv->phandle->cookie && @@ -2624,30 +2626,35 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) ((struct ieee80211_mgmt *) pkt) ->frame_control)) { + PRINTM(MEVENT, + "HostMlme %s: Received auth frame type = 0x%x\n", + priv->netdev->name, + priv->auth_alg); + if (priv->auth_flag & HOST_MLME_AUTH_PENDING) { - PRINTM(MEVENT, - "HostMlme %s: Receive auth\n", - priv->netdev - ->name); - priv->auth_flag &= - ~HOST_MLME_AUTH_PENDING; - priv->auth_flag |= - HOST_MLME_AUTH_DONE; - priv->phandle - ->host_mlme_priv = - priv; - queue_work( + if (priv->auth_alg != + WLAN_AUTH_SAE) { + priv->auth_flag &= + ~HOST_MLME_AUTH_PENDING; + priv->auth_flag |= + HOST_MLME_AUTH_DONE; priv->phandle - ->evt_workqueue, - &priv->phandle - ->host_mlme_work); + ->host_mlme_priv = + priv; + queue_work( + priv->phandle + ->evt_workqueue, + &priv->phandle + ->host_mlme_work); + } } else { PRINTM(MERROR, - "HostMlme %s: Drop auth pkt,auth_flag=0x%x\n", + "HostMlme %s: Drop auth frame, auth_flag=0x%x auth_alg=0x%x\n", priv->netdev ->name, - priv->auth_flag); + priv->auth_flag, + priv->auth_alg); break; } } else { @@ -2665,6 +2672,7 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) MFALSE); priv->host_mlme = MFALSE; priv->auth_flag = 0; + priv->auth_alg = 0xFFFF; if (!priv->wdev->current_bss) { PRINTM(MEVENT, "HostMlme: Drop deauth/disassociate, we already disconnected\n"); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index 98f71fa5b052..547c1eb6f918 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -1867,11 +1867,13 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, } kfree(ssid_bssid); - if (priv->auth_flag & HOST_MLME_AUTH_PENDING) { + if ((priv->auth_alg != WLAN_AUTH_SAE) && + (priv->auth_flag & HOST_MLME_AUTH_PENDING)) { PRINTM(MERROR, "pending auth on going\n"); LEAVE(); return -EBUSY; } + /** cancel pending scan */ woal_cancel_scan(priv, MOAL_IOCTL_WAIT); @@ -1903,9 +1905,11 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, #endif /*enable auth register frame*/ - woal_mgmt_frame_register(priv, IEEE80211_STYPE_AUTH, MTRUE); - woal_mgmt_frame_register(priv, IEEE80211_STYPE_DEAUTH, MTRUE); - woal_mgmt_frame_register(priv, IEEE80211_STYPE_DISASSOC, MTRUE); + if (priv->auth_flag == 0) { + woal_mgmt_frame_register(priv, IEEE80211_STYPE_AUTH, MTRUE); + woal_mgmt_frame_register(priv, IEEE80211_STYPE_DEAUTH, MTRUE); + woal_mgmt_frame_register(priv, IEEE80211_STYPE_DISASSOC, MTRUE); + } #define HEADER_SIZE 8 // frmctl + durationid + addr1 + addr2 + addr3 + seqctl + addr4 @@ -1988,23 +1992,25 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, } #define AUTH_TX_DEFAULT_WAIT_TIME 1200 - if (woal_cfg80211_remain_on_channel_cfg( - priv, MOAL_IOCTL_WAIT, MFALSE, (t_u8 *)&status, - req->bss->channel, 0, AUTH_TX_DEFAULT_WAIT_TIME)) { - PRINTM(MERROR, "Fail to configure remain on channel\n"); - ret = -EFAULT; - goto done; - } - if (status == MLAN_STATUS_SUCCESS) { - priv->phandle->remain_on_channel = MTRUE; - moal_memcpy_ext(priv->phandle, &(priv->phandle->chan), - req->bss->channel, - sizeof(struct ieee80211_channel), - sizeof(priv->phandle->chan)); - } else { - PRINTM(MERROR, - "HostMlme %s: Set remain on Channel: with status=%d\n", - dev->name, status); + if (priv->auth_flag == 0) { + if (woal_cfg80211_remain_on_channel_cfg( + priv, MOAL_IOCTL_WAIT, MFALSE, (t_u8 *)&status, + req->bss->channel, 0, AUTH_TX_DEFAULT_WAIT_TIME)) { + PRINTM(MERROR, "Fail to configure remain on channel\n"); + ret = -EFAULT; + goto done; + } + if (status == MLAN_STATUS_SUCCESS) { + priv->phandle->remain_on_channel = MTRUE; + moal_memcpy_ext(priv->phandle, &(priv->phandle->chan), + req->bss->channel, + sizeof(struct ieee80211_channel), + sizeof(priv->phandle->chan)); + } else { + PRINTM(MERROR, + "HostMlme %s: Set remain on Channel: with status=%d\n", + dev->name, status); + } } pmbuf->data_offset = MLAN_MIN_DATA_HEADER_LEN; @@ -2092,6 +2098,8 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, priv->host_mlme = MTRUE; priv->auth_flag = HOST_MLME_AUTH_PENDING; + priv->auth_alg = cpu_to_le16(auth_alg); + PRINTM(MCMND, "wlan: HostMlme %s send auth to bssid " MACSTR "\n", dev->name, MAC2STR(req->bss->bssid)); DBG_HEXDUMP(MDAT_D, "Auth:", pmbuf->pbuf + pmbuf->data_offset, @@ -2111,6 +2119,9 @@ static int woal_cfg80211_authenticate(struct wiphy *wiphy, case MLAN_STATUS_FAILURE: default: woal_free_mlan_buffer(priv->phandle, pmbuf); + priv->host_mlme = MFALSE; + priv->auth_flag = 0; + priv->auth_alg = 0xFFFF; ret = -EFAULT; break; } @@ -2321,9 +2332,30 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, const u8 *ssid_ie; int wpa_enabled = 0, group_enc_mode = 0, pairwise_enc_mode = 0; mlan_bss_info bss_info; + mlan_status status = MLAN_STATUS_SUCCESS; ENTER(); + if (priv->auth_alg == WLAN_AUTH_SAE) { + priv->auth_flag = HOST_MLME_AUTH_DONE; + + woal_mgmt_frame_register(priv, IEEE80211_STYPE_AUTH, MFALSE); + PRINTM(MINFO, "wlan: HostMlme %s auth exchange successful\n", + priv->netdev->name); + + if (priv->phandle->remain_on_channel) { + if (woal_cfg80211_remain_on_channel_cfg( + priv, MOAL_IOCTL_WAIT, MTRUE, + (t_u8 *)&status, NULL, 0, 0)) { + PRINTM(MERROR, + "Failed to cancel remain on channel\n"); + ret = -EFAULT; + goto done; + } + priv->phandle->remain_on_channel = MFALSE; + } + } + if (priv->auth_flag && !(priv->auth_flag & HOST_MLME_AUTH_DONE)) { LEAVE(); return -EBUSY; @@ -2331,6 +2363,7 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, priv->cfg_connect = MTRUE; priv->assoc_status = 0; + priv->auth_alg = 0xFFFF; memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); @@ -2414,7 +2447,6 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, goto done; } ssid_bssid.host_mlme = priv->host_mlme; - ssid_bssid.use_mfp = req->use_mfp; if (req->bss->channel) { ssid_bssid.channel_flags = req->bss->channel->flags; @@ -2860,10 +2892,6 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, ssid_bssid.channel_flags |= CHAN_FLAGS_MAX; PRINTM(MCMND, "channel flags=0x%x\n", channel->flags); } -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) - if (conn_param) - ssid_bssid.use_mfp = conn_param->mfp; -#endif if (MLAN_STATUS_SUCCESS != woal_bss_start(priv, MOAL_IOCTL_WAIT_TIMEOUT, &ssid_bssid)) { ret = -EFAULT; @@ -4875,6 +4903,7 @@ static int woal_cfg80211_deauthenticate(struct wiphy *wiphy, if (priv->host_mlme) { priv->host_mlme = MFALSE; priv->auth_flag = 0; + priv->auth_alg = 0xFFFF; /*send deauth packet to notify disconnection to wpa_supplicant */ woal_deauth_event(priv, req->reason_code); @@ -4913,6 +4942,7 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy, if (priv->host_mlme) { priv->host_mlme = MFALSE; priv->auth_flag = 0; + priv->auth_alg = 0xFFFF; /*send deauth packet to notify disconnection to wpa_supplicant */ woal_deauth_event(priv, req->reason_code); |