diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index c3742f5..c599de9 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -49,7 +49,7 @@ CONFIG_SD8801=y CONFIG_USB8801=n CONFIG_USB9097=n CONFIG_PCIE9097=n -CONFIG_SD9098=n +CONFIG_SD9098=y CONFIG_USB9098=n CONFIG_PCIE9098=y diff --git a/mxm_wifiex/wlan_src/README_MLAN b/mxm_wifiex/wlan_src/README_MLAN index 03860b6..f532e2d 100644 --- a/mxm_wifiex/wlan_src/README_MLAN +++ b/mxm_wifiex/wlan_src/README_MLAN @@ -9,7 +9,7 @@ Goto source code directory wlan_src/. make [clean] build The driver and utility binaries can be found in ../bin_xxxx directory. - The driver code supports Linux kernel from 2.6.32 to 5.13.4. + The driver code supports Linux kernel from 2.6.32 to 5.15. 2) FOR DRIVER INSTALL @@ -51,6 +51,8 @@ auto_ds=0|1|2 ext_scan=0|1|2 net_rx=0|1 + amsdu_deaggr=0|1 + ps_mode=0|1|2 sched_scan=0|1 max_tx_buf=2048|4096|8192 @@ -60,6 +62,7 @@ dts_enable=0|1 fw_name = e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin + hw_name = hw_test=0|1 fw_serial=0|1 req_fw_nowait=0|1 diff --git a/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V3_9177.conf b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V3_9177.conf new file mode 100644 index 0000000..e746855 --- /dev/null +++ b/mxm_wifiex/wlan_src/mapp/mlanconfig/config/ed_mac_ctrl_V3_9177.conf @@ -0,0 +1,23 @@ +# File : ed_mac_ctrl_V3_9177.conf +# +# ed_mac_ctrl_v3 is used for W9177 +# ./mlanutl mlan0 hostcmd config/ed_mac_ctrl_V3_9177.conf ed_mac_ctrl_v3 +# +## Set Energy Detect Threshold for EU Adaptivity test + +ed_mac_ctrl_v3={ + CmdCode=0x0130 #Command code, DO NOT change this line + ed_ctrl_2g.enable:2=0x1 # 0 - disable EU adaptivity for 2.4GHz band + # 1 - enable EU adaptivity for 2.4GHz band + + ed_ctrl_2g.offset:2=0xA # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_5g.enable:2=0x1 # 0 - disable EU adaptivity for 5GHz band + # 1 - enable EU adaptivity for 5GHz band + + ed_ctrl_5g.offset:2=0xA # 0 - Default Energy Detect threshold + #offset value range: 0x80 to 0x7F + + ed_ctrl_txq_lock:4=0x1e00FF #DO NOT Change this line +} diff --git a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c index 8cee774..cf7140d 100644 --- a/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c +++ b/mxm_wifiex/wlan_src/mapp/mlanutl/mlanutl.c @@ -56,6 +56,16 @@ int terminate_flag = 0; Local Variables ********************************************************/ +#define BAND_B (1U << 0) +#define BAND_G (1U << 1) +#define BAND_A (1U << 2) +#define BAND_GN (1U << 3) +#define BAND_AN (1U << 4) +#define BAND_GAC (1U << 5) +#define BAND_AAC (1U << 6) +#define BAND_GAX (1U << 8) +#define BAND_AAX (1U << 9) + /** Stringification of rateId enumeration */ const char *rateIdStr[] = {"1", "2", "5.5", "11", "--", "6", "9", "12", "18", "24", "36", "48", "54", "--", "M0", "M1", diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11d.c b/mxm_wifiex/wlan_src/mlan/mlan_11d.c index a3ef84e..2ffc34e 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11d.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11d.c @@ -119,7 +119,10 @@ static chan_freq_power_t channel_freq_power_UN_AJ[] = { {153, 5765, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, {157, 5785, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, {161, 5805, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, - {165, 5825, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}} + {165, 5825, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {169, 5845, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {173, 5865, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}}, + {177, 5885, TX_PWR_DEFAULT, MFALSE, {0x10, 0, 0}} /* {240, 4920, TX_PWR_DEFAULT}, {244, 4940, TX_PWR_DEFAULT}, {248, 4960, TX_PWR_DEFAULT}, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11h.c b/mxm_wifiex/wlan_src/mlan/mlan_11h.c index bf68c99..5725e39 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11h.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11h.c @@ -118,6 +118,8 @@ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band_1 = { /** U-NII sub-band config : Start Channel = 149, NumChans = 5 */ static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_upper_band = {149, 5}; +/** U-NII sub-band config : Start Channel = 169, NumChans = 3 */ +static const IEEEtypes_SupportChan_Subband_t wlan_11h_unii_4_band = {169, 3}; /** Internally passed structure used to send a CMD_802_11_TPC_INFO command */ typedef struct { @@ -352,6 +354,17 @@ wlan_11h_set_supp_channels_ie(mlan_private *priv, t_u8 band, */ switch (cfp_a) { case 0x10: /* USA FCC */ + psup_chan->subband[num_subbands++] = + wlan_11h_unii_lower_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_middle_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_mid_upper_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_upper_band; + psup_chan->subband[num_subbands++] = + wlan_11h_unii_4_band; + break; case 0x20: /* Canada IC */ case 0x30: /* Europe ETSI */ default: @@ -1338,19 +1351,24 @@ wlan_11h_prepare_custom_ie_chansw(mlan_adapter *pmadapter, * @brief Check if start channel 165 is allowed to operate in * previous uAP channel's band config * + * @param priv a pointer to mlan_private structure * @param start_chn Random Start channel choosen after radar detection * @param uap_band_cfg Private driver uAP band configuration information * structure * * @return MFALSE if the channel is not allowed in given band */ -static t_bool wlan_11h_is_band_valid(t_u8 start_chn, Band_Config_t uap_band_cfg) +static t_bool wlan_11h_is_band_valid(mlan_private *priv, t_u8 start_chn, + Band_Config_t uap_band_cfg) { /* if band width is not 20MHZ (either 40 or 80MHz) * return MFALSE, 165 is not allowed in bands other than 20MHZ */ - if (start_chn == 165 && (uap_band_cfg.chanWidth != CHAN_BW_20MHZ)) { - return MFALSE; + if (start_chn == 165) { + if (priv->adapter->region_code == COUNTRY_CODE_US) + return MTRUE; + if (uap_band_cfg.chanWidth != CHAN_BW_20MHZ) + return MFALSE; } return MTRUE; } @@ -1445,7 +1463,7 @@ static t_u8 wlan_11h_get_uap_start_channel(mlan_private *priv, wlan_11h_radar_detect_required( priv, start_chn)) || !(wlan_11h_is_band_valid( - start_chn, + priv, start_chn, uap_band_cfg)))) && (++rand_tries < chn_tbl->num_cfp)) { @@ -2963,6 +2981,7 @@ mlan_status wlan_11h_ioctl_get_channel_nop_info(pmlan_adapter pmadapter, if (ch_nop_info->chan_width == CHAN_BW_80MHZ || ch_nop_info->chan_width == CHAN_BW_40MHZ) wlan_11h_update_bandcfg( + pmpriv, &ch_nop_info->new_chan.bandcfg, ch_nop_info->new_chan.channel); if (ch_nop_info->chan_width == CHAN_BW_80MHZ) @@ -3166,7 +3185,6 @@ mlan_status wlan_11h_handle_event_chanrpt_ready(mlan_private *priv, priv->adapter->pmoal_handle, &sec, &usec); pstate_dfs->dfs_report_time_sec = sec; pstate_dfs->dfs_check_pending = MFALSE; - pstate_dfs->dfs_check_priv = MNULL; LEAVE(); return ret; @@ -3326,7 +3344,8 @@ void wlan_dfs_rep_bw_change(mlan_adapter *pmadapter) * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE or MLAN_STATUS_PENDING */ -void wlan_11h_update_bandcfg(Band_Config_t *uap_band_cfg, t_u8 new_channel) +void wlan_11h_update_bandcfg(mlan_private *pmpriv, Band_Config_t *uap_band_cfg, + t_u8 new_channel) { t_u8 chan_offset; ENTER(); @@ -3335,7 +3354,7 @@ void wlan_11h_update_bandcfg(Band_Config_t *uap_band_cfg, t_u8 new_channel) * Clear the channel bandwidth for 20MHz * since channel switch could be happening from 40/80MHz to 20MHz */ - chan_offset = wlan_get_second_channel_offset(new_channel); + chan_offset = wlan_get_second_channel_offset(pmpriv, new_channel); uap_band_cfg->chan2Offset = chan_offset; if (!chan_offset) { /* 40MHz/80MHz */ @@ -3897,7 +3916,7 @@ mlan_status wlan_11h_radar_detected_handling(mlan_adapter *pmadapter, /* DFS only in 5GHz */ wlan_11h_update_bandcfg( - &pstate_rdh->uap_band_cfg, + pmpriv, &pstate_rdh->uap_band_cfg, pstate_rdh->new_channel); PRINTM(MCMD_D, "RDH_SET_NEW_CHANNEL: uAP band config = 0x%x channel=%d\n", @@ -4115,7 +4134,8 @@ mlan_status wlan_11h_dfs_event_preprocessing(mlan_adapter *pmadapter) pmpriv = priv_list[0]; PRINTM(MINFO, "%s: found dfs_slave priv=%p\n", __func__, pmpriv); - } else if (pmadapter->state_dfs.dfs_check_pending) { + } else if (pmadapter->state_dfs.dfs_check_pending || + pmadapter->state_dfs.dfs_check_channel) { pmpriv = (mlan_private *)(pmadapter->state_dfs .dfs_check_priv); PRINTM(MINFO, "%s: found dfs priv=%p\n", __func__, diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11h.h b/mxm_wifiex/wlan_src/mlan/mlan_11h.h index 37a48c0..eecca8d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11h.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11h.h @@ -192,7 +192,8 @@ extern mlan_status wlan_11h_dfs_event_preprocessing(mlan_adapter *pmadapter); /** DFS switch to non-DFS channel */ extern mlan_status wlan_11h_switch_non_dfs_chan(mlan_private *priv, t_u8 *chan); -extern void wlan_11h_update_bandcfg(Band_Config_t *uap_band_cfg, +extern void wlan_11h_update_bandcfg(mlan_private *pmpriv, + Band_Config_t *uap_band_cfg, t_u8 new_channel); /** function checks if interface is active. **/ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n.c b/mxm_wifiex/wlan_src/mlan/mlan_11n.c index a9a42d8..cfbd7af 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n.c @@ -2289,10 +2289,14 @@ mlan_status wlan_ret_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, * @param chan channel num * @return second channel offset */ -t_u8 wlan_get_second_channel_offset(int chan) +t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan) { t_u8 chan2Offset = SEC_CHAN_NONE; + /* Special Case: 20Mhz-only Channel */ + if (priv->adapter->region_code != COUNTRY_CODE_US && chan == 165) + return chan2Offset; + switch (chan) { case 36: case 44: @@ -2306,6 +2310,8 @@ t_u8 wlan_get_second_channel_offset(int chan) case 140: case 149: case 157: + case 165: + case 173: chan2Offset = SEC_CHAN_ABOVE; break; case 40: @@ -2320,12 +2326,10 @@ t_u8 wlan_get_second_channel_offset(int chan) case 144: case 153: case 161: + case 169: + case 177: chan2Offset = SEC_CHAN_BELOW; break; - case 165: - /* Special Case: 20Mhz-only Channel */ - chan2Offset = SEC_CHAN_NONE; - break; } return chan2Offset; } @@ -2371,7 +2375,8 @@ t_u8 wlan_validate_chan_offset(mlan_private *pmpriv, t_u16 band, t_u32 chan, if ((chan == 8) || (chan == 9)) chan_offset = SEC_CHAN_BELOW; } else if (band & BAND_AN) - chan_offset = wlan_get_second_channel_offset(chan); + chan_offset = + wlan_get_second_channel_offset(pmpriv, chan); } return chan_offset; } diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n.h b/mxm_wifiex/wlan_src/mlan/mlan_11n.h index af382b1..15b3e5d 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n.h @@ -123,7 +123,7 @@ mlan_status wlan_cmd_amsdu_aggr_ctrl(mlan_private *priv, t_u8 wlan_validate_chan_offset(mlan_private *pmpriv, t_u16 band, t_u32 chan, t_u8 chan_bw); /** get channel offset */ -t_u8 wlan_get_second_channel_offset(int chan); +t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan); void wlan_update_11n_cap(mlan_private *pmpriv); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c b/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c index af501f0..5560449 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c @@ -234,7 +234,6 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) t_u32 out_ts_sec, out_ts_usec; t_u32 in_copy_ts_sec, in_copy_ts_usec; t_u32 out_copy_ts_sec, out_copy_ts_usec; - pmlan_callbacks pcb = &pmadapter->callbacks; t_u32 copy_delay = 0; t_u32 delay = 0; @@ -268,8 +267,8 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) goto done; } if (pmadapter->tp_state_on) - pcb->moal_get_system_time(pmadapter->pmoal_handle, &in_ts_sec, - &in_ts_usec); + pmadapter->callbacks.moal_get_system_time( + pmadapter->pmoal_handle, &in_ts_sec, &in_ts_usec); pmbuf->use_count = wlan_11n_get_num_aggrpkts(data, total_pkt_len); // rx_trace 7 @@ -281,7 +280,20 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) } if (pmadapter->tp_state_drop_point == 7 /*RX_DROP_P3*/) goto done; - + prx_pkt = (RxPacketHdr_t *)data; + if (pmbuf->pdesc && !memcmp(pmadapter, prx_pkt->eth803_hdr.dest_addr, + priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) { + if (pmadapter->callbacks.moal_recv_amsdu_packet) { + ret = pmadapter->callbacks.moal_recv_amsdu_packet( + pmadapter->pmoal_handle, pmbuf); + if (ret == MLAN_STATUS_PENDING) { + priv->msdu_in_rx_amsdu_cnt += pmbuf->use_count; + priv->amsdu_rx_cnt++; + return ret; + } + goto done; + } + } while (total_pkt_len >= hdr_len) { prx_pkt = (RxPacketHdr_t *)data; /* Length will be in network format, change it to host */ @@ -331,16 +343,16 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) daggr_mbuf->pparent = pmbuf; daggr_mbuf->priority = pmbuf->priority; if (pmadapter->tp_state_on) - pcb->moal_get_system_time(pmadapter->pmoal_handle, - &in_copy_ts_sec, - &in_copy_ts_usec); + pmadapter->callbacks.moal_get_system_time( + pmadapter->pmoal_handle, &in_copy_ts_sec, + &in_copy_ts_usec); memcpy_ext(pmadapter, daggr_mbuf->pbuf + daggr_mbuf->data_offset, data, pkt_len, daggr_mbuf->data_len); if (pmadapter->tp_state_on) { - pcb->moal_get_system_time(pmadapter->pmoal_handle, - &out_copy_ts_sec, - &out_copy_ts_usec); + pmadapter->callbacks.moal_get_system_time( + pmadapter->pmoal_handle, &out_copy_ts_sec, + &out_copy_ts_usec); copy_delay += (t_s32)(out_copy_ts_sec - in_copy_ts_sec) * 1000000; @@ -408,8 +420,8 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) data += pkt_len + pad; } if (pmadapter->tp_state_on) { - pcb->moal_get_system_time(pmadapter->pmoal_handle, &out_ts_sec, - &out_ts_usec); + pmadapter->callbacks.moal_get_system_time( + pmadapter->pmoal_handle, &out_ts_sec, &out_ts_usec); delay += (t_s32)(out_ts_sec - in_ts_sec) * 1000000; delay += (t_s32)(out_ts_usec - in_ts_usec); pmadapter->callbacks.moal_amsdu_tp_accounting( diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c index e9f6a89..3823b49 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cfp.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cfp.c @@ -340,7 +340,10 @@ static chan_freq_power_t channel_freq_power_A[] = { {153, 5765, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, {157, 5785, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, {161, 5805, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, - {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}}; + {165, 5825, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {169, 5845, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {173, 5865, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}, + {177, 5885, WLAN_TX_PWR_US_DEFAULT, MFALSE, {0x10, 0, 0}}}; /** Band: 'A', Region: Canada IC */ static chan_freq_power_t channel_freq_power_CAN_A[] = { diff --git a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c index 6b9d127..b78d9ea 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c @@ -173,6 +173,8 @@ static t_void wlan_queue_cmd(mlan_private *pmpriv, cmd_ctrl_node *pcmd_node, if (pmpriv->adapter->scan_processing && pmpriv->adapter->ext_scan_type == EXT_SCAN_ENHANCE) { if (MFALSE == wlan_is_cmd_allowed_during_scan(cmd_no)) { + PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x scan_pending_q\n", + cmd_no); wlan_queue_scan_cmd(pmpriv, pcmd_node); return; } @@ -2248,6 +2250,7 @@ mlan_status wlan_process_cmdresp(mlan_adapter *pmadapter) #ifdef STA_SUPPORT if (pmadapter->pwarm_reset_ioctl_req) { /* warm reset complete */ + PRINTM(MMSG, "wlan: warm reset complete\n"); pmadapter->hw_status = WlanHardwareStatusReady; pcb->moal_ioctl_complete( pmadapter->pmoal_handle, @@ -2372,7 +2375,10 @@ exit: t_void wlan_flush_scan_queue(pmlan_adapter pmadapter) { cmd_ctrl_node *pcmd_node = MNULL; - + mlan_ioctl_req *pioctl_buf = MNULL; + HostCmd_DS_COMMAND *pcmd = MNULL; + t_u16 cmd_no = 0; + pmlan_callbacks pcb = &pmadapter->callbacks; ENTER(); wlan_request_cmd_lock(pmadapter); @@ -2382,7 +2388,20 @@ t_void wlan_flush_scan_queue(pmlan_adapter pmadapter) util_unlink_list(pmadapter->pmoal_handle, &pmadapter->scan_pending_q, (pmlan_linked_list)pcmd_node, MNULL, MNULL); - pcmd_node->pioctl_buf = MNULL; + pcmd = (HostCmd_DS_COMMAND *)(pcmd_node->cmdbuf->pbuf + + pcmd_node->cmdbuf->data_offset); + cmd_no = wlan_le16_to_cpu(pcmd->command); + PRINTM(MCMND, "flush scan queue: cmd 0x%02x\n", cmd_no); + if (pcmd_node->pioctl_buf && + cmd_no != HostCmd_CMD_802_11_SCAN && + cmd_no != HostCmd_CMD_802_11_SCAN_EXT) { + pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf; + pcmd_node->pioctl_buf = MNULL; + pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL; + pcb->moal_ioctl_complete(pmadapter->pmoal_handle, + pioctl_buf, + MLAN_STATUS_FAILURE); + } wlan_insert_cmd_to_free_q(pmadapter, pcmd_node); } diff --git a/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/mxm_wifiex/wlan_src/mlan/mlan_decl.h index 9812046..00cf3f0 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 "283.p2" +#define MLAN_RELEASE_VERSION "293" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -138,6 +138,9 @@ typedef t_s32 t_sval; /** NET IP alignment */ #define MLAN_NET_IP_ALIGN 2 +/** US country code */ +#define COUNTRY_CODE_US 0x10 + /** DMA alignment */ /* SDIO3.0 Inrevium Adapter require 32 bit DMA alignment */ #define DMA_ALIGNMENT 32 @@ -1916,6 +1919,9 @@ typedef struct _mlan_callbacks { t_u32 port, mlan_status status); /** moal_recv_packet */ mlan_status (*moal_recv_packet)(t_void *pmoal, pmlan_buffer pmbuf); + /** moal_recv_amsdu_packet */ + mlan_status (*moal_recv_amsdu_packet)(t_void *pmoal, + pmlan_buffer pmbuf); /** moal_recv_event */ mlan_status (*moal_recv_event)(t_void *pmoal, pmlan_event pmevent); /** moal_ioctl_complete */ @@ -2234,6 +2240,9 @@ MLAN_API mlan_status mlan_recv_packet_complete(t_void *padapter, pmlan_buffer pmbuf, mlan_status status); +/** handle amsdu deaggregated packet */ +void mlan_process_deaggr_pkt(t_void *padapter, pmlan_buffer pmbuf, t_u8 *drop); + #if defined(SDIO) || defined(PCIE) /** interrupt handler */ MLAN_API mlan_status mlan_interrupt(t_u16 msg_id, t_void *padapter); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/mxm_wifiex/wlan_src/mlan/mlan_fw.h index 1308a1f..af95fc3 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -406,6 +406,9 @@ typedef enum _WLAN_802_11_WEP_STATUS { #define TLV_TYPE_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 0x3c) /* 0x013c */ /** TLV type : SAE Password */ #define TLV_TYPE_SAE_PASSWORD (PROPRIETARY_TLV_BASE_ID + 0x141) /* 0x0241 */ +/** TLV type : SAE PWE Derivation Mode */ +#define TLV_TYPE_WPA3_SAE_PWE_DERIVATION_MODE \ + (PROPRIETARY_TLV_BASE_ID + 339) /* 0x0100 + 0x153 */ /** TLV type : Encryption Protocol TLV */ #define TLV_TYPE_ENCRYPTION_PROTO \ (PROPRIETARY_TLV_BASE_ID + 0x40) /* 0x0140 \ @@ -5480,6 +5483,17 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_SAE_Password_t { char sae_password[1]; } MLAN_PACK_END MrvlIEtypes_SAE_Password_t; +/** MrvlIEtypes_SAE_PWE_Mode_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_SAE_PWE_Mode_t { + /** Header */ + MrvlIEtypesHeader_t header; + /** WPA3 SAE mechanism for PWE derivation */ + char pwe[1]; +} MLAN_PACK_END MrvlIEtypes_SAE_PWE_Mode_t; + +/** SAE H2E capability bit in RSNX */ +#define SAE_H2E_BIT 5 + /* rsnMode - * Bit 0 : No RSN * Bit 1-2 : RFU @@ -6203,6 +6217,18 @@ typedef MLAN_PACK_START struct _MrvlIEtypes_uap_max_sta_cnt_t { t_u16 uap_max_sta; } MLAN_PACK_END MrvlIEtypes_uap_max_sta_cnt_t; +#define MRVL_ACTION_CHAN_SWITCH_ANNOUNCE (PROPRIETARY_TLV_BASE_ID + 0x341) + +/** MrvlIEtypes_uap_chan_switch */ +typedef MLAN_PACK_START struct _MrvlIEtypes_action_chan_switch_t { + /** Header */ + MrvlIEtypesHeader_t header; + /* 0 send broadcast CSA action frame, 1 send unicast CSA action frame */ + t_u32 mode; + /**ie buf*/ + t_u8 ie_buf[]; +} MLAN_PACK_END MrvlIEtypes_action_chan_switch_t; + /** MrvlIEtypes_sta_ageout_t */ typedef MLAN_PACK_START struct _MrvlIEtypes_sta_ageout_t { /** Header */ diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h index 329aa77..e64d4b7 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ieee.h @@ -1321,7 +1321,7 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END IEEEtypes_ExtChanSwitchAnn_t; /** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */ -#define WLAN_11H_MAX_SUBBANDS 5 +#define WLAN_11H_MAX_SUBBANDS 6 /** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */ #define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25 @@ -1976,6 +1976,10 @@ typedef struct _BSSDescriptor_t { IEEEtypes_Generic_t *prsn_ie; /** RSN IE offset in the beacon buffer */ t_u16 rsn_offset; + /** RSNX IE */ + IEEEtypes_Generic_t *prsnx_ie; + /** RSNX IE offset in the beacon buffer */ + t_u16 rsnx_offset; #ifdef STA_SUPPORT /** WAPI IE */ IEEEtypes_Generic_t *pwapi_ie; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_init.c b/mxm_wifiex/wlan_src/mlan/mlan_init.c index 15f6406..4b1319a 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_init.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_init.c @@ -240,9 +240,10 @@ mlan_status wlan_allocate_adapter(pmlan_adapter pmadapter) t_u32 buf_size; BSSDescriptor_t *ptemp_scan_table = MNULL; t_u8 chan_2g[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - t_u8 chan_5g[] = {12, 16, 34, 38, 42, 46, 36, 40, 44, 48, 52, - 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, - 132, 136, 140, 144, 149, 153, 157, 161, 165}; + t_u8 chan_5g[] = {12, 16, 34, 38, 42, 46, 36, 40, 44, + 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128, 132, 136, 140, 144, 149, + 153, 157, 161, 165, 169, 173, 177}; #endif #ifdef SDIO t_u32 max_mp_regs = 0; diff --git a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index 0aa139c..31a8bac 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -86,6 +86,9 @@ enum _mlan_ioctl_req_id { #endif MLAN_OID_BSS_FIND_BSSID = 0x0002001D, +#ifdef UAP_SUPPORT + MLAN_OID_ACTION_CHAN_SWITCH = 0x0002001E, +#endif /* Radio Configuration Group */ MLAN_IOCTL_RADIO_CFG = 0x00030000, @@ -627,7 +630,7 @@ typedef struct _mlan_multicast_list { } mlan_multicast_list, *pmlan_multicast_list; /** Max channel */ -#define MLAN_MAX_CHANNEL 165 +#define MLAN_MAX_CHANNEL 177 /** Maximum number of channels in table */ #define MLAN_MAX_CHANNEL_NUM 128 @@ -1119,6 +1122,20 @@ typedef struct _mlan_uap_scan_channels { scan_chan_list chan_list[MLAN_MAX_CHANNEL]; } mlan_uap_scan_channels; +/** mlan_chan_switch_param */ +typedef struct _mlan_action_chan_switch { + /** mode*/ + t_u8 mode; + /** switch mode*/ + t_u8 chan_switch_mode; + /** oper class*/ + t_u8 new_oper_class; + /** new channel */ + t_u8 new_channel_num; + /** chan_switch_count */ + t_u8 chan_switch_count; +} mlan_action_chan_switch; + /** mlan_uap_oper_ctrl */ typedef struct _mlan_uap_oper_ctrl { /** control value @@ -1232,6 +1249,8 @@ typedef struct _mlan_ds_bss { wmm_parameter_t ap_wmm_para; /** ap scan channels for MLAN_OID_UAP_SCAN_CHANNELS*/ mlan_uap_scan_channels ap_scan_channels; + /** channel switch for MLAN_OID_UAP_CHAN_SWITCH */ + mlan_action_chan_switch chanswitch; /** ap channel for MLAN_OID_UAP_CHANNEL*/ chan_band_info ap_channel; /** ap operation control for MLAN_OID_UAP_OPER_CTRL*/ @@ -2449,8 +2468,6 @@ typedef struct _sta_info_data { sta_stats stats; /** ie length */ t_u16 ie_len; - /** ie buffer */ - t_u8 ie_buf[1]; } sta_info_data; /** mlan_ds_sta_list structure for MLAN_OID_UAP_STA_LIST */ @@ -2459,6 +2476,7 @@ typedef struct _mlan_ds_sta_list { t_u16 sta_count; /** station list */ sta_info_data info[MAX_NUM_CLIENTS]; + /* ie_buf will be append at the end */ } mlan_ds_sta_list, *pmlan_ds_sta_list; #endif diff --git a/mxm_wifiex/wlan_src/mlan/mlan_join.c b/mxm_wifiex/wlan_src/mlan/mlan_join.c index 4a1377d..1fb6293 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_join.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_join.c @@ -869,7 +869,7 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, MrvlIEtypes_PhyParamSet_t *pphy_tlv; MrvlIEtypes_SsParamSet_t *pss_tlv; MrvlIEtypes_RatesParamSet_t *prates_tlv; - MrvlIEtypes_AuthType_t *pauth_tlv; + MrvlIEtypes_AuthType_t *pauth_tlv = MNULL; MrvlIEtypes_RsnParamSet_t *prsn_ie_tlv = MNULL; MrvlIEtypes_SecurityCfg_t *psecurity_cfg_ie = MNULL; MrvlIEtypes_ChanListParamSet_t *pchan_tlv; @@ -983,6 +983,27 @@ mlan_status wlan_cmd_802_11_associate(mlan_private *pmpriv, pauth_tlv->header.len = wlan_cpu_to_le16(pauth_tlv->header.len); } + if ((pauth_tlv != MNULL) && + (pauth_tlv->auth_type == + wlan_cpu_to_le16(AssocAgentAuth_Wpa3Sae))) { + if (pbss_desc->prsnx_ie && pbss_desc->prsnx_ie->ieee_hdr.len && + (pbss_desc->prsnx_ie->data[0] & (0x1 << SAE_H2E_BIT))) { + MrvlIEtypes_SAE_PWE_Mode_t *psae_pwe_mode_tlv; + + /* Setup the sae pwe derivation mode TLV in the + * association command */ + psae_pwe_mode_tlv = (MrvlIEtypes_SAE_PWE_Mode_t *)pos; + psae_pwe_mode_tlv->header.type = wlan_cpu_to_le16( + TLV_TYPE_WPA3_SAE_PWE_DERIVATION_MODE); + psae_pwe_mode_tlv->header.len = + sizeof(psae_pwe_mode_tlv->pwe); + psae_pwe_mode_tlv->pwe[0] = + pbss_desc->prsnx_ie->data[0]; + pos += sizeof(psae_pwe_mode_tlv->header) + + sizeof(psae_pwe_mode_tlv->pwe); + } + } + if (IS_SUPPORT_MULTI_BANDS(pmadapter) && (pbss_desc->bss_band & pmpriv->config_bands) && !(ISSUPP_11NENABLED(pmadapter->fw_cap_info) && diff --git a/mxm_wifiex/wlan_src/mlan/mlan_misc.c b/mxm_wifiex/wlan_src/mlan/mlan_misc.c index c2db6da..16480bc 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_misc.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_misc.c @@ -2156,8 +2156,8 @@ static t_void wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr, tdls_all_cfg->u.tdls_chan_switch .secondary_channel_offset = wlan_get_second_channel_offset( - tdls_all_cfg->u.tdls_chan_switch - .primary_channel); + pmpriv, tdls_all_cfg->u.tdls_chan_switch + .primary_channel); } PRINTM(MCMND, "Start TDLS CS: channel=%d\n", tdls_all_cfg->u.tdls_chan_switch.primary_channel); @@ -2175,7 +2175,7 @@ static t_void wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr, tdls_all_cfg->u.tdls_chan_switch .secondary_channel_offset = wlan_get_second_channel_offset( - pmpriv->tdls_cs_channel); + pmpriv, pmpriv->tdls_cs_channel); } else { tdls_all_cfg->u.tdls_chan_switch.band = BAND_2GHZ; } @@ -2682,13 +2682,13 @@ mlan_status wlan_misc_ioctl_tdls_get_ies(pmlan_adapter pmadapter, } else { ht_info->ht_info.field2 = wlan_get_second_channel_offset( - pbss_desc->channel); + pmpriv, pbss_desc->channel); } if (vht_oprat && vht_oprat->ieee_hdr.element_id == VHT_OPERATION) { ht_info->ht_info.field2 = wlan_get_second_channel_offset( - pbss_desc->channel); + pmpriv, pbss_desc->channel); ht_info->ht_info.field2 |= MBIT(2); } if (sta_ptr) @@ -2806,309 +2806,6 @@ mlan_status wlan_get_info_ver_ext(pmlan_adapter pmadapter, return ret; } -/** - * @brief This function convert mlan_wifi_rate to wifi_rate. - * - * @param pmpriv A pointer to mlan_private structure - * @param rateStats wifi_rate_stat array - * @param pnum_rate A pointer to num_rate - * - * @return N/A - */ -t_void wlan_fill_hal_wifi_rate_in_host(pmlan_private pmpriv, - OUT wifi_rate_stat rateStats[], - t_u32 *pnumRate) -{ - t_u32 total_num_rate = 0; - t_u32 mcs_idx = 0; - t_u8 index = 0; - t_u8 rate_info = 0; - - ENTER(); - - /* HT MCS */ - for (mcs_idx = 0; mcs_idx < MCS_NUM_SUPP; mcs_idx++) { - /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ - rateStats[total_num_rate].rate.preamble = 2; - /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ - rateStats[total_num_rate].rate.bw = 0; - rateStats[total_num_rate].rate.rateMcsIdx = mcs_idx; - index = rateStats[total_num_rate].rate.rateMcsIdx; - rate_info = MLAN_RATE_FORMAT_HT | - (rateStats[total_num_rate].rate.bw << 2); - rateStats[total_num_rate].rate.bitrate = - wlan_index_to_data_rate(pmpriv->adapter, index, - rate_info, 0) * - 5; - PRINTM(MINFO, "HT[%d] index=0x%x rate_info=0x%x bitrate=0x%x\n", - total_num_rate, index, rate_info, - rateStats[total_num_rate].rate.bitrate / 5); - - /* Get Tx mpdu */ - rateStats[total_num_rate].tx_mpdu = 0; - rateStats[total_num_rate].rx_mpdu = 0; - - /* Todo: mpdu_lost/retries*, need extend GetTxRxRateInfo */ - rateStats[total_num_rate].mpdu_lost = 0xC1; - rateStats[total_num_rate].retries = 0xC2; - rateStats[total_num_rate].retries_short = 0xC3; - rateStats[total_num_rate].retries_long = 0xC4; - - total_num_rate++; - } - - /* VHT MCS */ - for (mcs_idx = 0; mcs_idx < VHT_NUM_SUPPORT_MCS; mcs_idx++) { - /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ - rateStats[total_num_rate].rate.preamble = 3; - /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ - rateStats[total_num_rate].rate.nss = 0; - /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ - rateStats[total_num_rate].rate.bw = 0; - rateStats[total_num_rate].rate.rateMcsIdx = mcs_idx; - /* nss 2 ? bw 20MHZ ? */ - index = rateStats[total_num_rate].rate.rateMcsIdx | - (rateStats[total_num_rate].rate.nss << 4); - rate_info = MLAN_RATE_FORMAT_VHT | - (rateStats[total_num_rate].rate.bw << 2); - rateStats[total_num_rate].rate.bitrate = - wlan_index_to_data_rate(pmpriv->adapter, index, - rate_info, 0) * - 5; - PRINTM(MINFO, - "VHT[%d] index=0x%x rate_info=0x%x bitrate=0x%x\n", - total_num_rate, index, rate_info, - rateStats[total_num_rate].rate.bitrate / 5); - - rateStats[total_num_rate].tx_mpdu = 0; - rateStats[total_num_rate].rx_mpdu = 0; - - /* Todo: mpdu_lost/retries*, need extend GetTxRxRateInfo */ - rateStats[total_num_rate].mpdu_lost = 0xC1; - rateStats[total_num_rate].retries = 0xC2; - rateStats[total_num_rate].retries_short = 0xC3; - rateStats[total_num_rate].retries_long = 0xC4; - - total_num_rate++; - } - - *pnumRate = total_num_rate; - - LEAVE(); -} - -/** - * @brief This function fill link layer statistic from firmware - * - * @param priv A pointer to - * mlan_private structure - * @param link_statistic_ioctl_buf, A pointer to fill ioctl buffer - * - * @return MLAN_STATUS_SUCCESS - */ -static void wlan_fill_link_statistic_in_host(mlan_private *priv, - char *link_statistic_ioctl_buf) -{ - char *link_statistic = link_statistic_ioctl_buf; - wifi_radio_stat *radio_stat = MNULL; - wifi_iface_stat *iface_stat = MNULL; - t_u32 num_radio = MAX_RADIO; - int i = 0, chan_idx = 0; - t_u32 num_peers = 0; - sta_node *sta_ptr = MNULL; -#ifdef WMM - t_u8 *ptid = MNULL; -#endif - - ENTER(); - - *((t_u32 *)link_statistic) = num_radio; - link_statistic += sizeof(num_radio); - - /* Fill radio stats array */ - for (i = 0; i < num_radio; i++) { - radio_stat = (wifi_radio_stat *)link_statistic; - link_statistic += sizeof(wifi_radio_stat); - - radio_stat->radio = 0xF0; - - radio_stat->on_time = 0; - radio_stat->tx_time = 0; - radio_stat->reserved0 = 0; - radio_stat->rx_time = 0; - radio_stat->on_time_scan = 0; - radio_stat->on_time_nbd = 0; - radio_stat->on_time_gscan = 0; - radio_stat->on_time_roam_scan = 0; - radio_stat->on_time_pno_scan = 0; - radio_stat->on_time_hs20 = 0; - - radio_stat->num_channels = 1; - for (chan_idx = 0; chan_idx < radio_stat->num_channels; - chan_idx++) { - if (radio_stat->num_channels > MAX_NUM_CHAN) { - radio_stat->num_channels = MAX_NUM_CHAN; - PRINTM(MERROR, - "%s : radio_stat->num_channels=%d\n", - __func__, radio_stat->num_channels); - break; - } - - if (priv->bss_role == MLAN_BSS_ROLE_STA) { - if (priv->media_connected) { - radio_stat->channels[chan_idx] - .channel.width = - priv->curr_bss_params - .bss_descriptor - .curr_bandwidth; - radio_stat->channels[chan_idx] - .channel.center_freq = - priv->curr_bss_params - .bss_descriptor.freq; - radio_stat->channels[chan_idx] - .channel.center_freq0 = 0; - radio_stat->channels[chan_idx] - .channel.center_freq1 = 0; - } - } else { - radio_stat->channels[chan_idx].channel.width = - priv->uap_state_chan_cb.bandcfg - .chanWidth; - radio_stat->channels[chan_idx] - .channel - .center_freq = wlan_11d_chan_2_freq( - priv->adapter, - priv->uap_state_chan_cb.channel, - (priv->uap_state_chan_cb.channel > 14) ? - BAND_A : - BAND_G); - radio_stat->channels[chan_idx] - .channel.center_freq0 = 0; - radio_stat->channels[chan_idx] - .channel.center_freq1 = 0; - } - radio_stat->channels[chan_idx].on_time = 0xE3; - radio_stat->channels[chan_idx].cca_busy_time = 0xE4; - } - } - - /* Fill iface stats*/ - iface_stat = (wifi_iface_stat *)link_statistic; - - /* get wifi_interface_link_layer_info in driver, not in firmware */ - if (priv->bss_role == MLAN_BSS_ROLE_STA) { - iface_stat->info.mode = MLAN_INTERFACE_STA; - if (priv->media_connected) - iface_stat->info.state = MLAN_ASSOCIATING; - else - iface_stat->info.state = MLAN_DISCONNECTED; - iface_stat->info.roaming = MLAN_ROAMING_IDLE; - iface_stat->info.capabilities = MLAN_CAPABILITY_QOS; - memcpy_ext(priv->adapter, iface_stat->info.ssid, - priv->curr_bss_params.bss_descriptor.ssid.ssid, - MLAN_MAX_SSID_LENGTH, MLAN_MAX_SSID_LENGTH); - memcpy_ext(priv->adapter, iface_stat->info.bssid, - priv->curr_bss_params.bss_descriptor.mac_address, - MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); - } else { - iface_stat->info.mode = MLAN_INTERFACE_SOFTAP; - iface_stat->info.capabilities = MLAN_CAPABILITY_QOS; - } - memcpy_ext(priv->adapter, iface_stat->info.mac_addr, priv->curr_addr, - MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); - memcpy_ext(priv->adapter, iface_stat->info.ap_country_str, - priv->adapter->country_code, COUNTRY_CODE_LEN, - COUNTRY_CODE_LEN); - memcpy_ext(priv->adapter, iface_stat->info.country_str, - priv->adapter->country_code, COUNTRY_CODE_LEN, - COUNTRY_CODE_LEN); - - iface_stat->beacon_rx = 0; - iface_stat->average_tsf_offset = 0; - iface_stat->leaky_ap_detected = 0; - iface_stat->leaky_ap_avg_num_frames_leaked = 0; - iface_stat->leaky_ap_guard_time = 0; - - /* Value of iface_stat should be Reaccumulate by each peer */ - iface_stat->mgmt_rx = 0; - iface_stat->mgmt_action_rx = 0; - iface_stat->mgmt_action_tx = 0; - - iface_stat->rssi_mgmt = 0; - iface_stat->rssi_data = 0; - iface_stat->rssi_ack = 0; - -#ifdef WMM - for (i = WMM_AC_BK; i <= WMM_AC_VO; i++) { - iface_stat->ac[i].ac = i; - ptid = ac_to_tid[i]; - iface_stat->ac[i].tx_mpdu = priv->wmm.packets_out[ptid[0]] + - priv->wmm.packets_out[ptid[1]]; - iface_stat->ac[i].rx_mpdu = 0; - iface_stat->ac[i].tx_mcast = 0; - iface_stat->ac[i].rx_mcast = 0; - iface_stat->ac[i].rx_ampdu = 0; - iface_stat->ac[i].tx_ampdu = 0; - iface_stat->ac[i].mpdu_lost = 0; - iface_stat->ac[i].retries = 0; - iface_stat->ac[i].retries_short = 0; - iface_stat->ac[i].retries_long = 0; - iface_stat->ac[i].contention_time_min = 0; - iface_stat->ac[i].contention_time_max = 0; - iface_stat->ac[i].contention_time_avg = 0; - iface_stat->ac[i].contention_num_samples = 0; - } -#endif - - if (priv->bss_role == MLAN_BSS_ROLE_STA) { - if (priv->media_connected) { - iface_stat->peer_info[0].type = WIFI_PEER_AP; - memcpy_ext( - priv->adapter, - iface_stat->peer_info[0].peer_mac_address, - priv->curr_bss_params.bss_descriptor.mac_address, - MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); - iface_stat->peer_info[0].capabilities = - MLAN_CAPABILITY_QOS; - wlan_fill_hal_wifi_rate_in_host( - priv, iface_stat->peer_info[0].rate_stats, - &(iface_stat->peer_info[0].num_rate)); - num_peers = 1; - } - } else { - sta_ptr = (sta_node *)util_peek_list( - priv->adapter->pmoal_handle, &priv->sta_list, - priv->adapter->callbacks.moal_spin_lock, - priv->adapter->callbacks.moal_spin_unlock); - if (sta_ptr) { - while (sta_ptr != (sta_node *)&priv->sta_list) { - iface_stat->peer_info[num_peers].type = - WIFI_PEER_STA; - memcpy_ext(priv->adapter, - iface_stat->peer_info[num_peers] - .peer_mac_address, - sta_ptr->mac_addr, - MLAN_MAC_ADDR_LENGTH, - MLAN_MAC_ADDR_LENGTH); - iface_stat->peer_info[num_peers].capabilities = - MLAN_CAPABILITY_QOS; - wlan_fill_hal_wifi_rate_in_host( - priv, - iface_stat->peer_info[num_peers] - .rate_stats, - &(iface_stat->peer_info[num_peers] - .num_rate)); - num_peers++; - - sta_ptr = sta_ptr->pnext; - } - } - } - iface_stat->num_peers = num_peers; - - LEAVE(); -} - /** * @brief Set/Get link layer statistics * @@ -3121,8 +2818,7 @@ mlan_status wlan_ioctl_link_statistic(mlan_private *pmpriv, pmlan_ioctl_req pioctl_req) { mlan_status ret = MLAN_STATUS_SUCCESS; - mlan_ds_get_info *info = MNULL; - t_u8 *link_statistic = MNULL; + t_u16 cmd_action = 0; ENTER(); @@ -3137,18 +2833,27 @@ mlan_status wlan_ioctl_link_statistic(mlan_private *pmpriv, goto exit; } - /** We will not send HostCmd_CMD_802_11_LINK_STATS to FW */ - if (pioctl_req->action == MLAN_ACT_GET) { - info = (mlan_ds_get_info *)pioctl_req->pbuf; - link_statistic = info->param.link_statistic; - /** Get the LL STATS from driver */ - wlan_fill_link_statistic_in_host(pmpriv, link_statistic); - DBG_HEXDUMP( - MCMD_D, - "wlan_ioctl_link_statistic() link_statistic in host", - (t_u8 *)link_statistic, 800); + switch (pioctl_req->action) { + case MLAN_ACT_GET: + cmd_action = HostCmd_ACT_GEN_GET; + break; + case MLAN_ACT_SET: + cmd_action = HostCmd_ACT_GEN_SET; + break; + case MLAN_ACT_CLEAR: + cmd_action = HostCmd_ACT_GEN_REMOVE; + break; + default: + ret = MLAN_STATUS_FAILURE; + goto exit; } - ret = MLAN_STATUS_SUCCESS; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_LINK_STATS, + cmd_action, 0, (t_void *)pioctl_req, MNULL); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; exit: LEAVE(); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_module.c b/mxm_wifiex/wlan_src/mlan/mlan_module.c index 67a6d7a..724c794 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_module.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_module.c @@ -45,6 +45,7 @@ EXPORT_SYMBOL(mlan_ioctl); EXPORT_SYMBOL(mlan_main_process); EXPORT_SYMBOL(mlan_rx_process); EXPORT_SYMBOL(mlan_select_wmm_queue); +EXPORT_SYMBOL(mlan_process_deaggr_pkt); #if defined(SDIO) || defined(PCIE) EXPORT_SYMBOL(mlan_interrupt); #if defined(SYSKT) diff --git a/mxm_wifiex/wlan_src/mlan/mlan_scan.c b/mxm_wifiex/wlan_src/mlan/mlan_scan.c index 4fcd638..389ad67 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_scan.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_scan.c @@ -452,9 +452,9 @@ static t_s32 wlan_find_best_network_in_list(mlan_private *pmpriv) * of channels sent in a scan command and to disable the firmware channel scan * filter. * - * @return N/A + * @return num of channel */ -static t_void wlan_scan_create_channel_list( +static t_u8 wlan_scan_create_channel_list( mlan_private *pmpriv, const wlan_user_scan_cfg *puser_scan_in, ChanScanParamSet_t *pscan_chan_list, t_u8 filtered_scan) { @@ -602,6 +602,7 @@ static t_void wlan_scan_create_channel_list( } LEAVE(); + return chan_idx; } /** @@ -1082,6 +1083,7 @@ static mlan_status wlan_scan_setup_scan_config( MrvlIEtypes_BssMode_t *pbss_mode; MrvlIEtypes_Extension_t *phe_cap; t_u16 len = 0; + t_u8 num_of_channel = 0; ENTER(); @@ -1568,9 +1570,14 @@ static mlan_status wlan_scan_setup_scan_config( } } else { - PRINTM(MINFO, "Scan: Creating full region channel list\n"); - wlan_scan_create_channel_list(pmpriv, puser_scan_in, - pscan_chan_list, *pfiltered_scan); + num_of_channel = + wlan_scan_create_channel_list(pmpriv, puser_scan_in, + pscan_chan_list, + *pfiltered_scan); + PRINTM(MCMND, "Scan: Creating full region channel list %d\n", + num_of_channel); + if (num_of_channel > MRVDRV_MAX_CHANNELS_PER_SCAN) + pmadapter->ext_scan_type = EXT_SCAN_DEFAULT; } LEAVE(); @@ -2070,6 +2077,16 @@ static mlan_status wlan_interpret_bss_desc_with_ie(pmlan_adapter pmadapter, (*(pbss_entry->prsn_ie)).ieee_hdr.len + sizeof(IEEEtypes_Header_t)); break; + case RSNX_IE: + pbss_entry->prsnx_ie = + (IEEEtypes_Generic_t *)pcurrent_ptr; + pbss_entry->rsnx_offset = + (t_u16)(pcurrent_ptr - pbss_entry->pbeacon_buf); + HEXDUMP("InterpretIE: Resp RSNX_IE", + (t_u8 *)pbss_entry->prsnx_ie, + (*(pbss_entry->prsnx_ie)).ieee_hdr.len + + sizeof(IEEEtypes_Header_t)); + break; case WAPI_IE: pbss_entry->pwapi_ie = (IEEEtypes_Generic_t *)pcurrent_ptr; @@ -2380,6 +2397,11 @@ static t_void wlan_adjust_ie_in_bss_entry(mlan_private *pmpriv, *)(pbss_entry->pbeacon_buf + pbss_entry->he_oprat_offset); } + if (pbss_entry->prsnx_ie) { + pbss_entry->prsnx_ie = + (IEEEtypes_Generic_t *)(pbss_entry->pbeacon_buf + + pbss_entry->rsnx_offset); + } } else { pbss_entry->pwpa_ie = MNULL; pbss_entry->wpa_offset = 0; @@ -2710,6 +2732,10 @@ static t_void wlan_ret_802_11_scan_store_beacon(mlan_private *pmpriv, pnew_beacon->he_oprat_offset = pmadapter->pscan_table[beacon_idx] .he_oprat_offset; + if (pnew_beacon->prsnx_ie) + pnew_beacon->rsnx_offset = + pmadapter->pscan_table[beacon_idx] + .rsnx_offset; } /* Point the new entry to its permanent storage space */ pnew_beacon->pbeacon_buf = pbcn_store; @@ -2970,6 +2996,11 @@ static mlan_status wlan_update_curr_bcn(mlan_private *pmpriv) *)(pcurr_bss->pbeacon_buf + pcurr_bss->he_oprat_offset); } + if (pcurr_bss->prsnx_ie) { + pcurr_bss->prsnx_ie = + (IEEEtypes_Generic_t *)(pcurr_bss->pbeacon_buf + + pcurr_bss->rsnx_offset); + } PRINTM(MINFO, "current beacon restored %d\n", pmpriv->curr_bcn_size); @@ -3185,6 +3216,8 @@ static t_void wlan_scan_process_results(mlan_private *pmpriv) MNULL; pmpriv->curr_bss_params.bss_descriptor.he_oprat_offset = 0; + pmpriv->curr_bss_params.bss_descriptor.prsnx_ie = MNULL; + pmpriv->curr_bss_params.bss_descriptor.rsnx_offset = 0; pmpriv->curr_bss_params.bss_descriptor.pbeacon_buf = MNULL; pmpriv->curr_bss_params.bss_descriptor.beacon_buf_size = diff --git a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c index ab0bc8a..fed31b0 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_sdio.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_sdio.c @@ -2850,8 +2850,7 @@ static mlan_status wlan_process_sdio_int_status(mlan_adapter *pmadapter) } rx_len = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE); - if ((rx_len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) || - (!new_mode && (port == CTRL_PORT))) + if (!new_mode && (port == CTRL_PORT)) pmbuf = wlan_alloc_mlan_buffer( pmadapter, rx_len, 0, MOAL_MALLOC_BUFFER); diff --git a/mxm_wifiex/wlan_src/mlan/mlan_shim.c b/mxm_wifiex/wlan_src/mlan/mlan_shim.c index 9618752..e513638 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_shim.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_shim.c @@ -257,6 +257,8 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter) LEAVE(); return MLAN_STATUS_FAILURE; } + if (pmdevice->callbacks.moal_recv_amsdu_packet) + PRINTM(MMSG, "Enable moal_recv_amsdu_packet\n"); /* Allocate memory for adapter structure */ if (pmdevice->callbacks.moal_vmalloc && pmdevice->callbacks.moal_vfree) @@ -1699,6 +1701,50 @@ t_u8 mlan_select_wmm_queue(t_void *padapter, t_u8 bss_num, t_u8 tid) return ret; } +/** + * @brief this function handle the amsdu packet after deaggreate. + * + * @param padapter A pointer to mlan_adapter structure + * @param pmbuf A pointer to the deaggreated buf + * @param drop A pointer to return the drop flag. + * + * @return N/A + */ +void mlan_process_deaggr_pkt(t_void *padapter, pmlan_buffer pmbuf, t_u8 *drop) +{ + mlan_adapter *pmadapter = (mlan_adapter *)padapter; + mlan_private *pmpriv; + t_u16 eth_type = 0; + + *drop = MFALSE; + pmpriv = pmadapter->priv[pmbuf->bss_index]; + eth_type = + mlan_ntohs(*(t_u16 *)&pmbuf->pbuf[pmbuf->data_offset + + MLAN_ETHER_PKT_TYPE_OFFSET]); + switch (eth_type) { + case MLAN_ETHER_PKT_TYPE_EAPOL: + PRINTM(MEVENT, "Recevie AMSDU EAPOL frame\n"); + if (pmpriv->sec_info.ewpa_enabled) { + *drop = MTRUE; + wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_EAPOL_PKT, + 0, 0, MNULL, pmbuf); + wlan_recv_event(pmpriv, + MLAN_EVENT_ID_DRV_DEFER_HANDLING, + MNULL); + } + break; + case MLAN_ETHER_PKT_TYPE_TDLS_ACTION: + PRINTM(MEVENT, "Recevie AMSDU TDLS action frame\n"); + wlan_process_tdls_action_frame(pmpriv, + pmbuf->pbuf + pmbuf->data_offset, + pmbuf->data_len); + break; + default: + break; + } + return; +} + #if defined(SDIO) || defined(PCIE) /** * @brief This function gets interrupt status. diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index b0d15a0..5f9e667 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -1512,6 +1512,9 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv, custom_ie *cptr = MNULL; mlan_status ret = MLAN_STATUS_SUCCESS; MrvlIEtypes_wacp_mode_t *tlv_wacp_mode = MNULL; + MrvlIEtypes_action_chan_switch_t *tlv_chan_switch = MNULL; + IEEEtypes_ChanSwitchAnn_t *csa_ie = MNULL; + IEEEtypes_ExtChanSwitchAnn_t *ecsa_ie = MNULL; ENTER(); @@ -1829,6 +1832,57 @@ static mlan_status wlan_uap_cmd_sys_configure(pmlan_private pmpriv, bss->param.ap_channel.bandcfg, bss->param.ap_channel.channel); } + } else if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH) { + cmd->size = sizeof(HostCmd_DS_SYS_CONFIG) - 1 + + S_DS_GEN + + sizeof(MrvlIEtypes_action_chan_switch_t); + tlv_chan_switch = (MrvlIEtypes_action_chan_switch_t *) + sys_config->tlv_buffer; + tlv_chan_switch->header.type = wlan_cpu_to_le16( + MRVL_ACTION_CHAN_SWITCH_ANNOUNCE); + // mode reserve for future use + tlv_chan_switch->mode = 0; + if (bss->param.chanswitch.new_oper_class) { + tlv_chan_switch->header.len = wlan_cpu_to_le16( + sizeof(MrvlIEtypes_action_chan_switch_t) - + sizeof(MrvlIEtypesHeader_t) + + sizeof(IEEEtypes_ExtChanSwitchAnn_t)); + ecsa_ie = (IEEEtypes_ExtChanSwitchAnn_t *) + tlv_chan_switch->ie_buf; + ecsa_ie->element_id = EXTEND_CHANNEL_SWITCH_ANN; + ecsa_ie->len = + sizeof(IEEEtypes_ExtChanSwitchAnn_t) - + sizeof(IEEEtypes_Header_t); + ecsa_ie->chan_switch_mode = + bss->param.chanswitch.chan_switch_mode; + ecsa_ie->chan_switch_count = + bss->param.chanswitch.chan_switch_count; + ecsa_ie->new_channel_num = + bss->param.chanswitch.new_channel_num; + ecsa_ie->new_oper_class = + bss->param.chanswitch.new_oper_class; + cmd->size += + sizeof(IEEEtypes_ExtChanSwitchAnn_t); + } else { + tlv_chan_switch->header.len = wlan_cpu_to_le16( + sizeof(MrvlIEtypes_action_chan_switch_t) - + sizeof(MrvlIEtypesHeader_t) + + sizeof(IEEEtypes_ChanSwitchAnn_t)); + csa_ie = (IEEEtypes_ChanSwitchAnn_t *) + tlv_chan_switch->ie_buf; + csa_ie->element_id = CHANNEL_SWITCH_ANN; + csa_ie->len = + sizeof(IEEEtypes_ChanSwitchAnn_t) - + sizeof(IEEEtypes_Header_t); + csa_ie->chan_switch_mode = + bss->param.chanswitch.chan_switch_mode; + csa_ie->chan_switch_count = + bss->param.chanswitch.chan_switch_count; + csa_ie->new_channel_num = + bss->param.chanswitch.new_channel_num; + cmd->size += sizeof(IEEEtypes_ChanSwitchAnn_t); + } + cmd->size = wlan_cpu_to_le16(cmd->size); } else if ((bss->sub_command == MLAN_OID_UAP_BSS_CONFIG) && (cmd_action == HostCmd_ACT_GEN_SET)) { ret = wlan_uap_cmd_ap_config(pmpriv, cmd, cmd_action, @@ -3628,6 +3682,7 @@ static mlan_status wlan_uap_ret_sta_list(pmlan_private pmpriv, sta_node *sta_ptr; t_u8 tlv_len = 0; t_u8 *buf = MNULL; + t_u8 *ie_buf = MNULL; ENTER(); if (pioctl_buf) { @@ -3638,8 +3693,12 @@ static mlan_status wlan_uap_ret_sta_list(pmlan_private pmpriv, tlv = (MrvlIEtypes_sta_info_t *)buf; info->param.sta_list.sta_count = MIN(info->param.sta_list.sta_count, MAX_NUM_CLIENTS); + ie_buf = (t_u8 *)&info->param.sta_list.info[0]; + ie_buf += + sizeof(sta_info_data) * info->param.sta_list.sta_count; pioctl_buf->data_read_written = - sizeof(info->param.sta_list.sta_count); + sizeof(mlan_ds_sta_list) - + sizeof(sta_info_data) * MAX_NUM_CLIENTS; for (i = 0; i < info->param.sta_list.sta_count; i++) { tlv_len = wlan_le16_to_cpu(tlv->header.len); memcpy_ext(pmpriv->adapter, @@ -3649,12 +3708,12 @@ static mlan_status wlan_uap_ret_sta_list(pmlan_private pmpriv, info->param.sta_list.info[i].ie_len = tlv_len + sizeof(MrvlIEtypesHeader_t) - sizeof(MrvlIEtypes_sta_info_t); - if (info->param.sta_list.info[i].ie_len) - memcpy_ext(pmpriv->adapter, - info->param.sta_list.info[i].ie_buf, - tlv->ie_buf, + if (info->param.sta_list.info[i].ie_len) { + memcpy_ext(pmpriv->adapter, ie_buf, tlv->ie_buf, info->param.sta_list.info[i].ie_len, info->param.sta_list.info[i].ie_len); + ie_buf += info->param.sta_list.info[i].ie_len; + } info->param.sta_list.info[i].power_mgmt_status = tlv->power_mgmt_status; info->param.sta_list.info[i].rssi = tlv->rssi; @@ -3671,7 +3730,7 @@ static mlan_status wlan_uap_ret_sta_list(pmlan_private pmpriv, } else info->param.sta_list.info[i].bandmode = 0xFF; pioctl_buf->data_read_written += - sizeof(sta_info_data) - 1 + + sizeof(sta_info_data) + info->param.sta_list.info[i].ie_len; buf += sizeof(MrvlIEtypes_sta_info_t) + info->param.sta_list.info[i].ie_len; @@ -4069,6 +4128,7 @@ static mlan_status wlan_uap_cmd_oper_ctrl(pmlan_private pmpriv, if (bandcfg->chanWidth) bandcfg->chan2Offset = wlan_get_second_channel_offset( + pmpriv, uap_oper_ctrl->channel); bandcfg->scanMode = SCAN_MODE_MANUAL; poper_ctl->channel_band.channel = diff --git a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c index 892f764..5017c32 100644 --- a/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c +++ b/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c @@ -171,6 +171,7 @@ static mlan_status wlan_uap_callback_bss_ioctl_start(t_void *priv) if (ret == MLAN_STATUS_SUCCESS) { wlan_11h_update_bandcfg( + pmpriv, &pmpriv->uap_state_chan_cb.bandcfg, puap_state_chan_cb->channel); PRINTM(MCMD_D, @@ -349,11 +350,6 @@ static mlan_status wlan_uap_bss_ioctl_reset(pmlan_adapter pmadapter, pmpriv->addba_reject[6] = pmpriv->addba_reject[7] = ADDBA_RSP_STATUS_REJECT; - /* hs_configured, hs_activated are reset by main loop */ - pmadapter->hs_cfg.conditions = HOST_SLEEP_DEF_COND; - pmadapter->hs_cfg.gpio = HOST_SLEEP_DEF_GPIO; - pmadapter->hs_cfg.gap = HOST_SLEEP_DEF_GAP; - ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_RESET, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req, MNULL); @@ -459,6 +455,37 @@ static mlan_status wlan_uap_bss_ioctl_uap_wmm_param(pmlan_adapter pmadapter, return ret; } +/** + * @brief Handle channel switch + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +static mlan_status +wlan_uap_bss_ioctl_action_chan_switch(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_status ret = MLAN_STATUS_SUCCESS; + t_u16 cmd_action = 0; + + ENTER(); + + cmd_action = HostCmd_ACT_GEN_SET; + + /* Send request to firmware */ + ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE, cmd_action, + 0, (t_void *)pioctl_req, MNULL); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + /** * @brief Set/Get scan channels * @@ -1858,6 +1885,9 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) else if (bss->sub_command == MLAN_OID_UAP_ADD_STATION) status = wlan_uap_bss_ioctl_add_station(pmadapter, pioctl_req); + else if (bss->sub_command == MLAN_OID_ACTION_CHAN_SWITCH) + status = wlan_uap_bss_ioctl_action_chan_switch( + pmadapter, pioctl_req); break; #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) case MLAN_IOCTL_SCAN: diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index 9812046..00cf3f0 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 "283.p2" +#define MLAN_RELEASE_VERSION "293" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -138,6 +138,9 @@ typedef t_s32 t_sval; /** NET IP alignment */ #define MLAN_NET_IP_ALIGN 2 +/** US country code */ +#define COUNTRY_CODE_US 0x10 + /** DMA alignment */ /* SDIO3.0 Inrevium Adapter require 32 bit DMA alignment */ #define DMA_ALIGNMENT 32 @@ -1916,6 +1919,9 @@ typedef struct _mlan_callbacks { t_u32 port, mlan_status status); /** moal_recv_packet */ mlan_status (*moal_recv_packet)(t_void *pmoal, pmlan_buffer pmbuf); + /** moal_recv_amsdu_packet */ + mlan_status (*moal_recv_amsdu_packet)(t_void *pmoal, + pmlan_buffer pmbuf); /** moal_recv_event */ mlan_status (*moal_recv_event)(t_void *pmoal, pmlan_event pmevent); /** moal_ioctl_complete */ @@ -2234,6 +2240,9 @@ MLAN_API mlan_status mlan_recv_packet_complete(t_void *padapter, pmlan_buffer pmbuf, mlan_status status); +/** handle amsdu deaggregated packet */ +void mlan_process_deaggr_pkt(t_void *padapter, pmlan_buffer pmbuf, t_u8 *drop); + #if defined(SDIO) || defined(PCIE) /** interrupt handler */ MLAN_API mlan_status mlan_interrupt(t_u16 msg_id, t_void *padapter); diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h index 329aa77..e64d4b7 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ieee.h @@ -1321,7 +1321,7 @@ typedef MLAN_PACK_START struct { } MLAN_PACK_END IEEEtypes_ExtChanSwitchAnn_t; /** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */ -#define WLAN_11H_MAX_SUBBANDS 5 +#define WLAN_11H_MAX_SUBBANDS 6 /** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */ #define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25 @@ -1976,6 +1976,10 @@ typedef struct _BSSDescriptor_t { IEEEtypes_Generic_t *prsn_ie; /** RSN IE offset in the beacon buffer */ t_u16 rsn_offset; + /** RSNX IE */ + IEEEtypes_Generic_t *prsnx_ie; + /** RSNX IE offset in the beacon buffer */ + t_u16 rsnx_offset; #ifdef STA_SUPPORT /** WAPI IE */ IEEEtypes_Generic_t *pwapi_ie; diff --git a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index 0aa139c..31a8bac 100644 --- a/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -86,6 +86,9 @@ enum _mlan_ioctl_req_id { #endif MLAN_OID_BSS_FIND_BSSID = 0x0002001D, +#ifdef UAP_SUPPORT + MLAN_OID_ACTION_CHAN_SWITCH = 0x0002001E, +#endif /* Radio Configuration Group */ MLAN_IOCTL_RADIO_CFG = 0x00030000, @@ -627,7 +630,7 @@ typedef struct _mlan_multicast_list { } mlan_multicast_list, *pmlan_multicast_list; /** Max channel */ -#define MLAN_MAX_CHANNEL 165 +#define MLAN_MAX_CHANNEL 177 /** Maximum number of channels in table */ #define MLAN_MAX_CHANNEL_NUM 128 @@ -1119,6 +1122,20 @@ typedef struct _mlan_uap_scan_channels { scan_chan_list chan_list[MLAN_MAX_CHANNEL]; } mlan_uap_scan_channels; +/** mlan_chan_switch_param */ +typedef struct _mlan_action_chan_switch { + /** mode*/ + t_u8 mode; + /** switch mode*/ + t_u8 chan_switch_mode; + /** oper class*/ + t_u8 new_oper_class; + /** new channel */ + t_u8 new_channel_num; + /** chan_switch_count */ + t_u8 chan_switch_count; +} mlan_action_chan_switch; + /** mlan_uap_oper_ctrl */ typedef struct _mlan_uap_oper_ctrl { /** control value @@ -1232,6 +1249,8 @@ typedef struct _mlan_ds_bss { wmm_parameter_t ap_wmm_para; /** ap scan channels for MLAN_OID_UAP_SCAN_CHANNELS*/ mlan_uap_scan_channels ap_scan_channels; + /** channel switch for MLAN_OID_UAP_CHAN_SWITCH */ + mlan_action_chan_switch chanswitch; /** ap channel for MLAN_OID_UAP_CHANNEL*/ chan_band_info ap_channel; /** ap operation control for MLAN_OID_UAP_OPER_CTRL*/ @@ -2449,8 +2468,6 @@ typedef struct _sta_info_data { sta_stats stats; /** ie length */ t_u16 ie_len; - /** ie buffer */ - t_u8 ie_buf[1]; } sta_info_data; /** mlan_ds_sta_list structure for MLAN_OID_UAP_STA_LIST */ @@ -2459,6 +2476,7 @@ typedef struct _mlan_ds_sta_list { t_u16 sta_count; /** station list */ sta_info_data info[MAX_NUM_CLIENTS]; + /* ie_buf will be append at the end */ } mlan_ds_sta_list, *pmlan_ds_sta_list; #endif diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c index bafe406..e8a719f 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.c @@ -127,6 +127,9 @@ static struct ieee80211_channel cfg80211_channels_5ghz[] = { {.center_freq = 5785, .hw_value = 157, .max_power = 20}, {.center_freq = 5805, .hw_value = 161, .max_power = 20}, {.center_freq = 5825, .hw_value = 165, .max_power = 20}, + {.center_freq = 5845, .hw_value = 169, .max_power = 20}, + {.center_freq = 5865, .hw_value = 173, .max_power = 20}, + {.center_freq = 5885, .hw_value = 177, .max_power = 20}, }; struct ieee80211_supported_band cfg80211_band_2ghz = { @@ -172,6 +175,9 @@ static struct ieee80211_channel mac1_cfg80211_channels_5ghz[] = { {.center_freq = 5785, .hw_value = 157, .max_power = 20}, {.center_freq = 5805, .hw_value = 161, .max_power = 20}, {.center_freq = 5825, .hw_value = 165, .max_power = 20}, + {.center_freq = 5845, .hw_value = 169, .max_power = 20}, + {.center_freq = 5865, .hw_value = 173, .max_power = 20}, + {.center_freq = 5885, .hw_value = 177, .max_power = 20}, }; struct ieee80211_supported_band mac1_cfg80211_band_2ghz = { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h index d723540..4f014e5 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211.h @@ -108,6 +108,10 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv, #endif #endif +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) +void woal_regulatory_work_queue(struct work_struct *work); +#endif + t_u8 woal_band_cfg_to_ieee_band(t_u32 band); int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c index d5289db..bedfdaf 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_cfg80211_util.c @@ -2773,11 +2773,6 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy, t_u32 num_radio = 0, iface_stat_len = 0, radio_stat_len = 0; int err = -1, length = 0, i; char *ioctl_link_stats_buf = NULL; - mlan_ds_get_stats stats; - t_u64 cur_time = 0; - t_u64 inter_msec = 0; - t_u64 max_msec = (t_u64)24 * (t_u64)24 * (t_u64)3600 * (t_u64)1000; - moal_handle *handle = priv->phandle; /* Allocate an IOCTL request buffer */ req = woal_alloc_mlan_ioctl_req(sizeof(t_u32) + BUF_MAXLEN); @@ -2799,14 +2794,6 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy, goto done; } - /* Get Log from the firmware */ - memset(&stats, 0, sizeof(mlan_ds_get_stats)); - if (MLAN_STATUS_SUCCESS != - woal_get_stats_info(priv, MOAL_IOCTL_WAIT, &stats)) { - PRINTM(MERROR, "Error getting stats information\n"); - goto done; - } - ioctl_link_stats_buf = info->param.link_statistic; num_radio = *((t_u32 *)info->param.link_statistic); @@ -2814,44 +2801,9 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy, sizeof(num_radio)); radio_stat_len = num_radio * sizeof(wifi_radio_stat); - /* Re-write on_time/tx_time/rx_time/on_time_scan from moal handle */ - PRINTM(MINFO, "handle->on_time=%llu\n", handle->on_time); - if (handle->on_time) { - moal_get_boot_ktime(handle, &cur_time); - inter_msec = moal_do_div(cur_time - handle->on_time, 1000000); - PRINTM(MINFO, "cur_time=%llu inter_msec=%llu max_msec=%llu\n", - cur_time, inter_msec, max_msec); - /* When we report the time up, u32 is not big enough(represent - * max 49days) and might out of range, make the max value to - * 24days. - */ - if (inter_msec > max_msec) { - PRINTM(MMSG, - "Out of range, set inter_msec=%llu to max_msec=%llu\n", - inter_msec, max_msec); - inter_msec = max_msec; - } - } - PRINTM(MINFO, "handle->tx_time=%llu\n", handle->tx_time); - PRINTM(MINFO, "handle->rx_time=%llu\n", handle->rx_time); - PRINTM(MINFO, "handle->scan_time=%llu\n", handle->scan_time); - radio_stat_tmp = radio_stat; - for (i = 0; i < num_radio; i++) { - radio_stat_tmp->on_time = (t_u32)inter_msec; - radio_stat_tmp->tx_time = - (t_u32)moal_do_div(handle->tx_time, 1000); - radio_stat_tmp->rx_time = - (t_u32)moal_do_div(handle->rx_time, 1000); - radio_stat_tmp->on_time_scan = - (t_u32)moal_do_div(handle->scan_time, 1000); - radio_stat_tmp++; - } - iface_stat = (wifi_iface_stat *)(info->param.link_statistic + sizeof(num_radio) + radio_stat_len); iface_stat_len = sizeof(wifi_iface_stat); - /* Fill some fileds */ - iface_stat->beacon_rx = stats.bcn_rcv_cnt; /* could get peer info with separate cmd */ for (i = 0; i < iface_stat->num_peers; i++) { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index be9f40e..348be7d 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -2803,9 +2803,10 @@ static int woal_priv_get_sta_list(moal_private *priv, t_u8 *respbuf, strlen(PRIV_CMD_GET_STA_LIST)); moal_memcpy_ext( priv->phandle, sta_list, &info->param.sta_list, - sizeof(mlan_ds_sta_list), + ioctl_req->data_read_written, respbuflen - (strlen(CMD_NXP) + strlen(PRIV_CMD_GET_STA_LIST))); - ret = sizeof(mlan_ds_sta_list); + ret = ioctl_req->data_read_written + strlen(CMD_NXP) + + strlen(PRIV_CMD_GET_STA_LIST); done: if (status != MLAN_STATUS_PENDING) kfree(ioctl_req); @@ -10788,8 +10789,7 @@ static t_u8 woal_get_center_freq_idx(moal_private *priv, t_u8 band, #if defined(UAP_SUPPORT) /** - * @brief determine the center frquency center index for bandwidth - * of 80 MHz and 160 MHz + * @brief This function handles channel switch with CSA/ECSA IE. * ** @param priv Pointer to moal_private structure * @param block_tx 0-no need block traffic 1- need block traffic @@ -10801,7 +10801,6 @@ static t_u8 woal_get_center_freq_idx(moal_private *priv, t_u8 band, * * @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) @@ -13040,6 +13039,54 @@ done: return ret; } +/** + * @brief Set/Get transition channel + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return Number of bytes written, negative for failure. + */ +static int woal_priv_transition_channel(moal_private *priv, t_u8 *respbuf, + t_u32 respbuflen) +{ + int header_len = 0, user_data_len = 0; + int ret = 0, data[1]; + + ENTER(); + if (!priv || (priv->bss_type != MLAN_BSS_TYPE_UAP)) { + PRINTM(MERROR, "priv is null or interface is not AP"); + ret = -EFAULT; + LEAVE(); + return ret; + } + + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TRANSITION_CHANNEL); + if ((int)strlen(respbuf) == header_len) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + parse_arguments(respbuf + header_len, data, + sizeof(data) / sizeof(int), &user_data_len); + if (user_data_len > 1) { + PRINTM(MERROR, "Invalid parameter number\n"); + ret = -EINVAL; + goto done; + } + if (user_data_len) + priv->trans_chan = data[0]; + } + data[0] = priv->trans_chan; + moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data), + respbuflen); + ret = sizeof(int); +done: + + LEAVE(); + return ret; +} + #if defined(STA_CFG80211) || defined(UAP_CFG80211) #ifdef WIFI_DIRECT_SUPPORT #define DEF_NOA_INTERVAL 100 @@ -14016,14 +14063,60 @@ done: } /** - ** @brief Set extended channel switch ie - ** + * @brief send CSA/ECSA action frame + * ** @param priv Pointer to moal_private structure - ** @param respbuf Pointer to response buffer - ** @param resplen Response buffer length - ** - ** @return Number of bytes written, negative for failure. - **/ + * @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 wait_option + * + * @return channel center frequency center, if found; O, otherwise + */ +static int woal_action_channel_switch(moal_private *priv, t_u8 block_tx, + t_u8 oper_class, t_u8 channel, + t_u8 switch_count, t_u8 wait_option) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ds_bss *bss = NULL; + mlan_ioctl_req *req = NULL; + + ENTER(); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss)); + if (req == NULL) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + + bss = (mlan_ds_bss *)req->pbuf; + bss->sub_command = MLAN_OID_ACTION_CHAN_SWITCH; + req->req_id = MLAN_IOCTL_BSS; + req->action = MLAN_ACT_SET; + bss->param.chanswitch.chan_switch_mode = block_tx; + bss->param.chanswitch.new_channel_num = channel; + bss->param.chanswitch.chan_switch_count = switch_count; + bss->param.chanswitch.new_oper_class = oper_class; + ret = woal_request_ioctl(priv, req, wait_option); + if (ret != MLAN_STATUS_SUCCESS) + goto done; +done: + if (ret != MLAN_STATUS_PENDING) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief Set extended channel switch ie + * + * @param priv Pointer to moal_private structure + * @param respbuf Pointer to response buffer + * @param resplen Response buffer length + * + * @return Number of bytes written, negative for failure. + */ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) { @@ -14052,7 +14145,12 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, LEAVE(); return ret; } - + if (user_data_len < 4) { + PRINTM(MERROR, "Too few arguments\n"); + ret = -EINVAL; + LEAVE(); + return ret; + } if (data[1]) { if (woal_check_valid_channel_operclass(priv, data[2], data[1])) { @@ -14061,8 +14159,12 @@ static int woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf, goto done; } } - woal_channel_switch(priv, data[0], data[1], data[2], data[3], data[4], - MFALSE); + if (data[3]) + woal_channel_switch(priv, data[0], data[1], data[2], data[3], + data[4], MFALSE); + else + woal_action_channel_switch(priv, data[0], data[1], data[2], + data[3], MOAL_IOCTL_WAIT); done: LEAVE(); return ret; @@ -16523,10 +16625,18 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFG_GET_TSF_INFO, strlen(PRIV_CMD_CFG_GET_TSF_INFO)) == 0) { - /* Set/Get P2P OPP-PS parameters */ + /* Get TSF info */ len = woal_priv_cfg_get_tsf_info(priv, buf, priv_cmd.total_len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), + PRIV_CMD_TRANSITION_CHANNEL, + strlen(PRIV_CMD_TRANSITION_CHANNEL)) == 0) { + /* Get/Set Transition channel*/ + len = woal_priv_transition_channel(priv, buf, + priv_cmd.total_len); + goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_REPEATER_CFG, strlen(PRIV_CMD_DFS_REPEATER_CFG)) == 0) { diff --git a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index 460c97b..f186fcb 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -238,6 +238,8 @@ typedef struct _chan_stats { #endif #define PRIV_CMD_CFG_CLOCK_SYNC "clocksync" #define PRIV_CMD_CFG_GET_TSF_INFO "gettsfinfo" +#define PRIV_CMD_TRANSITION_CHANNEL "transchan" + #define PRIV_CMD_DFS_REPEATER_CFG "dfs_repeater" #ifdef WIFI_DIRECT_SUPPORT #if defined(STA_CFG80211) || defined(UAP_CFG80211) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_init.c b/mxm_wifiex/wlan_src/mlinux/moal_init.c index f16dfb1..7f1d6be 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_init.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_init.c @@ -30,6 +30,8 @@ static char *fw_name; static int req_fw_nowait; int fw_reload; +static char *hw_name; + /** MAC address */ static char *mac_addr; /** Module param cfg file */ @@ -68,6 +70,8 @@ static int auto_ds; /** net_rx mode*/ static int net_rx; +/** amsdu deaggr mode */ +static int amsdu_deaggr; static int ext_scan; @@ -593,6 +597,12 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, moal_extflg_isset(handle, EXT_FW_SERIAL) ? "on" : "off"); + } else if (strncmp(line, "hw_name", strlen("hw_name")) == 0) { + if (parse_line_read_string(line, &out_str) != + MLAN_STATUS_SUCCESS) + goto err; + woal_dup_string(¶ms->hw_name, out_str); + PRINTM(MMSG, "hw_name=%s\n", params->hw_name); } else if (strncmp(line, "mac_addr", strlen("mac_addr")) == 0) { if (parse_line_read_string(line, &out_str) != MLAN_STATUS_SUCCESS) @@ -616,6 +626,15 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, params->drv_mode = out_data; PRINTM(MMSG, "drv_mode = %d\n", params->drv_mode); } +#ifdef DEBUG_LEVEL1 + else if (strncmp(line, "drvdbg", strlen("drvdbg")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + params->drvdbg = out_data; + PRINTM(MMSG, "drvdbg = %d\n", params->drvdbg); + } +#endif #ifdef STA_SUPPORT else if (strncmp(line, "max_sta_bss", strlen("max_sta_bss")) == 0) { @@ -679,6 +698,14 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, goto err; params->net_rx = out_data; PRINTM(MMSG, "net_rx = %d\n", params->net_rx); + } else if (strncmp(line, "amsdu_deaggr", + strlen("amsdu_deaggr")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + params->amsdu_deaggr = out_data; + PRINTM(MMSG, "amsdu_deaggr = %d\n", + params->amsdu_deaggr); } else if (strncmp(line, "ext_scan", strlen("ext_scan")) == 0) { if (parse_line_read_int(line, &out_data) != MLAN_STATUS_SUCCESS) @@ -1318,6 +1345,10 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) handle->params.fw_reload = params->fw_reload; if (fw_serial) moal_extflg_set(handle, EXT_FW_SERIAL); + woal_dup_string(&handle->params.hw_name, hw_name); + if (params && params->hw_name) + woal_dup_string(&handle->params.hw_name, params->hw_name); + woal_dup_string(&handle->params.mac_addr, mac_addr); if (params && params->mac_addr) woal_dup_string(&handle->params.mac_addr, params->mac_addr); @@ -1329,6 +1360,12 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) handle->params.drv_mode = drv_mode; if (params) handle->params.drv_mode = params->drv_mode; +#ifdef DEBUG_LEVEL1 + handle->params.drvdbg = drvdbg; + if (params) + handle->params.drvdbg = params->drvdbg; +#endif + #ifdef STA_SUPPORT handle->params.max_sta_bss = max_sta_bss; woal_dup_string(&handle->params.sta_name, sta_name); @@ -1369,6 +1406,10 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) if (params) handle->params.net_rx = params->net_rx; + handle->params.amsdu_deaggr = amsdu_deaggr; + if (params) + handle->params.amsdu_deaggr = params->amsdu_deaggr; + handle->params.ext_scan = ext_scan; if (params) handle->params.ext_scan = params->ext_scan; @@ -1597,6 +1638,11 @@ void woal_free_module_param(moal_handle *handle) kfree(params->fw_name); params->fw_name = NULL; } + if (params->hw_name) { + kfree(params->hw_name); + params->hw_name = NULL; + } + if (params->mac_addr) { kfree(params->mac_addr); params->mac_addr = NULL; @@ -1781,6 +1827,12 @@ void woal_init_from_dev_tree(void) fw_name = (char *)string_data; PRINTM(MIOCTL, "fw_name=%s\n", fw_name); } + } else if (!strncmp(prop->name, "hw_name", strlen("hw_name"))) { + if (!of_property_read_string(dt_node, prop->name, + &string_data)) { + hw_name = (char *)string_data; + PRINTM(MIOCTL, "hw_name=%s\n", hw_name); + } } #if defined(STA_WEXT) || defined(UAP_WEXT) else if (!strncmp(prop->name, "cfg80211_wext", @@ -2217,6 +2269,9 @@ MODULE_PARM_DESC(hw_test, "0: Disable hardware test; 1: Enable hardware test"); module_param(dts_enable, int, 0); MODULE_PARM_DESC(dts_enable, "0: Disable DTS; 1: Enable DTS"); #endif +module_param(hw_name, charp, 0660); +MODULE_PARM_DESC(hw_name, "hardware name"); + module_param(fw_name, charp, 0660); MODULE_PARM_DESC(fw_name, "Firmware name"); module_param(req_fw_nowait, int, 0); @@ -2392,6 +2447,10 @@ MODULE_PARM_DESC(dev_cap_mask, "Device capability mask"); module_param(net_rx, int, 0); MODULE_PARM_DESC(net_rx, "0: use netif_rx_ni in rx; 1: use netif_receive_skb in rx"); +module_param(amsdu_deaggr, int, 0); +MODULE_PARM_DESC(amsdu_deaggr, + "0: default; 1: Try to avoid buf copy in amsud deaggregation"); + #ifdef SDIO module_param(sdio_rx_aggr, int, 0); MODULE_PARM_DESC(sdio_rx_aggr, diff --git a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index 8a19127..e190a45 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -252,12 +252,19 @@ t_u8 woal_is_valid_alpha2(char *alpha2) /** * @brief Get second channel offset * + * @param priv A pointer to moal_private structure * @param chan channel num * @return second channel offset */ -t_u8 woal_get_second_channel_offset(int chan) +t_u8 woal_get_second_channel_offset(moal_private *priv, int chan) { t_u8 chan2Offset = SEC_CHAN_NONE; + mlan_bss_info 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) + return chan2Offset; switch (chan) { case 36: @@ -272,6 +279,8 @@ t_u8 woal_get_second_channel_offset(int chan) case 140: case 149: case 157: + case 165: + case 173: chan2Offset = SEC_CHAN_ABOVE; break; case 40: @@ -286,12 +295,10 @@ t_u8 woal_get_second_channel_offset(int chan) case 144: case 153: case 161: + case 169: + case 177: chan2Offset = SEC_CHAN_BELOW; break; - case 165: - /* Special Case: 20Mhz-only Channel */ - chan2Offset = SEC_CHAN_NONE; - break; } return chan2Offset; } @@ -3302,6 +3309,7 @@ int woal_enable_hs(moal_private *priv) mlan_ds_ps_info pm_info; #endif pmlan_ds_misc_keep_alive keep_alive = NULL; + t_u8 media_connected = MFALSE; ENTER(); @@ -3373,8 +3381,9 @@ int woal_enable_hs(moal_private *priv) woal_reconfig_bgscan(priv->phandle); #endif + media_connected = woal_check_media_connected(handle); #if IS_ENABLED(CONFIG_IPV6) - if (handle->hs_auto_arp) { + if (handle->hs_auto_arp && media_connected) { PRINTM(MIOCTL, "Host Sleep enabled... set ipv6 offload\n"); /** Set ipv6 router advertisement message offload */ woal_set_ipv6_ra_offload(handle, MTRUE); @@ -3382,8 +3391,7 @@ int woal_enable_hs(moal_private *priv) woal_set_ipv6_ns_offload(handle); } #endif - - if (handle->hs_auto_arp) { + if (handle->hs_auto_arp && media_connected) { PRINTM(MIOCTL, "Host Sleep enabled... set FW auto arp\n"); /* Set auto arp response configuration to Fw */ woal_set_auto_arp(handle, MTRUE); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.c b/mxm_wifiex/wlan_src/mlinux/moal_main.c index 0d385dc..7a2d980 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -674,6 +674,7 @@ static mlan_callbacks woal_callbacks = { .moal_shutdown_fw_complete = moal_shutdown_fw_complete, .moal_send_packet_complete = moal_send_packet_complete, .moal_recv_packet = moal_recv_packet, + .moal_recv_amsdu_packet = moal_recv_amsdu_packet, .moal_recv_event = moal_recv_event, .moal_ioctl_complete = moal_ioctl_complete, .moal_alloc_mlan_buffer = moal_alloc_mlan_buffer, @@ -886,8 +887,9 @@ static void woal_hang_work_queue(struct work_struct *work) } } - woal_flush_workqueue(reset_handle); mlan_ioctl(reset_handle->pmlan_adapter, NULL); + woal_flush_workqueue(reset_handle); + priv = woal_get_priv(reset_handle, MLAN_BSS_ROLE_ANY); if (priv) { woal_broadcast_event(priv, CUS_EVT_DRIVER_HANG, @@ -1866,6 +1868,8 @@ mlan_status woal_init_sw(moal_handle *handle) } moal_memcpy_ext(handle, &device.callbacks, &woal_callbacks, sizeof(mlan_callbacks), sizeof(mlan_callbacks)); + if (!handle->params.amsdu_deaggr) + device.callbacks.moal_recv_amsdu_packet = NULL; device.drv_mode = handle->params.drv_mode; if (MLAN_STATUS_SUCCESS == mlan_register(&device, &pmlan)) handle->pmlan_adapter = pmlan; @@ -3594,9 +3598,6 @@ static mlan_status woal_init_fw_dpc(moal_handle *handle) handle->driver_status = MFALSE; } - moal_get_boot_ktime(handle, &handle->on_time); - PRINTM(MMSG, "on_time is %llu\n", handle->on_time); - /** data request */ memset(¶m, 0, sizeof(mlan_init_param)); @@ -6108,12 +6109,9 @@ static int woal_start_xmit(moal_private *priv, struct sk_buff *skb) goto done; } // kernel crash with cloned skb without copy + // 2 AGO case // uap0 <-->muap0 bridge - /* STA role need skb copy to improve throughput.but uAP unicast not */ - if ((moal_extflg_isset(priv->phandle, EXT_TX_SKB_CLONE)) || - (skb->cloned && priv->bss_role == MLAN_BSS_ROLE_STA) || - (skb->cloned && priv->bss_role == MLAN_BSS_ROLE_UAP && - (!is_unicast_ether_addr(((struct ethhdr *)skb->data)->h_dest))) || + if (moal_extflg_isset(priv->phandle, EXT_TX_SKB_CLONE) || skb->cloned || (skb_headroom(skb) < (MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer) + priv->extra_tx_head_len))) { @@ -6161,15 +6159,6 @@ static int woal_start_xmit(moal_private *priv, struct sk_buff *skb) status = mlan_send_packet(priv->phandle->pmlan_adapter, pmbuf); switch (status) { case MLAN_STATUS_PENDING: - if (is_zero_timeval(priv->phandle->tx_time_start)) { - priv->phandle->tx_time_start.time_sec = - pmbuf->in_ts_sec; - priv->phandle->tx_time_start.time_usec = - pmbuf->in_ts_usec; - PRINTM(MINFO, "%s : start_timeval=%d:%d \n", __func__, - priv->phandle->tx_time_start.time_sec, - priv->phandle->tx_time_start.time_usec); - } atomic_inc(&priv->phandle->tx_pending); #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) @@ -6623,6 +6612,7 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) #endif #ifdef UAP_SUPPORT + priv->trans_chan = 0; priv->user_cac_period_msec = 0; priv->chan_under_nop = MFALSE; #endif @@ -7143,12 +7133,17 @@ int woal_reassociation_thread(void *data) int i; BOOLEAN reassoc_timer_req; mlan_802_11_ssid req_ssid; - mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *ssid_bssid = NULL; mlan_status status; mlan_bss_info bss_info; t_u32 timer_val = MOAL_TIMER_10S; t_u8 zero_mac[] = {0, 0, 0, 0, 0, 0}; ENTER(); + ssid_bssid = kmalloc(sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!ssid_bssid) { + LEAVE(); + return 0; + } woal_activate_thread(pmoal_thread); init_waitqueue_entry(&wait, current); @@ -7279,7 +7274,7 @@ int woal_reassociation_thread(void *data) break; } - memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); if (priv->set_asynced_essid_flag == MTRUE) { if (priv->assoc_with_mac && @@ -7290,7 +7285,7 @@ int woal_reassociation_thread(void *data) "Reassoc: Search AP by BSSID & SSID\n"); moal_memcpy_ext( priv->phandle, - &ssid_bssid.bssid, + &ssid_bssid->bssid, &priv->prev_ssid_bssid.bssid, MLAN_MAC_ADDR_LENGTH, sizeof(mlan_802_11_mac_addr)); @@ -7301,7 +7296,8 @@ int woal_reassociation_thread(void *data) "Set asynced essid: Search AP by ESSID\n"); } - moal_memcpy_ext(priv->phandle, &ssid_bssid.ssid, + moal_memcpy_ext(priv->phandle, + &ssid_bssid->ssid, &priv->prev_ssid_bssid.ssid, sizeof(mlan_802_11_ssid), sizeof(mlan_802_11_ssid)); @@ -7310,20 +7306,20 @@ int woal_reassociation_thread(void *data) PRINTM(MINFO, "Reassoc: Search AP by BSSID first\n"); moal_memcpy_ext(priv->phandle, - &ssid_bssid.bssid, + &ssid_bssid->bssid, &priv->prev_ssid_bssid.bssid, MLAN_MAC_ADDR_LENGTH, sizeof(mlan_802_11_mac_addr)); } status = woal_find_best_network(priv, MOAL_IOCTL_WAIT, - &ssid_bssid); + ssid_bssid); #ifdef STA_WEXT if (status == MLAN_STATUS_SUCCESS) { if (MLAN_STATUS_SUCCESS != woal_11d_check_ap_channel(priv, MOAL_IOCTL_WAIT, - &ssid_bssid)) { + ssid_bssid)) { PRINTM(MERROR, "Reassoc: The AP's channel is invalid for current region\n"); status = MLAN_STATUS_FAILURE; @@ -7333,7 +7329,7 @@ int woal_reassociation_thread(void *data) /** The find AP without ssid, we need re-search */ if (status == MLAN_STATUS_SUCCESS && - !ssid_bssid.ssid.ssid_len) { + !ssid_bssid->ssid.ssid_len) { PRINTM(MINFO, "Reassoc: Skip AP without ssid\n"); status = MLAN_STATUS_FAILURE; @@ -7345,19 +7341,20 @@ int woal_reassociation_thread(void *data) "Reassoc: AP not found in scan list\n"); PRINTM(MINFO, "Reassoc: Search AP by SSID\n"); /* Search AP by SSID */ - memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); - moal_memcpy_ext(priv->phandle, &ssid_bssid.ssid, + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + moal_memcpy_ext(priv->phandle, + &ssid_bssid->ssid, &priv->prev_ssid_bssid.ssid, sizeof(mlan_802_11_ssid), sizeof(mlan_802_11_ssid)); status = woal_find_best_network( - priv, MOAL_IOCTL_WAIT, &ssid_bssid); + priv, MOAL_IOCTL_WAIT, ssid_bssid); #ifdef STA_WEXT if (status == MLAN_STATUS_SUCCESS) { if (MLAN_STATUS_SUCCESS != woal_11d_check_ap_channel( priv, MOAL_IOCTL_WAIT, - &ssid_bssid)) { + ssid_bssid)) { PRINTM(MERROR, "Reassoc: The AP's channel is invalid for current region\n"); status = MLAN_STATUS_FAILURE; @@ -7373,10 +7370,10 @@ int woal_reassociation_thread(void *data) MOAL_IOCTL_WAIT); /* Zero SSID implies use BSSID to * connect */ - memset(&ssid_bssid.ssid, 0, + memset(&ssid_bssid->ssid, 0, sizeof(mlan_802_11_ssid)); status = woal_bss_start(priv, MOAL_IOCTL_WAIT, - &ssid_bssid); + ssid_bssid); } if (priv->media_connected == MFALSE) @@ -7473,7 +7470,7 @@ int woal_reassociation_thread(void *data) } } woal_deactivate_thread(pmoal_thread); - + kfree(ssid_bssid); LEAVE(); return MLAN_STATUS_SUCCESS; } @@ -7532,7 +7529,7 @@ void woal_fw_dump_timer_func(void *context) */ void woal_update_dscp_mapping(moal_private *priv) { - mlan_ds_misc_assoc_rsp assoc_rsp; + mlan_ds_misc_assoc_rsp *assoc_rsp = NULL; IEEEtypes_AssocRsp_t *passoc_rsp = NULL; IEEEtypes_Header_t *qos_mapping_ie = NULL; DSCP_Range_t *pdscp_range = NULL; @@ -7540,14 +7537,18 @@ void woal_update_dscp_mapping(moal_private *priv) DSCP_Exception_t dscp_except[MAX_DSCP_EXCEPTION_NUM]; int i, j; ENTER(); - - memset(&assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); - woal_get_assoc_rsp(priv, &assoc_rsp, MOAL_NO_WAIT); - passoc_rsp = (IEEEtypes_AssocRsp_t *)assoc_rsp.assoc_resp_buf; + assoc_rsp = kmalloc(sizeof(mlan_ds_misc_assoc_rsp), GFP_KERNEL); + if (!assoc_rsp) { + LEAVE(); + return; + } + memset(assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); + woal_get_assoc_rsp(priv, assoc_rsp, MOAL_NO_WAIT); + passoc_rsp = (IEEEtypes_AssocRsp_t *)assoc_rsp->assoc_resp_buf; memset(priv->dscp_map, 0xFF, sizeof(priv->dscp_map)); qos_mapping_ie = (IEEEtypes_Header_t *)woal_parse_ie_tlv( passoc_rsp->ie_buffer, - assoc_rsp.assoc_resp_len - ASSOC_RESP_FIXED_SIZE, QOS_MAPPING); + assoc_rsp->assoc_resp_len - ASSOC_RESP_FIXED_SIZE, QOS_MAPPING); if (qos_mapping_ie && (qos_mapping_ie->len >= (sizeof(DSCP_Range_t) * MAX_NUM_TID))) { dscp_except_num = (qos_mapping_ie->len - @@ -7593,6 +7594,7 @@ void woal_update_dscp_mapping(moal_private *priv) } } } + kfree(assoc_rsp); LEAVE(); } @@ -8591,7 +8593,7 @@ mlan_status woal_request_country_power_table(moal_private *priv, char *country) { mlan_status ret = MLAN_STATUS_SUCCESS; moal_handle *handle = NULL; - char country_name[] = "txpower_XX.bin"; + char country_name[128]; char file_path[256]; char *last_slash = NULL; char *fw_name = NULL; @@ -8610,11 +8612,24 @@ mlan_status woal_request_country_power_table(moal_private *priv, char *country) return MLAN_STATUS_FAILURE; } handle = priv->phandle; + memset(country_name, 0, sizeof(country_name)); + if (handle->params.hw_name) + sprintf(country_name, "%s_txpower_XX.bin", + handle->params.hw_name); + else + memcpy(country_name, "txpower_XX.bin", + strlen("txpower_XX.bin")); #if defined(STA_CFG80211) || defined(UAP_CFG80211) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) - memcpy(country_name, "rgpower_XX.bin", - strlen("rgpower_XX.bin")); + if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) { + memset(country_name, 0, sizeof(country_name)); + if (handle->params.hw_name) + sprintf(country_name, "%s_rgpower_XX.bin", + handle->params.hw_name); + else + memcpy(country_name, "rgpower_XX.bin", + strlen("rgpower_XX.bin")); + } #endif #endif @@ -8656,8 +8671,13 @@ mlan_status woal_request_country_power_table(moal_private *priv, char *country) /* Try download WW rgpowertable */ if ((handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) && (ret == MLAN_STATUS_FILE_ERR)) { - memcpy(country_name, "rgpower_WW.bin", - strlen("rgpower_WW.bin")); + memset(country_name, 0, sizeof(country_name)); + if (handle->params.hw_name) + sprintf(country_name, "%s_rgpower_WW.bin", + handle->params.hw_name); + else + memcpy(country_name, "rgpower_WW.bin", + strlen("rgpower_WW.bin")); last_slash = strrchr(file_path, '/'); if (last_slash) memset(last_slash + 1, 0, @@ -8825,8 +8845,6 @@ t_void woal_rx_work_queue(struct work_struct *work) #endif #endif #endif - wifi_timeval start_timeval; - wifi_timeval end_timeval; ENTER(); if (handle->surprise_removed == MTRUE) { @@ -8834,19 +8852,8 @@ t_void woal_rx_work_queue(struct work_struct *work) return; } - woal_get_monotonic_time(&start_timeval); mlan_rx_process(handle->pmlan_adapter, NULL); - woal_get_monotonic_time(&end_timeval); - handle->rx_time += (t_u64)(timeval_to_usec(end_timeval) - - timeval_to_usec(start_timeval)); - PRINTM(MINFO, - "%s : start_timeval=%d:%d end_timeval=%d:%d inter=%llu rx_time=%llu\n", - __func__, start_timeval.time_sec, start_timeval.time_usec, - end_timeval.time_sec, end_timeval.time_usec, - (t_u64)(timeval_to_usec(end_timeval) - - timeval_to_usec(start_timeval)), - handle->rx_time); LEAVE(); } @@ -9295,6 +9302,12 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, INIT_LIST_HEAD(&handle->evt_queue); spin_lock_init(&handle->evt_lock); +#if defined(STA_CFG80211) || defined(UAP_CFG80211) +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + MLAN_INIT_WORK(&handle->regulatory_work, woal_regulatory_work_queue); +#endif +#endif + #if defined(STA_CFG80211) || defined(UAP_CFG80211) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) MLAN_INIT_WORK(&handle->host_mlme_work, woal_host_mlme_work_queue); @@ -9843,21 +9856,56 @@ done: return ret; } +/** + * @brief This function handle the pre_reset + * + * @param handle A pointer to moal_handle structure + * + * @return NULL; + */ static void woal_pre_reset(moal_handle *handle) { int intf_num; + t_u8 driver_status = handle->driver_status; + t_u8 i; + moal_private *priv = woal_get_priv(handle, MLAN_BSS_ROLE_STA); + mlan_debug_info *info = &(handle->debug_info); + int ioctl_pending = 0; + ENTER(); + if (!driver_status && priv) + woal_cancel_scan(priv, MOAL_IOCTL_WAIT); handle->driver_status = MTRUE; + + if (!driver_status) + woal_sched_timeout_uninterruptible(MOAL_TIMER_1S); + + // wait for IOCTL return + if (!driver_status && priv) { + for (i = 0; i < 5; i++) { + woal_get_debug_info(priv, MOAL_IOCTL_WAIT, info); + ioctl_pending = atomic_read(&handle->ioctl_pending); + if (!info->pending_cmd && !ioctl_pending) { + PRINTM(MCMND, + "fw_reload: No pending command and IOCTL\n"); + break; + } + woal_sched_timeout_uninterruptible(MOAL_TIMER_1S); + } + } /** detach network interface */ for (intf_num = 0; intf_num < handle->priv_num; intf_num++) { - woal_stop_queue(handle->priv[intf_num]->netdev); - netif_device_detach(handle->priv[intf_num]->netdev); + if (handle->priv[intf_num]) { + woal_stop_queue(handle->priv[intf_num]->netdev); + netif_device_detach(handle->priv[intf_num]->netdev); + } } - woal_flush_workqueue(handle); /** mask host interrupt from firmware */ mlan_disable_host_int(handle->pmlan_adapter); /** cancel all pending commands */ mlan_ioctl(handle->pmlan_adapter, NULL); + woal_flush_workqueue(handle); + handle->fw_reload = MTRUE; woal_update_firmware_name(handle); #ifdef USB @@ -9867,6 +9915,13 @@ static void woal_pre_reset(moal_handle *handle) LEAVE(); } +/** + * @brief This function handle pose_reset + * + * @param handle A pointer to moal_handle structure + * + * @return NULL; + */ static void woal_post_reset(moal_handle *handle) { mlan_ioctl_req *req = NULL; @@ -9893,12 +9948,15 @@ static void woal_post_reset(moal_handle *handle) req->action = MLAN_ACT_SET; if (MLAN_STATUS_SUCCESS != woal_request_ioctl(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), - req, MOAL_IOCTL_WAIT)) { + req, MOAL_IOCTL_WAIT_TIMEOUT)) { kfree(req); goto done; } kfree(req); } +#ifdef DEBUG_LEVEL1 + drvdbg = handle->params.drvdbg; +#endif handle->driver_status = MFALSE; handle->hardware_status = HardwareStatusReady; /* Reset all interfaces */ @@ -9906,30 +9964,35 @@ static void woal_post_reset(moal_handle *handle) MOAL_IOCTL_WAIT, MTRUE); /* Initialize private structures */ for (intf_num = 0; intf_num < handle->priv_num; intf_num++) { - woal_init_priv(handle->priv[intf_num], MOAL_IOCTL_WAIT); + if (handle->priv[intf_num]) { + woal_init_priv(handle->priv[intf_num], MOAL_IOCTL_WAIT); #ifdef WIFI_DIRECT_SUPPORT #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) #if defined(STA_WEXT) || defined(UAP_WEXT) - if ((handle->priv[intf_num]->bss_type == - MLAN_BSS_TYPE_WIFIDIRECT) && - (GET_BSS_ROLE(handle->priv[intf_num]) == - MLAN_BSS_ROLE_UAP)) { - if (MLAN_STATUS_SUCCESS != - woal_bss_role_cfg(handle->priv[intf_num], - MLAN_ACT_SET, MOAL_IOCTL_WAIT, - &bss_role)) { - goto done; + if ((handle->priv[intf_num]->bss_type == + MLAN_BSS_TYPE_WIFIDIRECT) && + (GET_BSS_ROLE(handle->priv[intf_num]) == + MLAN_BSS_ROLE_UAP)) { + if (MLAN_STATUS_SUCCESS != + woal_bss_role_cfg(handle->priv[intf_num], + MLAN_ACT_SET, + MOAL_IOCTL_WAIT, + &bss_role)) { + goto done; + } } - } #endif /* STA_WEXT || UAP_WEXT */ #endif /* STA_SUPPORT && UAP_SUPPORT */ #endif /* WIFI_DIRECT_SUPPORT */ + } } /* Enable interfaces */ for (intf_num = 0; intf_num < handle->priv_num; intf_num++) { - netif_device_attach(handle->priv[intf_num]->netdev); - woal_start_queue(handle->priv[intf_num]->netdev); + if (handle->priv[intf_num]) { + netif_device_attach(handle->priv[intf_num]->netdev); + woal_start_queue(handle->priv[intf_num]->netdev); + } } done: if (handle->dpd_data) { @@ -9986,10 +10049,7 @@ void woal_request_fw_reload(moal_handle *phandle, t_u8 mode) } else { ref_handle = (moal_handle *)handle->pref_mac; } - ref_handle->driver_status = MTRUE; } - /** start block IOCTL */ - handle->driver_status = MTRUE; if (mode == FW_RELOAD_WITH_EMULATION) { fw_reload = FW_RELOAD_WITH_EMULATION; diff --git a/mxm_wifiex/wlan_src/mlinux/moal_main.h b/mxm_wifiex/wlan_src/mlinux/moal_main.h index af8cd0d..5d6a23b 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -551,6 +551,19 @@ static inline void woal_sched_timeout(t_u32 millisec) schedule_timeout((millisec * HZ) / 1000); } +/** + * @brief Schedule timeout uninterruptible + * + * @param millisec Timeout duration in milli second + * + * @return N/A + */ +static inline void woal_sched_timeout_uninterruptible(t_u32 millisec) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout_uninterruptible((millisec * HZ) / 1000); +} + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #define IN6PTON_XDIGIT 0x00010000 #define IN6PTON_DIGIT 0x00020000 @@ -1292,6 +1305,8 @@ struct _moal_private { BOOLEAN bss_started; /** host based uap flag */ BOOLEAN uap_host_based; + /** transition channel */ + t_u8 trans_chan; /** uAP skip CAC*/ BOOLEAN skip_cac; /** tx block flag */ @@ -1734,7 +1749,11 @@ typedef struct _moal_mod_para { #ifdef MFG_CMD_SUPPORT int mfg_mode; #endif /* MFG_CMD_SUPPORT */ + char *hw_name; int drv_mode; +#ifdef DEBUG_LEVEL1 + int drvdbg; +#endif #ifdef STA_SUPPORT int max_sta_bss; char *sta_name; @@ -1754,6 +1773,7 @@ typedef struct _moal_mod_para { #endif /* WIFI_DIRECT_SUPPORT */ int auto_ds; int net_rx; + int amsdu_deaggr; int ext_scan; int ps_mode; int p2a_scan; @@ -2039,6 +2059,10 @@ struct _moal_handle { struct wiphy *wiphy; /** Country code for regulatory domain */ t_u8 country_code[COUNTRY_CODE_LEN]; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + /** regulatory work */ + struct work_struct regulatory_work; +#endif /** band */ enum ieee80211_band band; /** first scan done flag */ @@ -2230,22 +2254,6 @@ struct _moal_handle { mlan_debug_info debug_info; /* block id in module param config file */ int blk_id; - /** time when FW is active, time is get from boot time, in Nanosecond */ - t_u64 on_time; - /** tx time, in usecs */ - t_u64 tx_time; - /** systime when tx start */ - wifi_timeval tx_time_start; - /** systime when tx end */ - wifi_timeval tx_time_end; - /** rx time, in usecs */ - t_u64 rx_time; - /** scan time, in usecs */ - t_u64 scan_time; - /** systime when scan cmd response return success */ - wifi_timeval scan_time_start; - /** systime when scan event has no more event */ - wifi_timeval scan_time_end; /** seecond mac flag */ t_u8 second_mac; /** moal handle for another mac */ @@ -2914,6 +2922,7 @@ mlan_status woal_broadcast_event(moal_private *priv, t_u8 *payload, t_u32 len); mlan_status woal_switch_drv_mode(moal_handle *handle, t_u32 mode); #endif +int woal_check_media_connected(t_void *pmoal); /** check if any interface is up */ t_u8 woal_is_any_interface_active(moal_handle *handle); /** Get version */ @@ -3395,7 +3404,7 @@ mlan_status woal_set_rekey_data(moal_private *priv, mlan_status woal_vdll_req_fw(moal_handle *handle); void woal_ioctl_get_misc_conf(moal_private *priv, mlan_ds_misc_cfg *info); -t_u8 woal_get_second_channel_offset(int chan); +t_u8 woal_get_second_channel_offset(moal_private *priv, int chan); #ifdef IMX_SUPPORT void woal_regist_oob_wakeup_irq(moal_handle *handle); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/mxm_wifiex/wlan_src/mlinux/moal_shim.c index 92fd93b..759f5a2 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -51,6 +51,8 @@ Change log: #endif #endif +#include + #endif /*defined(PCIE) || defined(SDIO)*/ /******************************************************** @@ -1145,24 +1147,6 @@ mlan_status moal_send_packet_complete(t_void *pmoal, pmlan_buffer pmbuf, } done: - if ((atomic_read(&handle->tx_pending) == 0) && - !is_zero_timeval(handle->tx_time_start)) { - woal_get_monotonic_time(&handle->tx_time_end); - handle->tx_time += - (t_u64)(timeval_to_usec(handle->tx_time_end) - - timeval_to_usec(handle->tx_time_start)); - PRINTM(MINFO, - "%s : start_timeval=%d:%d end_timeval=%d:%d inter=%llu tx_time=%llu\n", - __func__, handle->tx_time_start.time_sec, - handle->tx_time_start.time_usec, - handle->tx_time_end.time_sec, - handle->tx_time_end.time_usec, - (t_u64)(timeval_to_usec(handle->tx_time_end) - - timeval_to_usec(handle->tx_time_start)), - handle->tx_time); - handle->tx_time_start.time_sec = 0; - handle->tx_time_start.time_usec = 0; - } LEAVE(); return MLAN_STATUS_SUCCESS; } @@ -1319,6 +1303,166 @@ mlan_status moal_read_reg(t_void *pmoal, t_u32 reg, t_u32 *data) #endif /* SDIO || PCIE */ +/** + * @brief This function uploads amsdu packet to the network stack + * + * @param pmoal Pointer to the MOAL context + * @param pmbuf Pointer to the mlan buffer structure + * + * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE + */ +mlan_status moal_recv_amsdu_packet(t_void *pmoal, pmlan_buffer pmbuf) +{ + mlan_status status = MLAN_STATUS_FAILURE; + struct sk_buff *skb = NULL; + struct sk_buff *frame = NULL; + int remaining; + const struct ethhdr *eth; + u8 dst[ETH_ALEN], src[ETH_ALEN]; + moal_handle *handle = (moal_handle *)pmoal; + moal_private *priv = NULL; + struct net_device *netdev = NULL; + u8 *payload; + mlan_buffer mbuf; + t_u8 drop = 0; + t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03, + 0x00, 0x00, 0x00}; + + wifi_timeval t1, t2; + t_s32 delay; + t_u32 in_ts_sec = 0; + t_u32 in_ts_usec = 0; + + ENTER(); + memset(&mbuf, 0, sizeof(mlan_buffer)); + mbuf.bss_index = pmbuf->bss_index; + + priv = woal_bss_index_to_priv(pmoal, pmbuf->bss_index); + if (priv == NULL) { + PRINTM(MERROR, "%s: priv is null\n", __func__); + goto done; + } + netdev = priv->netdev; + skb = (struct sk_buff *)pmbuf->pdesc; + if (!skb) + goto done; + + skb_reserve(skb, pmbuf->data_offset); + if (skb_tailroom(skb) < (int)pmbuf->data_len) { + PRINTM(MERROR, "skb overflow: tail room=%d, data_len=%d\n", + skb_tailroom(skb), pmbuf->data_len); + goto done; + } + skb_put(skb, pmbuf->data_len); + + // rx_trace 8 + if (handle->tp_acnt.on) { + moal_tp_accounting(pmoal, skb, RX_DROP_P4); + woal_get_monotonic_time(&t1); + in_ts_sec = t1.time_sec; + in_ts_usec = t1.time_usec; + if (pmbuf && pmbuf->in_ts_sec) { + pmbuf->out_ts_sec = t1.time_sec; + pmbuf->out_ts_usec = t1.time_usec; + } + } + if (handle->tp_acnt.drop_point == RX_DROP_P4) { + status = MLAN_STATUS_PENDING; + dev_kfree_skb(skb); + goto done; + } + + while (skb != frame) { + __be16 len; + u8 padding; + unsigned int subframe_len; + eth = (struct ethhdr *)skb->data; + len = ntohs(eth->h_proto); + subframe_len = sizeof(struct ethhdr) + len; + remaining = skb->len; + + if (subframe_len > remaining) { + PRINTM(MERROR, + "Error in len: remaining = %d, subframe_len = %d\n", + remaining, subframe_len); + break; + } + memcpy(dst, eth->h_dest, ETH_ALEN); + memcpy(src, eth->h_source, ETH_ALEN); + + padding = (4 - subframe_len) & 0x3; + + skb_pull(skb, sizeof(struct ethhdr)); + + if (remaining <= (subframe_len + padding)) { + frame = skb; + status = MLAN_STATUS_PENDING; + } else { + frame = skb_clone(skb, GFP_ATOMIC); + skb_trim(frame, len); + eth = (struct ethhdr *)skb_pull(skb, len + padding); + if (!eth) { + PRINTM(MERROR, "Invalid amsdu packet\n"); + break; + } + } + skb_reset_network_header(frame); + frame->dev = netdev; + frame->priority = skb->priority; + payload = frame->data; + if (ether_addr_equal(payload, rfc1042_eth_hdr)) { + /* Remove RFC1042 */ + skb_pull(frame, 6); + memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); + } else { + memcpy(skb_push(frame, sizeof(__be16)), &len, + sizeof(__be16)); + memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); + } + mbuf.pbuf = frame->data; + mbuf.data_len = frame->len; + mlan_process_deaggr_pkt(handle->pmlan_adapter, &mbuf, &drop); + if (drop) { + dev_kfree_skb(frame); + continue; + } + frame->protocol = eth_type_trans(frame, netdev); + frame->ip_summed = CHECKSUM_NONE; + if (in_interrupt()) + netif_rx(frame); + else { + if (atomic_read(&handle->rx_pending) > + MAX_RX_PENDING_THRHLD) + netif_rx(frame); + else { + if (handle->params.net_rx == MTRUE) { + local_bh_disable(); + netif_receive_skb(frame); + local_bh_enable(); + } else { + netif_rx_ni(frame); + } + } + } + } + if (handle->tp_acnt.on) { + if (pmbuf && pmbuf->in_ts_sec) + moal_tp_accounting(handle, pmbuf, RX_TIME_PKT); + + woal_get_monotonic_time(&t2); + delay = (t_s32)(t2.time_sec - in_ts_sec) * 1000000; + delay += (t_s32)(t2.time_usec - in_ts_usec); + moal_amsdu_tp_accounting(pmoal, delay, 0); + } +done: + if (status == MLAN_STATUS_PENDING) + atomic_dec(&handle->mbufalloc_count); + LEAVE(); + return status; +} + /** * @brief This function uploads the packet to the network stack * @@ -1631,7 +1775,7 @@ void woal_release_busfreq_pmqos_remove(t_void *handle) * @param pmoal Pointer to the MOAL context * */ -static int woal_check_media_connected(t_void *pmoal) +int woal_check_media_connected(t_void *pmoal) { int i; moal_handle *pmhandle = (moal_handle *)pmoal; @@ -1923,28 +2067,6 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) sizeof(mlan_event_id)); } - if (!is_zero_timeval(priv->phandle->scan_time_start)) { - woal_get_monotonic_time(&priv->phandle->scan_time_end); - priv->phandle->scan_time += (t_u64)( - timeval_to_usec(priv->phandle->scan_time_end) - - timeval_to_usec( - priv->phandle->scan_time_start)); - PRINTM(MINFO, - "%s : start_timeval=%d:%d end_timeval=%d:%d inter=%llu scan_time=%llu\n", - __func__, - priv->phandle->scan_time_start.time_sec, - priv->phandle->scan_time_start.time_usec, - priv->phandle->scan_time_end.time_sec, - priv->phandle->scan_time_end.time_usec, - (t_u64)(timeval_to_usec( - priv->phandle->scan_time_end) - - timeval_to_usec( - priv->phandle->scan_time_start)), - priv->phandle->scan_time); - priv->phandle->scan_time_start.time_sec = 0; - priv->phandle->scan_time_start.time_usec = 0; - } - if (priv->phandle->scan_pending_on_block == MTRUE) { priv->phandle->scan_pending_on_block = MFALSE; priv->phandle->scan_priv = NULL; @@ -2232,6 +2354,15 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) } if (!hw_test && priv->roaming_enabled) woal_config_bgscan_and_rssi(priv, MFALSE); + else { + cfg80211_cqm_rssi_notify( + priv->netdev, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + 0, +#endif + GFP_KERNEL); + } priv->last_event |= EVENT_PRE_BCN_LOST; } #endif @@ -2497,7 +2628,6 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) " Radar event for incorrect inferface \n"); } } else { - PRINTM(MEVENT, "radar detected during BSS active \n"); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (moal_extflg_isset(priv->phandle, EXT_DFS_OFFLOAD)) woal_cfg80211_dfs_vendor_event( diff --git a/mxm_wifiex/wlan_src/mlinux/moal_shim.h b/mxm_wifiex/wlan_src/mlinux/moal_shim.h index 79568f4..5765ba7 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_shim.h +++ b/mxm_wifiex/wlan_src/mlinux/moal_shim.h @@ -59,6 +59,7 @@ mlan_status moal_write_data_sync(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port, t_u32 timeout); mlan_status moal_read_data_sync(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port, t_u32 timeout); +mlan_status moal_recv_amsdu_packet(t_void *pmoal, pmlan_buffer pmbuf); mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf); mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent); mlan_status moal_malloc(t_void *pmoal, t_u32 size, t_u32 flag, t_u8 **ppbuf); diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index c115b75..5cc5665 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -2468,7 +2468,7 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, { moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); int ret = 0; - mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *ssid_bssid = NULL; unsigned long flags; const u8 *ssid_ie; int wpa_enabled = 0, group_enc_mode = 0, pairwise_enc_mode = 0; @@ -2477,6 +2477,12 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, ENTER(); + ssid_bssid = kmalloc(sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!ssid_bssid) { + LEAVE(); + return -EFAULT; + } + if (priv->auth_alg == WLAN_AUTH_SAE) { priv->auth_flag = HOST_MLME_AUTH_DONE; @@ -2509,11 +2515,11 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, priv->assoc_status = 0; priv->auth_alg = 0xFFFF; - memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); rcu_read_lock(); ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); - moal_memcpy_ext(priv->phandle, ssid_bssid.bssid, req->bss->bssid, - ETH_ALEN, sizeof(ssid_bssid.bssid)); + moal_memcpy_ext(priv->phandle, ssid_bssid->bssid, req->bss->bssid, + ETH_ALEN, sizeof(ssid_bssid->bssid)); if (!ssid_ie) { rcu_read_unlock(); @@ -2521,18 +2527,18 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, goto done; } - moal_memcpy_ext(priv->phandle, ssid_bssid.ssid.ssid, ssid_ie + 2, - ssid_ie[1], sizeof(ssid_bssid.ssid.ssid)); - ssid_bssid.ssid.ssid_len = ssid_ie[1]; + moal_memcpy_ext(priv->phandle, ssid_bssid->ssid.ssid, ssid_ie + 2, + ssid_ie[1], sizeof(ssid_bssid->ssid.ssid)); + ssid_bssid->ssid.ssid_len = ssid_ie[1]; rcu_read_unlock(); - if (ssid_bssid.ssid.ssid_len > MW_ESSID_MAX_SIZE) { + if (ssid_bssid->ssid.ssid_len > MW_ESSID_MAX_SIZE) { PRINTM(MERROR, "Invalid SSID - aborting\n"); ret = -EINVAL; goto done; } - if (!ssid_bssid.ssid.ssid_len || ssid_bssid.ssid.ssid[0] < 0x20) { + if (!ssid_bssid->ssid.ssid_len || ssid_bssid->ssid.ssid[0] < 0x20) { PRINTM(MERROR, "Invalid SSID - aborting\n"); ret = -EINVAL; goto done; @@ -2593,23 +2599,23 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, if (ret) goto done; } - ssid_bssid.host_mlme = priv->host_mlme; + ssid_bssid->host_mlme = priv->host_mlme; if (req->bss->channel) { - ssid_bssid.channel_flags = req->bss->channel->flags; - ssid_bssid.channel_flags |= CHAN_FLAGS_MAX; + ssid_bssid->channel_flags = req->bss->channel->flags; + ssid_bssid->channel_flags |= CHAN_FLAGS_MAX; PRINTM(MCMND, "channel flags=0x%x\n", req->bss->channel->flags); } if (req->prev_bssid) { - moal_memcpy_ext(priv->phandle, ssid_bssid.prev_bssid, + moal_memcpy_ext(priv->phandle, ssid_bssid->prev_bssid, req->prev_bssid, ETH_ALEN, - sizeof(ssid_bssid.prev_bssid)); + sizeof(ssid_bssid->prev_bssid)); } PRINTM(MCMND, "wlan: HostMlme %s send assoicate to bssid " MACSTR "\n", priv->netdev->name, MAC2STR(req->bss->bssid)); if (MLAN_STATUS_SUCCESS != - woal_bss_start(priv, MOAL_IOCTL_WAIT_TIMEOUT, &ssid_bssid)) { + woal_bss_start(priv, MOAL_IOCTL_WAIT_TIMEOUT, ssid_bssid)) { PRINTM(MERROR, "HostMlme %s: bss_start Fails\n", priv->netdev->name); priv->host_mlme = MFALSE; @@ -2626,7 +2632,7 @@ done: || priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT #endif ) - woal_save_assoc_params(priv, req, &ssid_bssid); + woal_save_assoc_params(priv, req, ssid_bssid); memset(&bss_info, 0, sizeof(bss_info)); woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); priv->channel = bss_info.bss_chan; @@ -2645,15 +2651,15 @@ done: "wlan: HostMlme %s Failed to connect to bssid " MACSTR "\n", priv->netdev->name, MAC2STR(req->bss->bssid)); - if (ssid_bssid.assoc_rsp.assoc_resp_len && - ssid_bssid.assoc_rsp.assoc_resp_len > + if (ssid_bssid->assoc_rsp.assoc_resp_len && + ssid_bssid->assoc_rsp.assoc_resp_len > sizeof(IEEEtypes_MgmtHdr_t)) { // save the connection param when send assoc_resp to // kernel - woal_save_assoc_params(priv, req, &ssid_bssid); + woal_save_assoc_params(priv, req, ssid_bssid); ret = 0; } else { - ssid_bssid.assoc_rsp.assoc_resp_len = 0; + ssid_bssid->assoc_rsp.assoc_resp_len = 0; ret = -EFAULT; memset(priv->cfg_bssid, 0, ETH_ALEN); if (priv->bss_type == MLAN_BSS_TYPE_STA) @@ -2666,11 +2672,11 @@ done: /*Association Response should also be send when ret is non-zero. We also need to return success when we have association response available*/ - if (ssid_bssid.assoc_rsp.assoc_resp_len) { + if (ssid_bssid->assoc_rsp.assoc_resp_len) { priv->auth_flag |= HOST_MLME_ASSOC_DONE; - woal_assoc_resp_event(priv, &ssid_bssid.assoc_rsp); + woal_assoc_resp_event(priv, &ssid_bssid->assoc_rsp); } - + kfree(ssid_bssid); LEAVE(); return ret; } @@ -2692,7 +2698,7 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, struct cfg80211_ibss_params *ibss_param = NULL; struct cfg80211_connect_params *conn_param = NULL; mlan_802_11_ssid req_ssid; - mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *ssid_bssid = NULL; mlan_ioctl_req *req = NULL; int ret = 0; t_u32 auth_type = 0, mode; @@ -2715,6 +2721,11 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, LEAVE(); return -EFAULT; } + ssid_bssid = kmalloc(sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!ssid_bssid) { + LEAVE(); + return -EFAULT; + } mode = woal_nl80211_iftype_to_mode(priv->wdev->iftype); @@ -2806,7 +2817,7 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, } memset(&req_ssid, 0, sizeof(mlan_802_11_ssid)); - memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); req_ssid.ssid_len = ssid_len; if (ssid_len > MW_ESSID_MAX_SIZE) { @@ -2825,7 +2836,7 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, if (priv->phandle->card_info->embedded_supp) if (MLAN_STATUS_SUCCESS != - woal_set_ewpa_mode(priv, wait_option, &ssid_bssid)) { + woal_set_ewpa_mode(priv, wait_option, ssid_bssid)) { ret = -EFAULT; goto done; } @@ -2984,13 +2995,13 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, goto done; } } - moal_memcpy_ext(priv->phandle, &ssid_bssid.ssid, &req_ssid, - sizeof(mlan_802_11_ssid), sizeof(ssid_bssid.ssid)); + moal_memcpy_ext(priv->phandle, &ssid_bssid->ssid, &req_ssid, + sizeof(mlan_802_11_ssid), sizeof(ssid_bssid->ssid)); if (bssid) - moal_memcpy_ext(priv->phandle, &ssid_bssid.bssid, bssid, - ETH_ALEN, sizeof(ssid_bssid.bssid)); + moal_memcpy_ext(priv->phandle, &ssid_bssid->bssid, bssid, + ETH_ALEN, sizeof(ssid_bssid->bssid)); if (MLAN_STATUS_SUCCESS != - woal_find_essid(priv, &ssid_bssid, wait_option)) { + woal_find_essid(priv, ssid_bssid, wait_option)) { /* Do specific SSID scanning */ if (mode != MLAN_BSS_MODE_IBSS) ret = woal_cfg80211_connect_scan(priv, conn_param, @@ -3010,46 +3021,46 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, if (mode != MLAN_BSS_MODE_IBSS) { if (MLAN_STATUS_SUCCESS != - woal_find_best_network(priv, wait_option, &ssid_bssid)) { + woal_find_best_network(priv, wait_option, ssid_bssid)) { ret = -EFAULT; goto done; } /* Inform the BSS information to kernel, otherwise * kernel will give a panic after successful assoc */ if (MLAN_STATUS_SUCCESS != - woal_inform_bss_from_scan_result(priv, &ssid_bssid, + woal_inform_bss_from_scan_result(priv, ssid_bssid, wait_option)) { ret = -EFAULT; goto done; } } else if (MLAN_STATUS_SUCCESS != - woal_find_best_network(priv, wait_option, &ssid_bssid)) + woal_find_best_network(priv, wait_option, ssid_bssid)) /* Adhoc start, Check the channel command */ woal_11h_channel_check_ioctl(priv, wait_option); PRINTM(MINFO, "Trying to associate to %s and bssid " MACSTR "\n", - (char *)req_ssid.ssid, MAC2STR(ssid_bssid.bssid)); + (char *)req_ssid.ssid, MAC2STR(ssid_bssid->bssid)); /* Zero SSID implies use BSSID to connect */ if (bssid) - memset(&ssid_bssid.ssid, 0, sizeof(mlan_802_11_ssid)); + memset(&ssid_bssid->ssid, 0, sizeof(mlan_802_11_ssid)); else /* Connect to BSS by ESSID */ - memset(&ssid_bssid.bssid, 0, MLAN_MAC_ADDR_LENGTH); + memset(&ssid_bssid->bssid, 0, MLAN_MAC_ADDR_LENGTH); if (channel) { - ssid_bssid.channel_flags = channel->flags; - ssid_bssid.channel_flags |= CHAN_FLAGS_MAX; + ssid_bssid->channel_flags = channel->flags; + ssid_bssid->channel_flags |= CHAN_FLAGS_MAX; PRINTM(MCMND, "channel flags=0x%x\n", channel->flags); } #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) if (conn_param && conn_param->prev_bssid) { - moal_memcpy_ext(priv->phandle, ssid_bssid.prev_bssid, + moal_memcpy_ext(priv->phandle, ssid_bssid->prev_bssid, conn_param->prev_bssid, ETH_ALEN, - sizeof(ssid_bssid.prev_bssid)); + sizeof(ssid_bssid->prev_bssid)); } #endif if (MLAN_STATUS_SUCCESS != - woal_bss_start(priv, MOAL_IOCTL_WAIT_TIMEOUT, &ssid_bssid)) { + woal_bss_start(priv, MOAL_IOCTL_WAIT_TIMEOUT, ssid_bssid)) { ret = -EFAULT; goto done; } @@ -3064,13 +3075,15 @@ int woal_cfg80211_assoc(moal_private *priv, void *sme, t_u8 wait_option, goto done; } } else if (assoc_rsp) { - moal_memcpy_ext(priv->phandle, assoc_rsp, &ssid_bssid.assoc_rsp, + moal_memcpy_ext(priv->phandle, assoc_rsp, + &ssid_bssid->assoc_rsp, sizeof(mlan_ds_misc_assoc_rsp), sizeof(mlan_ds_misc_assoc_rsp)); PRINTM(MCMND, "assoc_rsp ie len=%d\n", assoc_rsp->assoc_resp_len); } done: + kfree(ssid_bssid); if (ret) { /* clear the encryption mode */ if (MLAN_STATUS_SUCCESS != @@ -3700,13 +3713,17 @@ static int woal_update_custom_regdomain(moal_private *priv, struct wiphy *wiphy) wiphy->regulatory_flags &= ~(REGULATORY_STRICT_REG | REGULATORY_CUSTOM_REG); wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; - ret = regulatory_set_wiphy_regd(wiphy, regd); + rtnl_lock(); +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) + ret = regulatory_set_wiphy_regd_sync(wiphy, regd); +#else + ret = regulatory_set_wiphy_regd_sync_rtnl(wiphy, regd); +#endif + rtnl_unlock(); kfree(regd); - if (!ret) { - woal_sched_timeout(100); + if (!ret) woal_reg_apply_beaconing_flags( wiphy, &misc->param.custom_reg_domain); - } } done: if (status != MLAN_STATUS_PENDING) @@ -3714,6 +3731,23 @@ done: LEAVE(); return ret; } + +/** + * @brief This workqueue handles create customer regulatory + * case + * + * @param work A pointer to work_struct + * + * @return N/A + */ +void woal_regulatory_work_queue(struct work_struct *work) +{ + moal_handle *handle = container_of(work, moal_handle, regulatory_work); + struct wiphy *wiphy = handle->wiphy; + moal_private *priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); + if (priv && wiphy) + woal_update_custom_regdomain(priv, wiphy); +} #endif /** @@ -3784,7 +3818,8 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, region[2] = ' '; if ((handle->country_code[0] != request->alpha2[0]) || (handle->country_code[1] != request->alpha2[1])) { - if (handle->params.cntry_txpwr) { + if (handle->params.cntry_txpwr && + !handle->params.txpwrlimit_cfg) { t_u8 country_code[COUNTRY_CODE_LEN]; handle->country_code[0] = request->alpha2[0]; handle->country_code[1] = request->alpha2[1]; @@ -3824,22 +3859,28 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) reg_alpha2 = priv->phandle->params.reg_alpha2; if ((handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) && - reg_alpha2 && woal_is_valid_alpha2(reg_alpha2)) - woal_update_custom_regdomain(priv, wiphy); + !handle->params.txpwrlimit_cfg && reg_alpha2 && + woal_is_valid_alpha2(reg_alpha2)) + queue_work(handle->evt_workqueue, + &handle->regulatory_work); #endif break; case NL80211_REGDOM_SET_BY_CORE: PRINTM(MCMND, "Regulatory domain BY_CORE\n"); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) - woal_update_custom_regdomain(priv, wiphy); + if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE && + !handle->params.txpwrlimit_cfg) + queue_work(handle->evt_workqueue, + &handle->regulatory_work); #endif break; case NL80211_REGDOM_SET_BY_USER: PRINTM(MCMND, "Regulatory domain BY_USER\n"); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE) - woal_update_custom_regdomain(priv, wiphy); + if (handle->params.cntry_txpwr == CNTRY_RGPOWER_MODE && + !handle->params.txpwrlimit_cfg) + queue_work(handle->evt_workqueue, + &handle->regulatory_work); #endif break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: @@ -4226,12 +4267,6 @@ static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, spin_lock_irqsave(&priv->phandle->scan_req_lock, flags); priv->phandle->scan_request = request; spin_unlock_irqrestore(&priv->phandle->scan_req_lock, flags); - if (is_zero_timeval(priv->phandle->scan_time_start)) { - woal_get_monotonic_time(&priv->phandle->scan_time_start); - PRINTM(MINFO, "%s : start_timeval=%d:%d \n", __func__, - priv->phandle->scan_time_start.time_sec, - priv->phandle->scan_time_start.time_usec); - } scan_req = kmalloc(sizeof(wlan_user_scan_cfg), GFP_KERNEL); memset(scan_req, 0x00, sizeof(wlan_user_scan_cfg)); #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) @@ -4339,7 +4374,7 @@ static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, #ifdef UAP_CFG80211 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) scan_req->chan_list[i].scan_time = - MIN_SPECIFIC_SCAN_CHAN_TIME; + PASSIVE_SCAN_CHAN_TIME; #endif } if (priv->phandle->scan_request->ie && @@ -4837,7 +4872,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, unsigned long flags; mlan_ds_misc_assoc_rsp *assoc_rsp = NULL; IEEEtypes_AssocRsp_t *passoc_rsp = NULL; - mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *ssid_bssid = NULL; moal_handle *handle = priv->phandle; int i; @@ -4863,18 +4898,23 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, LEAVE(); return -EINVAL; } - memset(&ssid_bssid, 0, sizeof(ssid_bssid)); - moal_memcpy_ext(priv->phandle, &ssid_bssid.ssid.ssid, sme->ssid, - sme->ssid_len, sizeof(ssid_bssid.ssid.ssid)); - ssid_bssid.ssid.ssid_len = sme->ssid_len; + ssid_bssid = kmalloc(sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!ssid_bssid) { + LEAVE(); + return -EFAULT; + } + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + moal_memcpy_ext(priv->phandle, &ssid_bssid->ssid.ssid, sme->ssid, + sme->ssid_len, sizeof(ssid_bssid->ssid.ssid)); + ssid_bssid->ssid.ssid_len = sme->ssid_len; if (sme->bssid) - moal_memcpy_ext(priv->phandle, &ssid_bssid.bssid, sme->bssid, - ETH_ALEN, sizeof(ssid_bssid.bssid)); + moal_memcpy_ext(priv->phandle, &ssid_bssid->bssid, sme->bssid, + ETH_ALEN, sizeof(ssid_bssid->bssid)); /* Not allowed to connect to the same AP which is already connected with other interface */ for (i = 0; i < handle->priv_num; i++) { if (handle->priv[i] != priv && - MTRUE == woal_is_connected(handle->priv[i], &ssid_bssid)) { + MTRUE == woal_is_connected(handle->priv[i], ssid_bssid)) { PRINTM(MMSG, "wlan: already connected with other interface, bssid " MACSTR "\n", @@ -4924,14 +4964,14 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); /** get target bss info */ if (MLAN_STATUS_SUCCESS != - woal_find_essid(priv, &ssid_bssid, MOAL_IOCTL_WAIT)) { + woal_find_essid(priv, ssid_bssid, MOAL_IOCTL_WAIT)) { ret = woal_cfg80211_connect_scan(priv, sme, MOAL_IOCTL_WAIT); if (!ret) { if (MLAN_STATUS_SUCCESS != woal_find_best_network(priv, MOAL_IOCTL_WAIT, - &ssid_bssid)) { + ssid_bssid)) { PRINTM(MERROR, "can't find targe AP \n"); // LEAVE(); @@ -4939,9 +4979,9 @@ 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); + if (bss_info.mdid == ssid_bssid->ft_md && + bss_info.ft_cap == ssid_bssid->ft_cap) { + ret = woal_start_ft_roaming(priv, ssid_bssid); LEAVE(); return 0; } @@ -4971,7 +5011,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memset(&bss_info, 0, sizeof(bss_info)); woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); priv->channel = bss_info.bss_chan; - if (!ssid_bssid.ft_md) { + if (!ssid_bssid->ft_md) { priv->ft_ie_len = 0; priv->ft_pre_connect = MFALSE; priv->ft_md = 0; @@ -4999,7 +5039,7 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, NULL, 0, woal_get_assoc_status(priv), GFP_KERNEL); } - + kfree(ssid_bssid); kfree(assoc_rsp); assoc_rsp = NULL; LEAVE(); @@ -8180,7 +8220,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); IEEEtypes_MobilityDomain_t *md_ie = NULL; int ret = 0; - mlan_ds_misc_assoc_rsp assoc_rsp; + mlan_ds_misc_assoc_rsp *assoc_rsp = NULL; IEEEtypes_AssocRsp_t *passoc_rsp = NULL; mlan_bss_info bss_info; @@ -8194,6 +8234,11 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, LEAVE(); return ret; } + assoc_rsp = kmalloc(sizeof(mlan_ds_misc_assoc_rsp), GFP_KERNEL); + if (!assoc_rsp) { + LEAVE(); + return ret; + } #ifdef MLAN_64BIT PRINTM(MINFO, "==>woal_cfg80211_update_ft_ies %lx \n", ftie->ie_len); #else @@ -8203,6 +8248,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, ftie->ie, ftie->ie_len, MOBILITY_DOMAIN); if (!md_ie) { PRINTM(MERROR, "No Mobility domain IE\n"); + kfree(assoc_rsp); LEAVE(); return ret; } @@ -8219,6 +8265,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, priv->ft_md = ftie->md; if (!priv->ft_pre_connect) { + kfree(assoc_rsp); LEAVE(); return ret; } @@ -8226,6 +8273,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, if (!memcmp(&priv->target_ap_bssid, priv->cfg_bssid, MLAN_MAC_ADDR_LENGTH)) { PRINTM(MMSG, "This is the same AP, no Fast bss transition\n"); + kfree(assoc_rsp); priv->ft_pre_connect = MFALSE; priv->ft_ie_len = 0; LEAVE(); @@ -8238,22 +8286,22 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, moal_memcpy_ext(priv->phandle, (void *)priv->sme_current.bssid, &priv->target_ap_bssid, MLAN_MAC_ADDR_LENGTH, sizeof(priv->conn_bssid)); - memset(&assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); + memset(assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); ret = woal_cfg80211_assoc(priv, (void *)&priv->sme_current, - MOAL_IOCTL_WAIT, &assoc_rsp); + MOAL_IOCTL_WAIT, assoc_rsp); if ((priv->ft_cap & MBIT(0)) || priv->ft_roaming_triggered_by_driver) { if (!ret) { woal_inform_bss_from_scan_result(priv, NULL, MOAL_IOCTL_WAIT); passoc_rsp = (IEEEtypes_AssocRsp_t *) - assoc_rsp.assoc_resp_buf; + assoc_rsp->assoc_resp_buf; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) roam_info.bssid = priv->cfg_bssid; roam_info.req_ie = priv->sme_current.ie; roam_info.req_ie_len = priv->sme_current.ie_len; roam_info.resp_ie = passoc_rsp->ie_buffer; - roam_info.resp_ie_len = assoc_rsp.assoc_resp_len - + roam_info.resp_ie_len = assoc_rsp->assoc_resp_len - ASSOC_RESP_FIXED_SIZE; cfg80211_roamed(priv->netdev, &roam_info, GFP_KERNEL); #else @@ -8262,7 +8310,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, priv->sme_current.ie, priv->sme_current.ie_len, passoc_rsp->ie_buffer, - assoc_rsp.assoc_resp_len - + assoc_rsp->assoc_resp_len - ASSOC_RESP_FIXED_SIZE, GFP_KERNEL); #else @@ -8270,7 +8318,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, priv->sme_current.ie, priv->sme_current.ie_len, passoc_rsp->ie_buffer, - assoc_rsp.assoc_resp_len - + assoc_rsp->assoc_resp_len - ASSOC_RESP_FIXED_SIZE, GFP_KERNEL); #endif @@ -8297,13 +8345,13 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, } else { if (!ret) { - memset(&assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); - woal_get_assoc_rsp(priv, &assoc_rsp, MOAL_IOCTL_WAIT); + memset(assoc_rsp, 0, sizeof(mlan_ds_misc_assoc_rsp)); + woal_get_assoc_rsp(priv, assoc_rsp, MOAL_IOCTL_WAIT); passoc_rsp = (IEEEtypes_AssocRsp_t *) - assoc_rsp.assoc_resp_buf; + assoc_rsp->assoc_resp_buf; cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, passoc_rsp->ie_buffer, - assoc_rsp.assoc_resp_len - + assoc_rsp->assoc_resp_len - ASSOC_RESP_FIXED_SIZE, WLAN_STATUS_SUCCESS, GFP_KERNEL); @@ -8336,7 +8384,7 @@ int woal_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, // priv->ft_ie_len = 0; } } - + kfree(assoc_rsp); priv->ft_pre_connect = MFALSE; LEAVE(); return 0; @@ -8565,10 +8613,10 @@ done: void woal_start_roaming(moal_private *priv) { mlan_ds_get_signal signal; - mlan_ssid_bssid ssid_bssid; + mlan_ssid_bssid *ssid_bssid = NULL; char rssi_low[10]; int ret = 0; - mlan_ds_misc_assoc_rsp *assoc_rsp; + mlan_ds_misc_assoc_rsp *assoc_rsp = NULL; IEEEtypes_AssocRsp_t *passoc_rsp = NULL; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) struct cfg80211_roam_info roam_info = {}; @@ -8580,6 +8628,11 @@ void woal_start_roaming(moal_private *priv) LEAVE(); return; } + ssid_bssid = kmalloc(sizeof(mlan_ssid_bssid), GFP_KERNEL); + if (!ssid_bssid) { + LEAVE(); + return; + } if (priv->last_event & EVENT_BG_SCAN_REPORT) { woal_inform_bss_from_scan_result(priv, NULL, MOAL_IOCTL_WAIT); @@ -8587,6 +8640,7 @@ void woal_start_roaming(moal_private *priv) } if (priv->media_connected == MFALSE || !priv->sme_current.ssid_len) { PRINTM(MIOCTL, "Not connected, ignore roaming\n"); + kfree(ssid_bssid); LEAVE(); return; } @@ -8599,28 +8653,29 @@ void woal_start_roaming(moal_private *priv) ret = -EFAULT; goto done; } - memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); - ssid_bssid.ssid.ssid_len = priv->sme_current.ssid_len; - moal_memcpy_ext(priv->phandle, ssid_bssid.ssid.ssid, + memset(ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + ssid_bssid->ssid.ssid_len = priv->sme_current.ssid_len; + moal_memcpy_ext(priv->phandle, ssid_bssid->ssid.ssid, priv->sme_current.ssid, priv->sme_current.ssid_len, - sizeof(ssid_bssid.ssid.ssid)); + sizeof(ssid_bssid->ssid.ssid)); if (MLAN_STATUS_SUCCESS != - woal_find_best_network(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) { + woal_find_best_network(priv, MOAL_IOCTL_WAIT, ssid_bssid)) { PRINTM(MIOCTL, "Can not find better network\n"); ret = -EFAULT; goto done; } /* check if we found different AP */ - if (!memcmp(&ssid_bssid.bssid, priv->cfg_bssid, MLAN_MAC_ADDR_LENGTH)) { + if (!memcmp(&ssid_bssid->bssid, priv->cfg_bssid, + MLAN_MAC_ADDR_LENGTH)) { PRINTM(MIOCTL, "This is the same AP, no roaming\n"); ret = -EFAULT; goto done; } PRINTM(MIOCTL, "Find AP: bssid=" MACSTR ", signal=%d\n", - MAC2STR(ssid_bssid.bssid), ssid_bssid.rssi); + MAC2STR(ssid_bssid->bssid), ssid_bssid->rssi); /* check signal */ if (!(priv->last_event & EVENT_PRE_BCN_LOST)) { - if ((abs(signal.bcn_rssi_avg) - abs(ssid_bssid.rssi)) < + if ((abs(signal.bcn_rssi_avg) - abs(ssid_bssid->rssi)) < DELTA_RSSI) { PRINTM(MERROR, "New AP's signal is not good too.\n"); ret = -EFAULT; @@ -8628,16 +8683,16 @@ void woal_start_roaming(moal_private *priv) } } /**check if need start FT Roaming*/ - if (priv->ft_ie_len && (priv->ft_md == ssid_bssid.ft_md) && - (priv->ft_cap == ssid_bssid.ft_cap)) { + if (priv->ft_ie_len && (priv->ft_md == ssid_bssid->ft_md) && + (priv->ft_cap == ssid_bssid->ft_cap)) { priv->ft_roaming_triggered_by_driver = MTRUE; - woal_start_ft_roaming(priv, &ssid_bssid); + woal_start_ft_roaming(priv, ssid_bssid); goto done; } /* start roaming to new AP */ priv->sme_current.bssid = priv->conn_bssid; moal_memcpy_ext(priv->phandle, (void *)priv->sme_current.bssid, - &ssid_bssid.bssid, MLAN_MAC_ADDR_LENGTH, + &ssid_bssid->bssid, MLAN_MAC_ADDR_LENGTH, sizeof(priv->conn_bssid)); #ifdef STA_CFG80211 @@ -8734,10 +8789,11 @@ void woal_start_roaming(moal_private *priv) MAC2STR(priv->cfg_bssid)); } else { PRINTM(MIOCTL, "Roaming to bssid " MACSTR " failed\n", - MAC2STR(ssid_bssid.bssid)); + MAC2STR(ssid_bssid->bssid)); } kfree(assoc_rsp); done: + kfree(ssid_bssid); /* config rssi low threshold again */ priv->last_event = 0; priv->rssi_low = DEFAULT_RSSI_LOW_THRESHOLD; @@ -9093,6 +9149,12 @@ mlan_status woal_register_sta_cfg80211(struct net_device *dev, t_u8 bss_type) priv->wdev->ps = MFALSE; } if (priv->phandle->country_code[0] && priv->phandle->country_code[1]) { +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + if (priv->phandle->params.cntry_txpwr == CNTRY_RGPOWER_MODE && + !priv->phandle->params.txpwrlimit_cfg) + queue_work(priv->phandle->evt_workqueue, + &priv->phandle->regulatory_work); +#endif band = priv->phandle->band; priv->phandle->band = IEEE80211_BAND_2GHZ; woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); @@ -9309,7 +9371,7 @@ static void woal_update_channel_flag(struct wiphy *wiphy, mlan_fw_info *fw_info) sband = wiphy->bands[band]; if (!sband) continue; - if (sband->band & IEEE80211_BAND_5GHZ && + if (sband->band == IEEE80211_BAND_5GHZ && fw_info->prohibit_80mhz) { for (i = 0; i < sband->n_channels; i++) { sband->channels[i].flags |= @@ -9649,7 +9711,8 @@ mlan_status woal_register_cfg80211(moal_private *priv) moal_memcpy_ext(priv->phandle, priv->phandle->country_code, country, 2, 2); - woal_update_custom_regdomain(priv, wiphy); + queue_work(priv->phandle->evt_workqueue, + &priv->phandle->regulatory_work); } } #endif diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c index 2c1d016..e4db64d 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_cfg80211.c @@ -654,12 +654,14 @@ static IEEEtypes_VHTOprat_t *woal_get_vht_oprat_ie(const t_u8 *ie, int len) /** * @brief convert cfg80211_chan_def to Band_Config * + * @param priv A pointer to moal private structure * @param bandcfg A pointer to (Band_Config_t structure * @param chandef A pointer to cfg80211_chan_def structure * * @return N/A */ -static void woal_convert_chan_to_bandconfig(Band_Config_t *bandcfg, +static void woal_convert_chan_to_bandconfig(moal_private *priv, + Band_Config_t *bandcfg, struct cfg80211_chan_def *chandef) { ENTER(); @@ -681,8 +683,8 @@ static void woal_convert_chan_to_bandconfig(Band_Config_t *bandcfg, bandcfg->chan2Offset = SEC_CHAN_BELOW; break; case NL80211_CHAN_WIDTH_80: - bandcfg->chan2Offset = - woal_get_second_channel_offset(chandef->chan->hw_value); + bandcfg->chan2Offset = woal_get_second_channel_offset( + priv, chandef->chan->hw_value); bandcfg->chanWidth = CHAN_BW_80MHZ; break; case NL80211_CHAN_WIDTH_80P80: @@ -727,7 +729,7 @@ static void woal_enable_dfs_support(moal_private *priv, pchan_rpt_req = &p11h_cfg->param.chan_rpt_req; pchan_rpt_req->startFreq = 5000; pchan_rpt_req->chanNum = (t_u8)chandef->chan->hw_value; - woal_convert_chan_to_bandconfig(&pchan_rpt_req->bandcfg, chandef); + woal_convert_chan_to_bandconfig(priv, &pchan_rpt_req->bandcfg, chandef); pchan_rpt_req->host_based = MTRUE; pchan_rpt_req->millisec_dwell_time = 0; @@ -949,7 +951,8 @@ static int woal_cfg80211_beacon_config(moal_private *priv, if (priv->phandle->usr_nop_period_sec) { PRINTM(MCMND, "Checking if AP's channel %d is under NOP\n", priv->channel); - woal_convert_chan_to_bandconfig(&bandcfg, ¶ms->chandef); + woal_convert_chan_to_bandconfig(priv, &bandcfg, + ¶ms->chandef); memset(&chan_nop_info, 0, sizeof(chan_nop_info)); chan_nop_info.curr_chan = priv->channel; chan_nop_info.chan_width = bandcfg.chanWidth; @@ -994,8 +997,8 @@ static int woal_cfg80211_beacon_config(moal_private *priv, case NL80211_CHAN_WIDTH_80: case NL80211_CHAN_WIDTH_80P80: case NL80211_CHAN_WIDTH_160: - chan2Offset = - woal_get_second_channel_offset(priv->channel); + chan2Offset = woal_get_second_channel_offset( + priv, priv->channel); break; default: PRINTM(MWARN, "Unknown channel width: %d\n", @@ -1041,8 +1044,8 @@ static int woal_cfg80211_beacon_config(moal_private *priv, } else { sys_config->bandcfg.chanBand = BAND_5GHZ; #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 6, 0) - chan2Offset = - woal_get_second_channel_offset(priv->channel); + chan2Offset = woal_get_second_channel_offset( + priv, priv->channel); #endif #ifdef WIFI_DIRECT_SUPPORT @@ -1050,7 +1053,7 @@ static int woal_cfg80211_beacon_config(moal_private *priv, /* Force enable 40MHZ on WFD interface */ if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) chan2Offset = woal_get_second_channel_offset( - priv->channel); + priv, priv->channel); #endif #endif #ifdef WIFI_DIRECT_SUPPORT @@ -1902,7 +1905,8 @@ void woal_remove_virtual_interface(moal_handle *handle) if (priv->netdev->reg_state == NETREG_REGISTERED) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) - cfg80211_unregister_netdevice(priv->netdev); + cfg80211_unregister_netdevice( + priv->netdev); #else unregister_netdevice(priv->netdev); #endif @@ -3083,8 +3087,8 @@ static void woal_switch_uap_channel(moal_private *priv, t_u8 wait_option) case NL80211_CHAN_WIDTH_80P80: case NL80211_CHAN_WIDTH_160: uap_channel.bandcfg.chanWidth = CHAN_BW_80MHZ; - chan2Offset = - woal_get_second_channel_offset(uap_channel.channel); + chan2Offset = woal_get_second_channel_offset( + priv, uap_channel.channel); break; default: PRINTM(MWARN, "Unknown channel width: %d\n", @@ -3241,7 +3245,7 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy, pchan_rpt_req = &p11h_cfg->param.chan_rpt_req; pchan_rpt_req->startFreq = START_FREQ_11A_BAND; pchan_rpt_req->chanNum = (t_u8)chandef->chan->hw_value; - woal_convert_chan_to_bandconfig(&pchan_rpt_req->bandcfg, chandef); + woal_convert_chan_to_bandconfig(priv, &pchan_rpt_req->bandcfg, chandef); pchan_rpt_req->host_based = MTRUE; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c index ac3b136..72914f8 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_uap_wext.c @@ -57,7 +57,7 @@ static const chan_to_freq_t chan_to_freq[] = { {116, 5580, 1}, {120, 5600, 1}, {124, 5620, 1}, {128, 5640, 1}, {132, 5660, 1}, {136, 5680, 1}, {140, 5700, 1}, {144, 5720, 1}, {149, 5745, 1}, {153, 5765, 1}, {157, 5785, 1}, {161, 5805, 1}, - {165, 5825, 1}, + {165, 5825, 1}, {169, 5845, 1}, {173, 5865, 1}, {177, 5885, 1}, }; /**