mxm_wifiex: update to mxm5x17293 release

changes:
    1. WCSWREL-199: Fixed the build error on kernel higher than L5.12
    2. WSW-16639: Improve the throughput by avoiding skb copy in amsdu deaggreation
    3. WSW-15903: By default enabled pmqos=1 module param on IMX8 only and disable this for other platforms like X86
    4. WSFD-411: Generate fw_dump files in HAL layer instead of driver
    5. WSW-17154: Fixed the issue of driver crash seen with AGO+AGO restart stress test
    6. WSFD-416: Added WPA3 R3 support using embedded supplicant
    7. WSW-16171: Fixed the issue of DUT failed to roam to other AP2, when low RSSI hits on connected AP1
    8. WSW-17323: Fixed the issue of not activating Channel 13 using DE or JP country codes
    9. WSW-16630: APUT is not switching back from 20/40MHz to 20MHz channel bandwidth in the presence of 20MHz testbed AP
    10. WCECCB-37: Added support for UNII-4 / upper 5 GHz channels
    11. WSW-17368: Fixed the issue of System shutdown after switching AC power to battery
    12. WSW-17447: Added RTT support enablement for Android
    13. WSW-17453: Fixed the issue of 0x107 Command timeout for scan(iwlist)
    14. WSW-17019: Fixed the issue of Wifi hang with timeout cmd id 0x20 due to interference from another device doing DPD
    15. WSW-14: Added Support for IMX Linux Kernel 5.15.0
    16. WSW-17450: Disable host based Link layer stats so that fw based stats will be used

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Approved-by: Tian Yang <yang.tian@nxp.com>
This commit is contained in:
Sherry Sun 2021-12-09 12:07:20 +08:00
parent 3c2a3c2cd2
commit 255269e2d3
42 changed files with 1208 additions and 717 deletions

View File

@ -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

View File

@ -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 <use MLAN default | enable auto deepsleep | disable auto deepsleep>
ext_scan=0|1|2 <use MLAN default | Enable Extended Scan| Enable Enhanced Extended Scan>
net_rx=0|1 <use netif_rx_ni in rx | use netif_receive_skb in rx>
amsdu_deaggr=0|1 <default | Try avoid buf copy in amsud deaggregation>
ps_mode=0|1|2 <use MLAN default | enable IEEE PS mode | disable IEEE PS mode>
sched_scan=0|1 <disable sched_scan | enable sched_scan default>
max_tx_buf=2048|4096|8192 <maximum AMSDU Tx buffer size>
@ -60,6 +62,7 @@
dts_enable=0|1 <Disable DTS | Enable DTS (default)>
fw_name = <FW file name>
e.g. copy pcieuart9098_combo_v1.bin to firmware directory, fw_name=nxp/pcieuart9098_combo_v1.bin
hw_name = <hardware name>
hw_test=0|1 <Disable hardware test (default) | Enable hardware test>
fw_serial=0|1 <support parallel download FW | support serial download FW (default)>
req_fw_nowait=0|1 <use request_firmware API (default) | use request_firmware_nowait API>

View File

@ -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
}

View File

@ -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",

View File

@ -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},

View File

@ -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__,

View File

@ -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. **/

View File

@ -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;
}

View File

@ -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);

View File

@ -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(

View File

@ -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[] = {

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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) &&

View File

@ -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();

View File

@ -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)

View File

@ -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 =

View File

@ -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);

View File

@ -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.

View File

@ -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 =

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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 = {

View File

@ -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,

View File

@ -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++) {

View File

@ -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) {

View File

@ -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)

View File

@ -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(&params->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,

View File

@ -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);

View File

@ -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(&param, 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;

View File

@ -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);

View File

@ -51,6 +51,8 @@ Change log:
#endif
#endif
#include <linux/etherdevice.h>
#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(

View File

@ -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);

View File

@ -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

View File

@ -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, &params->chandef);
woal_convert_chan_to_bandconfig(priv, &bandcfg,
&params->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)

View File

@ -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},
};
/**