mxm_wifiex: update to mxm6x17423.p6 release

Corresponding firmware version:
SDIO-UART W8987 Firmware version 16.92.21.p99.2
PCIE-UART W8997 Firmware version 16.92.21.p84.4
SDIO-UART W8997 Firmware version 16.92.21.p84.4
SDIO-UART IW416 Firmware version 16.92.21.p84.128
SDIO_UART IW612 Firmware version 18.99.2.p66.10
SDIO-UART W8801 Firmware version 14.92.36.p186
SDIO-UART W9098 Firmware version 17.92.1.p136.132
PCIE-UART W9098 Firmware version 17.92.1.p136.132

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
This commit is contained in:
Sherry Sun 2023-11-13 19:13:53 +08:00
parent 983c0739ec
commit 952d10f334
24 changed files with 441 additions and 44 deletions

View file

@ -9,7 +9,7 @@
Goto source code directory wlan_src/. Goto source code directory wlan_src/.
make [clean] build make [clean] build
The driver and utility binaries can be found in ../bin_xxxx directory. The driver and utility binaries can be found in ../bin_xxxx directory.
The driver code supports Linux kernel from 2.6.32 to 6.4.7. The driver code supports Linux kernel from 2.6.32 to 6.5.4.
2) FOR DRIVER INSTALL 2) FOR DRIVER INSTALL

View file

@ -3535,6 +3535,15 @@ mlan_status wlan_11h_ioctl_chan_dfs_state(pmlan_adapter pmadapter,
wlan_11h_add_dfs_timestamp( wlan_11h_add_dfs_timestamp(
pmadapter, DFS_TS_REPR_NOP_START, pmadapter, DFS_TS_REPR_NOP_START,
ds_11hcfg->param.ch_dfs_state.channel); ds_11hcfg->param.ch_dfs_state.channel);
} else if (ds_11hcfg->param.ch_dfs_state.dfs_state ==
DFS_AVAILABLE) {
if (MFALSE ==
wlan_11h_is_channel_under_nop(
pmadapter,
ds_11hcfg->param.ch_dfs_state
.channel))
PRINTM(MINFO,
"Channel is not in NOP\n");
} }
wlan_set_chan_dfs_state( wlan_set_chan_dfs_state(
priv, BAND_A, priv, BAND_A,

View file

@ -169,21 +169,48 @@ static INLINE void wlan_11n_update_pktlen_amsdu_txpd(mlan_private *priv,
LEAVE(); LEAVE();
} }
/**
* @brief check if UAP AMSDU packet need forward out to connected peers
*
* @param priv A pointer to mlan_private
*
* @return MTRUE--packet need forward
*
*/
static t_u8 wlan_uap_check_forward(mlan_private *priv, Eth803Hdr_t *hdr)
{
/** include multicast packet */
if (hdr->dest_addr[0] & 0x01)
return MTRUE;
/** include unicast packet to another station */
if (wlan_get_station_entry(priv, hdr->dest_addr))
return MTRUE;
return MFALSE;
}
/** /**
* @brief Get number of aggregated packets * @brief Get number of aggregated packets
* *
* @param priv A pointer to mlan_private structure
* @param data A pointer to packet data * @param data A pointer to packet data
* @param total_pkt_len Total packet length * @param total_pkt_len Total packet length
* @param forward A pointer forward flag
* *
* @return Number of packets * @return Number of packets
*/ */
static int wlan_11n_get_num_aggrpkts(t_u8 *data, int total_pkt_len) static int wlan_11n_get_num_aggrpkts(mlan_private *priv, t_u8 *data,
int total_pkt_len, t_u8 *forward)
{ {
int pkt_count = 0, pkt_len, pad; int pkt_count = 0, pkt_len, pad;
t_u8 hdr_len = sizeof(Eth803Hdr_t); t_u8 hdr_len = sizeof(Eth803Hdr_t);
t_u8 forward_flag = MFALSE;
ENTER(); ENTER();
while (total_pkt_len >= hdr_len) { while (total_pkt_len >= hdr_len) {
if (priv->bss_role == MLAN_BSS_ROLE_UAP &&
wlan_uap_check_forward(priv, (Eth803Hdr_t *)data))
forward_flag = MTRUE;
/* Length will be in network format, change it to host */ /* Length will be in network format, change it to host */
pkt_len = mlan_ntohs( pkt_len = mlan_ntohs(
(*(t_u16 *)(data + (2 * MLAN_MAC_ADDR_LENGTH)))); (*(t_u16 *)(data + (2 * MLAN_MAC_ADDR_LENGTH))));
@ -199,6 +226,7 @@ static int wlan_11n_get_num_aggrpkts(t_u8 *data, int total_pkt_len)
total_pkt_len -= pkt_len + pad + sizeof(Eth803Hdr_t); total_pkt_len -= pkt_len + pad + sizeof(Eth803Hdr_t);
++pkt_count; ++pkt_count;
} }
*forward = forward_flag;
LEAVE(); LEAVE();
return pkt_count; return pkt_count;
} }
@ -229,6 +257,7 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf)
t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03, t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03,
0x00, 0x00, 0x00}; 0x00, 0x00, 0x00};
t_u8 hdr_len = sizeof(Eth803Hdr_t); t_u8 hdr_len = sizeof(Eth803Hdr_t);
t_u8 forward = MFALSE;
t_u8 eapol_type[2] = {0x88, 0x8e}; t_u8 eapol_type[2] = {0x88, 0x8e};
t_u8 tdls_action_type[2] = {0x89, 0x0d}; t_u8 tdls_action_type[2] = {0x89, 0x0d};
t_u32 in_ts_sec, in_ts_usec; t_u32 in_ts_sec, in_ts_usec;
@ -237,6 +266,7 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf)
t_u32 out_copy_ts_sec, out_copy_ts_usec; t_u32 out_copy_ts_sec, out_copy_ts_usec;
t_u32 copy_delay = 0; t_u32 copy_delay = 0;
t_u32 delay = 0; t_u32 delay = 0;
t_u8 num_subframes = 0;
ENTER(); ENTER();
@ -270,7 +300,8 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf)
if (pmadapter->tp_state_on) if (pmadapter->tp_state_on)
pmadapter->callbacks.moal_get_system_time( pmadapter->callbacks.moal_get_system_time(
pmadapter->pmoal_handle, &in_ts_sec, &in_ts_usec); pmadapter->pmoal_handle, &in_ts_sec, &in_ts_usec);
pmbuf->use_count = wlan_11n_get_num_aggrpkts(data, total_pkt_len); num_subframes = pmbuf->use_count =
wlan_11n_get_num_aggrpkts(priv, data, total_pkt_len, &forward);
// rx_trace 7 // rx_trace 7
if (pmadapter->tp_state_on) { if (pmadapter->tp_state_on) {
@ -282,13 +313,13 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf)
if (pmadapter->tp_state_drop_point == 7 /*RX_DROP_P3*/) if (pmadapter->tp_state_drop_point == 7 /*RX_DROP_P3*/)
goto done; goto done;
prx_pkt = (RxPacketHdr_t *)data; prx_pkt = (RxPacketHdr_t *)data;
if (pmbuf->pdesc && !memcmp(pmadapter, prx_pkt->eth803_hdr.dest_addr, /** check if packet need send to host only */
priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) { if (pmbuf->pdesc && !forward) {
if (pmadapter->callbacks.moal_recv_amsdu_packet) { if (pmadapter->callbacks.moal_recv_amsdu_packet) {
ret = pmadapter->callbacks.moal_recv_amsdu_packet( ret = pmadapter->callbacks.moal_recv_amsdu_packet(
pmadapter->pmoal_handle, pmbuf); pmadapter->pmoal_handle, pmbuf);
if (ret == MLAN_STATUS_PENDING) { if (ret == MLAN_STATUS_PENDING) {
priv->msdu_in_rx_amsdu_cnt += pmbuf->use_count; priv->msdu_in_rx_amsdu_cnt += num_subframes;
priv->amsdu_rx_cnt++; priv->amsdu_rx_cnt++;
return ret; return ret;
} }

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_ #define _MLAN_DECL_H_
/** MLAN release version */ /** MLAN release version */
#define MLAN_RELEASE_VERSION "423.p1" #define MLAN_RELEASE_VERSION "423.p6"
/** Re-define generic data types for MLAN/MOAL */ /** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */ /** Signed char (1-byte) */

View file

@ -1219,7 +1219,7 @@ enum host_cmd_id {
#define FW_CAPINFO_EXT_CHAN_TRACK MBIT(13) #define FW_CAPINFO_EXT_CHAN_TRACK MBIT(13)
/** FW cap info bit 14: 6G Support */ /** FW cap info bit 14: 6G Support */
#define FW_CAPINFO_EXT_6G MBIT(14) #define FW_CAPINFO_EXT_6G MBIT(14)
/** FW cap info bit 16: 6G Support */ /** FW cap info bit 16: Tx mgmt pkt with command*/
#define FW_CAPINFO_EXT_CMD_TX_DATA MBIT(16) #define FW_CAPINFO_EXT_CMD_TX_DATA MBIT(16)
/** FW cap info bit 19: security rgpower table */ /** FW cap info bit 19: security rgpower table */
#define FW_CAPINFO_EXT_SEC_RG_POWER MBIT(19) #define FW_CAPINFO_EXT_SEC_RG_POWER MBIT(19)
@ -1261,8 +1261,10 @@ enum host_cmd_id {
(_adapter->fw_cap_ext & FW_CAPINFO_EXT_CHAN_TRACK) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_CHAN_TRACK)
/** Check if 6G supported by firmware */ /** Check if 6G supported by firmware */
#define IS_FW_SUPPORT_6G(_adapter) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_6G) #define IS_FW_SUPPORT_6G(_adapter) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_6G)
/** Check if transmit mgmt pkt through command supported by firmware */
#define IS_FW_SUPPORT_CMD_TX_DATA(_adapter) \ #define IS_FW_SUPPORT_CMD_TX_DATA(_adapter) \
(_adapter->fw_cap_ext & FW_CAPINFO_EXT_CMD_TX_DATA) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_CMD_TX_DATA)
/** Check if security rgpower table supported by firmware */
#define IS_FW_SUPPORT_SEC_RG_POWER(_adapter) \ #define IS_FW_SUPPORT_SEC_RG_POWER(_adapter) \
(_adapter->fw_cap_ext & FW_CAPINFO_EXT_SEC_RG_POWER) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_SEC_RG_POWER)

View file

@ -395,6 +395,8 @@ enum _mlan_act_ioctl {
MLAN_ACT_RESET, MLAN_ACT_RESET,
MLAN_ACT_DEFAULT MLAN_ACT_DEFAULT
}; };
#define MLAN_ACT_PASN_KEY_DNLD 7
#define MLAN_ACT_PASN_SET_KEY 0
/** Enumeration for generic enable/disable */ /** Enumeration for generic enable/disable */
enum _mlan_act_generic { MLAN_ACT_DISABLE = 0, MLAN_ACT_ENABLE = 1 }; enum _mlan_act_generic { MLAN_ACT_DISABLE = 0, MLAN_ACT_ENABLE = 1 };
@ -2380,6 +2382,8 @@ typedef struct _mlan_debug_info {
t_u8 tx_lock_flag; t_u8 tx_lock_flag;
/** Corresponds to port_open member of mlan_private */ /** Corresponds to port_open member of mlan_private */
t_u8 port_open; t_u8 port_open;
/** Corresponds to tx_pause member of mlan_private */
t_u8 tx_pause;
/** bypass pkt count */ /** bypass pkt count */
t_u32 bypass_pkt_count; t_u32 bypass_pkt_count;
/** Corresponds to scan_processing member of mlan_adapter */ /** Corresponds to scan_processing member of mlan_adapter */

View file

@ -465,6 +465,7 @@ mlan_status wlan_get_info_debug_info(pmlan_adapter pmadapter,
debug_info->qos_cfg = pmpriv->wmm_qosinfo; debug_info->qos_cfg = pmpriv->wmm_qosinfo;
debug_info->tx_lock_flag = pmadapter->tx_lock_flag; debug_info->tx_lock_flag = pmadapter->tx_lock_flag;
debug_info->port_open = pmpriv->port_open; debug_info->port_open = pmpriv->port_open;
debug_info->tx_pause = pmpriv->tx_pause;
debug_info->bypass_pkt_count = pmadapter->bypass_pkt_count; debug_info->bypass_pkt_count = pmadapter->bypass_pkt_count;
debug_info->scan_processing = pmadapter->scan_processing; debug_info->scan_processing = pmadapter->scan_processing;
debug_info->scan_state = pmadapter->scan_state; debug_info->scan_state = pmadapter->scan_state;

View file

@ -3127,14 +3127,14 @@ static t_u8 wlan_get_chan_rssi(mlan_adapter *pmadapter, t_u8 channel,
for (i = 0; i < (int)pmadapter->num_in_scan_table; i++) { for (i = 0; i < (int)pmadapter->num_in_scan_table; i++) {
if (pmadapter->pscan_table[i].channel == channel) { if (pmadapter->pscan_table[i].channel == channel) {
if (rssi == 0) if (rssi == 0)
rssi = (t_s32)pmadapter->pscan_table[i].rssi; rssi = (t_u8)pmadapter->pscan_table[i].rssi;
else { else {
if (min_flag) if (min_flag)
rssi = MIN( rssi = (t_u8)MIN(
rssi, rssi,
pmadapter->pscan_table[i].rssi); pmadapter->pscan_table[i].rssi);
else else
rssi = MAX( rssi = (t_u8)MAX(
rssi, rssi,
pmadapter->pscan_table[i].rssi); pmadapter->pscan_table[i].rssi);
} }

View file

@ -2269,10 +2269,6 @@ poll_fw:
LEAVE(); LEAVE();
return ret; return ret;
} }
#ifdef SD9177
if (IS_SD9177(pmadapter->card_type))
wlan_mdelay(pmadapter, 1000);
#endif
done: done:
/* re-enable host interrupt for mlan after fw dnld is successful */ /* re-enable host interrupt for mlan after fw dnld is successful */

View file

@ -1494,6 +1494,22 @@ mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf)
return ret; return ret;
} }
/**
* @brief clean up txrx
*
* @param adapter A pointer to mlan_adapter structure
*
* @return N/A
*/
static t_void wlan_free_txrx(pmlan_adapter pmadapter)
{
t_u8 i;
for (i = 0; i < pmadapter->priv_num; i++) {
if (pmadapter->priv[i])
wlan_clean_txrx(pmadapter->priv[i]);
}
}
/** /**
* @brief MLAN ioctl handler * @brief MLAN ioctl handler
* *
@ -1512,8 +1528,9 @@ mlan_status mlan_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
ENTER(); ENTER();
if (pioctl_req == MNULL) { if (pioctl_req == MNULL) {
PRINTM(MMSG, "Cancel all pending cmd!\n"); PRINTM(MMSG, "Cancel all pending cmd and txrx queue\n");
wlan_cancel_all_pending_cmd(pmadapter, MFALSE); wlan_cancel_all_pending_cmd(pmadapter, MFALSE);
wlan_free_txrx(pmadapter);
goto exit; goto exit;
} }
pmpriv = pmadapter->priv[pioctl_req->bss_index]; pmpriv = pmadapter->priv[pioctl_req->bss_index];

View file

@ -663,17 +663,9 @@ static void wlan_process_sta_tx_pause_event(pmlan_private priv,
PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n", PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n",
MAC2STR(tx_pause_tlv->peermac), MAC2STR(tx_pause_tlv->peermac),
tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt); tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
status = wlan_get_tdls_link_status(
if (bssid && priv, tx_pause_tlv->peermac);
!memcmp(priv->adapter, bssid, tx_pause_tlv->peermac, if (status != TDLS_NOT_SETUP) {
MLAN_MAC_ADDR_LENGTH)) {
if (tx_pause_tlv->tx_pause)
priv->tx_pause = MTRUE;
else
priv->tx_pause = MFALSE;
} else {
status = wlan_get_tdls_link_status(
priv, tx_pause_tlv->peermac);
if (MTRUE == wlan_is_tdls_link_setup(status)) { if (MTRUE == wlan_is_tdls_link_setup(status)) {
sta_ptr = wlan_get_station_entry( sta_ptr = wlan_get_station_entry(
priv, tx_pause_tlv->peermac); priv, tx_pause_tlv->peermac);
@ -692,6 +684,11 @@ static void wlan_process_sta_tx_pause_event(pmlan_private priv,
} }
} }
} }
} else {
if (tx_pause_tlv->tx_pause)
priv->tx_pause = MTRUE;
else
priv->tx_pause = MFALSE;
} }
} }
tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len); tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);

View file

@ -3122,6 +3122,7 @@ static mlan_status wlan_sec_ioctl_encrypt_key(pmlan_adapter pmadapter,
ENTER(); ENTER();
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf; sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
if ((pioctl_req->action == MLAN_ACT_SET) || if ((pioctl_req->action == MLAN_ACT_SET) ||
(pioctl_req->action == MLAN_ACT_PASN_KEY_DNLD) ||
(pioctl_req->action == MLAN_ACT_CLEAR)) { (pioctl_req->action == MLAN_ACT_CLEAR)) {
if (sec->param.encrypt_key.is_wapi_key) if (sec->param.encrypt_key.is_wapi_key)
status = wlan_sec_ioctl_set_wapi_key(pmadapter, status = wlan_sec_ioctl_set_wapi_key(pmadapter,

View file

@ -718,6 +718,13 @@ static mlan_status wlan_uap_bss_ioctl_deauth_sta(pmlan_adapter pmadapter,
ENTER(); ENTER();
bss = (mlan_ds_bss *)pioctl_req->pbuf; bss = (mlan_ds_bss *)pioctl_req->pbuf;
/*
* Clean up station's ralist, to stop and flush pending traffic
* before uAP sending deauth command to FW.
*/
wlan_wmm_delete_peer_ralist(pmpriv, bss->param.deauth_param.mac_addr);
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_APCMD_STA_DEAUTH, ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_APCMD_STA_DEAUTH,
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
(t_void *)&bss->param.deauth_param); (t_void *)&bss->param.deauth_param);
@ -1042,7 +1049,8 @@ wlan_uap_sec_ioctl_set_encrypt_key(pmlan_adapter pmadapter,
ENTER(); ENTER();
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf; sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
if ((pioctl_req->action != MLAN_ACT_SET)) { if ((pioctl_req->action != MLAN_ACT_SET) &&
(pioctl_req->action != MLAN_ACT_PASN_KEY_DNLD)) {
pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
LEAVE(); LEAVE();
return MLAN_STATUS_FAILURE; return MLAN_STATUS_FAILURE;

View file

@ -3703,8 +3703,8 @@ void wlan_dump_ralist(mlan_private *priv)
tx_pkts_queued = tx_pkts_queued =
util_scalar_read(pmadapter->pmoal_handle, util_scalar_read(pmadapter->pmoal_handle,
&priv->wmm.tx_pkts_queued, MNULL, MNULL); &priv->wmm.tx_pkts_queued, MNULL, MNULL);
PRINTM(MERROR, "bss_index = %d, tx_pkts_queued = %d\n", priv->bss_index, PRINTM(MERROR, "bss_index = %d, tx_pkts_queued = %d tx_pause\n",
tx_pkts_queued); priv->bss_index, tx_pkts_queued, priv->tx_pause);
if (!tx_pkts_queued) if (!tx_pkts_queued)
return; return;
for (i = 0; i < MAX_NUM_TID; i++) { for (i = 0; i < MAX_NUM_TID; i++) {

View file

@ -24,7 +24,7 @@
#define _MLAN_DECL_H_ #define _MLAN_DECL_H_
/** MLAN release version */ /** MLAN release version */
#define MLAN_RELEASE_VERSION "423.p1" #define MLAN_RELEASE_VERSION "423.p6"
/** Re-define generic data types for MLAN/MOAL */ /** Re-define generic data types for MLAN/MOAL */
/** Signed char (1-byte) */ /** Signed char (1-byte) */

View file

@ -395,6 +395,8 @@ enum _mlan_act_ioctl {
MLAN_ACT_RESET, MLAN_ACT_RESET,
MLAN_ACT_DEFAULT MLAN_ACT_DEFAULT
}; };
#define MLAN_ACT_PASN_KEY_DNLD 7
#define MLAN_ACT_PASN_SET_KEY 0
/** Enumeration for generic enable/disable */ /** Enumeration for generic enable/disable */
enum _mlan_act_generic { MLAN_ACT_DISABLE = 0, MLAN_ACT_ENABLE = 1 }; enum _mlan_act_generic { MLAN_ACT_DISABLE = 0, MLAN_ACT_ENABLE = 1 };
@ -2380,6 +2382,8 @@ typedef struct _mlan_debug_info {
t_u8 tx_lock_flag; t_u8 tx_lock_flag;
/** Corresponds to port_open member of mlan_private */ /** Corresponds to port_open member of mlan_private */
t_u8 port_open; t_u8 port_open;
/** Corresponds to tx_pause member of mlan_private */
t_u8 tx_pause;
/** bypass pkt count */ /** bypass pkt count */
t_u32 bypass_pkt_count; t_u32 bypass_pkt_count;
/** Corresponds to scan_processing member of mlan_adapter */ /** Corresponds to scan_processing member of mlan_adapter */

View file

@ -146,6 +146,23 @@ static const struct nla_policy woal_attr_policy[ATTR_WIFI_MAX + 1] = {
[ATTR_GET_CONCURRENCY_MATRIX_SET_SIZE_MAX] = {.type = NLA_U32}, [ATTR_GET_CONCURRENCY_MATRIX_SET_SIZE_MAX] = {.type = NLA_U32},
[ATTR_SCAN_BAND_SET] = {.type = NLA_U8}, [ATTR_SCAN_BAND_SET] = {.type = NLA_U8},
}; };
static const struct nla_policy woal_secure_ranging_ctx_policy
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX + 1] = {
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION] =
{.type = NLA_U32},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR] =
{.type = NLA_STRING, .len = ETH_ALEN},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR] =
{.type = NLA_STRING, .len = ETH_ALEN},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE] =
{.type = NLA_U32},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK] =
{.type = NLA_STRING, .len = 32},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER] =
{.type = NLA_U32},
[MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED] =
{.type = NLA_STRING, .len = 48},
};
// clang-format off // clang-format off
static const struct nla_policy static const struct nla_policy
woal_nd_offload_policy[ATTR_ND_OFFLOAD_MAX + 1] = { woal_nd_offload_policy[ATTR_ND_OFFLOAD_MAX + 1] = {
@ -2899,11 +2916,6 @@ static int woal_cfg80211_subcmd_link_statistic_get(struct wiphy *wiphy,
t_u64 inter_msec = 0; t_u64 inter_msec = 0;
t_u64 max_msec = (t_u64)24 * (t_u64)24 * (t_u64)3600 * (t_u64)1000; t_u64 max_msec = (t_u64)24 * (t_u64)24 * (t_u64)3600 * (t_u64)1000;
moal_handle *handle = priv->phandle; moal_handle *handle = priv->phandle;
if (!priv->media_connected) {
PRINTM(MERROR,
"Block get_link_statistics in disconnected state!\n");
return -EINVAL;
}
/* Allocate an IOCTL request buffer */ /* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(t_u32) + BUF_MAXLEN); req = woal_alloc_mlan_ioctl_req(sizeof(t_u32) + BUF_MAXLEN);
@ -3934,6 +3946,181 @@ done:
LEAVE(); LEAVE();
return ret; return ret;
} }
/**
* @brief vendor command to start
* woal_cfg80211_subcmd_secure_ranging_ctx
*
* @param wiphy A pointer to wiphy struct
* @param wdev A pointer to wireless_dev struct
* @param data a pointer to data
* @param len data length
*
* @return 0: success fail otherwise
*/
static int woal_cfg80211_subcmd_secure_ranging_ctx(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int len)
{
moal_private *priv;
struct net_device *dev;
mlan_ioctl_req *req = NULL;
mlan_ds_sec_cfg *sec = NULL;
mlan_status ret = MLAN_STATUS_SUCCESS;
int type, rem;
t_u32 action = 0;
int key_len = 0;
int peer_addr_set = 0;
t_u8 peer_addr[ETH_ALEN];
t_u8 own_addr[ETH_ALEN];
t_u32 cipher = 0;
t_u32 sha_type = 0;
t_u8 key[MLAN_MAX_KEY_LENGTH] = {0};
t_u8 *ltf_keyseed = NULL;
t_u8 bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const struct nlattr *iter;
ENTER();
if (!wdev || !wdev->netdev) {
LEAVE();
return -EFAULT;
}
dev = wdev->netdev;
priv = (moal_private *)woal_get_netdev_priv(dev);
if (!priv) {
LEAVE();
return -EFAULT;
}
nla_for_each_attr (iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION:
action = nla_get_u32(iter);
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR:
moal_memcpy_ext(priv->phandle, own_addr, nla_data(iter),
nla_len(iter), ETH_ALEN);
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR:
moal_memcpy_ext(priv->phandle, peer_addr,
nla_data(iter), nla_len(iter),
ETH_ALEN);
peer_addr_set = 1;
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE:
sha_type = nla_get_u32(iter);
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK:
moal_memcpy_ext(priv->phandle, key, nla_data(iter),
nla_len(iter), MLAN_MAX_KEY_LENGTH);
key_len = nla_len(iter);
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER:
cipher = nla_get_u32(iter);
break;
case MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED:
moal_memcpy_ext(priv->phandle, ltf_keyseed,
nla_data(iter), nla_len(iter), 48);
break;
default:
PRINTM(MERROR, "Unknown type: %d\n", type);
ret = -EINVAL;
}
}
/* Allocate an IOCTL request buffer */
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
if (req == NULL) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* Fill request buffer */
sec = (mlan_ds_sec_cfg *)req->pbuf;
sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
req->req_id = MLAN_IOCTL_SEC_CFG;
if (action == MLAN_ACT_PASN_SET_KEY) {
req->action = MLAN_ACT_PASN_KEY_DNLD;
if (key_len) {
moal_memcpy_ext(priv->phandle,
sec->param.encrypt_key.key_material,
key, key_len, MLAN_MAX_KEY_LENGTH);
sec->param.encrypt_key.key_len = key_len;
}
if (peer_addr_set) {
moal_memcpy_ext(priv->phandle,
sec->param.encrypt_key.mac_addr,
peer_addr, ETH_ALEN,
MLAN_MAC_ADDR_LENGTH);
if (memcmp(sec->param.encrypt_key.mac_addr, bcast_addr,
ETH_ALEN) == 0)
sec->param.encrypt_key.key_flags =
KEY_FLAG_GROUP_KEY;
else
sec->param.encrypt_key.key_flags =
KEY_FLAG_SET_TX_KEY;
} else {
moal_memcpy_ext(priv->phandle,
sec->param.encrypt_key.mac_addr,
bcast_addr, ETH_ALEN,
MLAN_MAC_ADDR_LENGTH);
sec->param.encrypt_key.key_flags =
KEY_FLAG_GROUP_KEY | KEY_FLAG_SET_TX_KEY;
}
#if KERNEL_VERSION(3, 6, 0) <= CFG80211_VERSION_CODE
if (cipher == WLAN_CIPHER_SUITE_GCMP)
sec->param.encrypt_key.key_flags |= KEY_FLAG_GCMP;
#endif
#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE
else if (cipher == WLAN_CIPHER_SUITE_GCMP_256)
sec->param.encrypt_key.key_flags |= KEY_FLAG_GCMP_256;
#endif
#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE
if (cipher == WLAN_CIPHER_SUITE_CCMP_256)
sec->param.encrypt_key.key_flags |= KEY_FLAG_CCMP_256;
#endif
if (cipher == WLAN_CIPHER_SUITE_AES_CMAC
#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE
|| cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256
#endif
) {
sec->param.encrypt_key.key_flags |=
KEY_FLAG_AES_MCAST_IGTK;
#if KERNEL_VERSION(4, 0, 0) <= CFG80211_VERSION_CODE
if (cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128)
sec->param.encrypt_key.key_flags |=
KEY_FLAG_GMAC_128;
else if (cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
sec->param.encrypt_key.key_flags |=
KEY_FLAG_GMAC_256;
#endif
}
} else {
req->action = MLAN_ACT_CLEAR;
sec->param.encrypt_key.key_len = MLAN_MAX_KEY_LENGTH;
sec->param.encrypt_key.key_index = MLAN_KEY_INDEX_UNICAST;
sec->param.encrypt_key.key_flags = KEY_FLAG_REMOVE_KEY;
moal_memcpy_ext(priv->phandle, sec->param.encrypt_key.mac_addr,
(u8 *)peer_addr, ETH_ALEN,
MLAN_MAC_ADDR_LENGTH);
memset(sec->param.encrypt_key.key_material, 0,
sizeof(sec->param.encrypt_key.key_material));
}
/* Send IOCTL request to MLAN */
ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
done:
if (ret != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/** /**
* @brief vendor command to * @brief vendor command to
* *
@ -5487,6 +5674,19 @@ static const struct wiphy_vendor_command vendor_commands[] = {
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE #if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = woal_attr_policy, .policy = woal_attr_policy,
.maxattr = ATTR_WIFI_MAX, .maxattr = ATTR_WIFI_MAX,
#endif
},
{
.info = {
.vendor_id = MRVL_VENDOR_ID,
.subcmd = sub_cmd_secure_ranging_ctx,
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = woal_cfg80211_subcmd_secure_ranging_ctx,
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = woal_secure_ranging_ctx_policy,
.maxattr = MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX,
#endif #endif
}, },
{ {

View file

@ -616,6 +616,21 @@ typedef enum wifi_attr {
ATTR_WIFI_AFTER_LAST, ATTR_WIFI_AFTER_LAST,
ATTR_WIFI_MAX = ATTR_WIFI_AFTER_LAST - 1 ATTR_WIFI_MAX = ATTR_WIFI_AFTER_LAST - 1
} wifi_attr_t; } wifi_attr_t;
enum mrvl_wlan_vendor_attr_secure_ranging_ctx {
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_INVALID = 0,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION = 1,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR = 2,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR = 3,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE = 4,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK = 5,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER = 6,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED = 7,
/* keep last */
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_AFTER_LAST,
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX =
MRVL_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_AFTER_LAST - 1,
};
enum mrvl_wlan_vendor_attr_wifi_logger { enum mrvl_wlan_vendor_attr_wifi_logger {
MRVL_WLAN_VENDOR_ATTR_NAME = 10, MRVL_WLAN_VENDOR_ATTR_NAME = 10,
}; };
@ -708,6 +723,7 @@ enum vendor_sub_command {
sub_cmd_dfs_capability = 0x0005, sub_cmd_dfs_capability = 0x0005,
sub_cmd_set_scan_mac_oui = 0x0007, sub_cmd_set_scan_mac_oui = 0x0007,
sub_cmd_set_scan_band = 0x0008, sub_cmd_set_scan_band = 0x0008,
sub_cmd_secure_ranging_ctx = 0x0009,
sub_cmd_set_packet_filter = 0x0011, sub_cmd_set_packet_filter = 0x0011,
sub_cmd_get_packet_filter_capability, sub_cmd_get_packet_filter_capability,
sub_cmd_nd_offload = 0x0100, sub_cmd_nd_offload = 0x0100,

View file

@ -113,6 +113,7 @@ static struct debug_data items[] = {
{"tx_lock_flag", item_size(tx_lock_flag), item_addr(tx_lock_flag), {"tx_lock_flag", item_size(tx_lock_flag), item_addr(tx_lock_flag),
INFO_ADDR}, INFO_ADDR},
{"port_open", item_size(port_open), item_addr(port_open), INFO_ADDR}, {"port_open", item_size(port_open), item_addr(port_open), INFO_ADDR},
{"tx_pause", item_size(tx_pause), item_addr(tx_pause), INFO_ADDR},
{"bypass_pkt_count", item_size(bypass_pkt_count), {"bypass_pkt_count", item_size(bypass_pkt_count),
item_addr(bypass_pkt_count), INFO_ADDR}, item_addr(bypass_pkt_count), INFO_ADDR},
{"scan_processing", item_size(scan_processing), {"scan_processing", item_size(scan_processing),
@ -309,6 +310,7 @@ static struct debug_data uap_items[] = {
INFO_ADDR}, INFO_ADDR},
{"tx_pkts_queued", item_size(tx_pkts_queued), item_addr(tx_pkts_queued), {"tx_pkts_queued", item_size(tx_pkts_queued), item_addr(tx_pkts_queued),
INFO_ADDR}, INFO_ADDR},
{"tx_pause", item_size(tx_pause), item_addr(tx_pause), INFO_ADDR},
{"bypass_pkt_count", item_size(bypass_pkt_count), {"bypass_pkt_count", item_size(bypass_pkt_count),
item_addr(bypass_pkt_count), INFO_ADDR}, item_addr(bypass_pkt_count), INFO_ADDR},
{"num_bridge_pkts", item_size(num_bridge_pkts), {"num_bridge_pkts", item_size(num_bridge_pkts),

View file

@ -5593,6 +5593,7 @@ void woal_remove_interface(moal_handle *handle, t_u8 bss_index)
if (dev->reg_state == NETREG_REGISTERED) if (dev->reg_state == NETREG_REGISTERED)
unregister_netdev(dev); unregister_netdev(dev);
woal_sched_timeout(100);
if (priv->mclist_workqueue) { if (priv->mclist_workqueue) {
flush_workqueue(priv->mclist_workqueue); flush_workqueue(priv->mclist_workqueue);
destroy_workqueue(priv->mclist_workqueue); destroy_workqueue(priv->mclist_workqueue);
@ -6690,6 +6691,7 @@ void woal_mlan_debug_info(moal_private *priv)
info->sleep_pd); info->sleep_pd);
PRINTM(MERROR, "tx_lock_flag = %d\n", info->tx_lock_flag); PRINTM(MERROR, "tx_lock_flag = %d\n", info->tx_lock_flag);
PRINTM(MERROR, "port_open = %d\n", info->port_open); PRINTM(MERROR, "port_open = %d\n", info->port_open);
PRINTM(MERROR, "tx_pause = %d\n", info->tx_pause);
PRINTM(MERROR, "scan_processing = %d\n", info->scan_processing); PRINTM(MERROR, "scan_processing = %d\n", info->scan_processing);
PRINTM(MERROR, "scan_state = 0x%x\n", info->scan_state); PRINTM(MERROR, "scan_state = 0x%x\n", info->scan_state);
for (i = 0; i < (int)info->ralist_num; i++) { for (i = 0; i < (int)info->ralist_num; i++) {
@ -6761,6 +6763,12 @@ void woal_tx_timeout(struct net_device *dev
priv->num_tx_timeout++; priv->num_tx_timeout++;
PRINTM(MERROR, "%lu : %s (bss=%d): Tx timeout (%d)\n", jiffies, PRINTM(MERROR, "%lu : %s (bss=%d): Tx timeout (%d)\n", jiffies,
dev->name, priv->bss_index, priv->num_tx_timeout); dev->name, priv->bss_index, priv->num_tx_timeout);
PRINTM(MERROR, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
PRINTM(MERROR, "tx_pending = %d\n",
atomic_read(&priv->phandle->tx_pending));
if (priv->num_tx_timeout < NUM_TX_TIMEOUT_THRESHOLD)
woal_mlan_debug_info(priv);
woal_set_trans_start(dev); woal_set_trans_start(dev);
if (priv->num_tx_timeout == NUM_TX_TIMEOUT_THRESHOLD && if (priv->num_tx_timeout == NUM_TX_TIMEOUT_THRESHOLD &&
@ -10384,6 +10392,7 @@ static int woal_dump_mlan_drv_info(moal_private *priv, t_u8 *buf)
ptr += snprintf(ptr, MAX_BUF_LEN, "tx_lock_flag = %d\n", ptr += snprintf(ptr, MAX_BUF_LEN, "tx_lock_flag = %d\n",
info->tx_lock_flag); info->tx_lock_flag);
ptr += snprintf(ptr, MAX_BUF_LEN, "port_open = %d\n", info->port_open); ptr += snprintf(ptr, MAX_BUF_LEN, "port_open = %d\n", info->port_open);
ptr += snprintf(ptr, MAX_BUF_LEN, "tx_pause = %d\n", info->tx_pause);
ptr += snprintf(ptr, MAX_BUF_LEN, "scan_processing = %d\n", ptr += snprintf(ptr, MAX_BUF_LEN, "scan_processing = %d\n",
info->scan_processing); info->scan_processing);
ptr += snprintf(ptr, MAX_BUF_LEN, "scan_state = %d\n", ptr += snprintf(ptr, MAX_BUF_LEN, "scan_state = %d\n",

View file

@ -231,6 +231,49 @@ static t_u16 woal_update_card_type(t_void *card)
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
/**
* @brief Function to program scratch register to ask device to clear ADMA
*
* @param handle A pointer to moal_handle structure
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
static mlan_status woal_reset_adma(moal_handle *handle)
{
int tries = 0;
int ret = MLAN_STATUS_SUCCESS;
t_u32 value;
t_u32 reset_reg = handle->card_info->fw_reset_reg;
t_u8 reset_adma_val = 0x97;
if (handle->ops.write_reg(handle, reset_reg, reset_adma_val) !=
MLAN_STATUS_SUCCESS) {
PRINTM(MERROR, "Failed to write register.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
for (tries = 0; tries < 100; ++tries) {
ret = handle->ops.read_reg(handle, reset_reg, &value);
if (value == 0) {
break;
}
moal_usleep_range(handle, 100, 200);
}
if (value == 0) {
PRINTM(MMSG, "%s:ADMA reset done\n", __func__);
ret = MLAN_STATUS_SUCCESS;
} else {
PRINTM(MERROR, "%s:ADMA reset failed(value:%x)\n", __func__,
value);
ret = MLAN_STATUS_FAILURE;
}
done:
return ret;
}
/** /**
* @brief Function to process pre/post PCIe function level reset * @brief Function to process pre/post PCIe function level reset
* *
@ -290,6 +333,7 @@ static mlan_status woal_do_flr(moal_handle *handle, bool prepare, bool flr_flag)
priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY);
woal_reset_intf(priv, MOAL_IOCTL_WAIT, MTRUE); woal_reset_intf(priv, MOAL_IOCTL_WAIT, MTRUE);
woal_clean_up(handle); woal_clean_up(handle);
mlan_ioctl(handle->pmlan_adapter, NULL);
/* Shutdown firmware */ /* Shutdown firmware */
handle->init_wait_q_woken = MFALSE; handle->init_wait_q_woken = MFALSE;
@ -830,6 +874,12 @@ static void woal_pcie_reset_prepare(struct pci_dev *pdev)
} }
} }
handle->surprise_removed = MTRUE; handle->surprise_removed = MTRUE;
// TODO: Can add more chips once the related code has been ported to fw
// v18
if (IS_PCIE9097(handle->card_type) || IS_PCIE9098(handle->card_type)) {
woal_reset_adma(handle);
}
woal_do_flr(handle, true, true); woal_do_flr(handle, true, true);
if (ref_handle) { if (ref_handle) {
ref_handle->surprise_removed = MTRUE; ref_handle->surprise_removed = MTRUE;
@ -934,6 +984,12 @@ static void woal_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
* Note. FW might not be healthy. * Note. FW might not be healthy.
*/ */
handle->surprise_removed = MTRUE; handle->surprise_removed = MTRUE;
// TODO: Can add more chips once the related code has been
// ported to fw v18
if (IS_PCIE9097(handle->card_type) ||
IS_PCIE9098(handle->card_type)) {
woal_reset_adma(handle);
}
woal_do_flr(handle, prepare, true); woal_do_flr(handle, prepare, true);
if (ref_handle) { if (ref_handle) {
ref_handle->surprise_removed = MTRUE; ref_handle->surprise_removed = MTRUE;

View file

@ -555,6 +555,28 @@ void woal_sdio_remove(struct sdio_func *func)
PRINTM(MINFO, "SDIO func=%d\n", func->num); PRINTM(MINFO, "SDIO func=%d\n", func->num);
card = sdio_get_drvdata(func); card = sdio_get_drvdata(func);
if (card) { if (card) {
/* We need to advance the time to set surprise_removed
* to MTRUE as fast as possible to avoid race condition
* with woal_sdio_interrupt()
*
* @todo: Due to woal_sdio_interrupt() is called in
* Linux's work queue, cannot be suspended to impact
* other works. Need a lock in these two functions:
* woal_sdio_remove() waits until woal_sdio_interrupt
* ends. woal_sdio_interrupt() returns if
* woal_sdio_remove() is running.
*/
if (card->handle != NULL) {
card->handle->surprise_removed = MTRUE;
/* check if woal_sdio_interrupt() is running */
while (card->handle->main_state !=
MOAL_END_MAIN_PROCESS)
woal_sched_timeout(2); /* wait until
woal_sdio_interrupt
ends */
}
#ifdef IMX_SUPPORT #ifdef IMX_SUPPORT
woal_unregist_oob_wakeup_irq(card->handle); woal_unregist_oob_wakeup_irq(card->handle);
#endif /* IMX_SUPPORT */ #endif /* IMX_SUPPORT */

View file

@ -4588,8 +4588,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
tx_status_event *tx_status = tx_status_event *tx_status =
(tx_status_event *)(pmevent->event_buf + 4); (tx_status_event *)(pmevent->event_buf + 4);
struct tx_status_info *tx_info = NULL; struct tx_status_info *tx_info = NULL;
PRINTM(MINFO, PRINTM(MEVENT,
"Receive Tx status: tx_token=%d, pkt_type=0x%x, status=%d tx_seq_num=%d\n", "Wlan: Tx status: tx_token=%d, pkt_type=0x%x, status=%d priv->tx_seq_num=%d\n",
tx_status->tx_token_id, tx_status->packet_type, tx_status->tx_token_id, tx_status->packet_type,
tx_status->status, priv->tx_seq_num); tx_status->status, priv->tx_seq_num);
spin_lock_irqsave(&priv->tx_stat_lock, flag); spin_lock_irqsave(&priv->tx_stat_lock, flag);

View file

@ -4591,6 +4591,15 @@ static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
return -EBUSY; return -EBUSY;
} }
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
/* This check is to prevent the situation where
* new scan request comes while Auth is not completed */
if (priv->auth_flag & HOST_MLME_AUTH_PENDING) {
PRINTM(MCMND, "Block scan as auth is pending\n");
LEAVE();
return -EAGAIN;
}
#endif
spin_lock_irqsave(&priv->phandle->scan_req_lock, flags); spin_lock_irqsave(&priv->phandle->scan_req_lock, flags);
priv->phandle->scan_request = request; priv->phandle->scan_request = request;
spin_unlock_irqrestore(&priv->phandle->scan_req_lock, flags); spin_unlock_irqrestore(&priv->phandle->scan_req_lock, flags);
@ -8043,12 +8052,13 @@ static int woal_send_tdls_action_frame(struct wiphy *wiphy,
pmbuf = woal_alloc_mlan_buffer( pmbuf = woal_alloc_mlan_buffer(
priv->phandle, priv->phandle,
MLAN_MIN_DATA_HEADER_LEN + HEADER_SIZE + sizeof(pkt_len) + ((int)((MLAN_MIN_DATA_HEADER_LEN + HEADER_SIZE +
sizeof(pkt_len) +
max(sizeof(struct ieee80211_mgmt), max(sizeof(struct ieee80211_mgmt),
sizeof(struct ieee80211_tdls_data)) + sizeof(struct ieee80211_tdls_data))) +
50 + /* supported rates */ 50 + /* supported rates */
sizeof(IEEEtypes_ExtCap_t) + /* ext capab */ sizeof(IEEEtypes_ExtCap_t) + /* ext capab */
extra_ies_len + sizeof(IEEEtypes_tdls_linkie)); extra_ies_len + sizeof(IEEEtypes_tdls_linkie))));
if (!pmbuf) { if (!pmbuf) {
PRINTM(MERROR, "Fail to allocate mlan_buffer\n"); PRINTM(MERROR, "Fail to allocate mlan_buffer\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -10433,7 +10443,8 @@ mlan_status woal_register_cfg80211(moal_private *priv)
PRINTM(MIOCTL, "Follow countryIE provided by AP.\n"); PRINTM(MIOCTL, "Follow countryIE provided by AP.\n");
} }
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) && CFG80211_VERSION_CODE < KERNEL_VERSION(6, 1, 39) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
#if CFG80211_VERSION_CODE <= KERNEL_VERSION(6, 1, 38)
/*REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make /*REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make
* sure all interfaces on this wiphy reside on allowed channels. If this * sure all interfaces on this wiphy reside on allowed channels. If this
* flag is not set, upon a regdomain change, the interfaces are given a * flag is not set, upon a regdomain change, the interfaces are given a
@ -10441,7 +10452,18 @@ mlan_status woal_register_cfg80211(moal_private *priv)
* allowed channel.*/ * allowed channel.*/
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
#endif #endif
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
#if CFG80211_VERSION_CODE <= KERNEL_VERSION(6, 3, 12)
/*REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make
* sure all interfaces on this wiphy reside on allowed channels. If this
* flag is not set, upon a regdomain change, the interfaces are given a
* grace period (currently 60 seconds) to disconnect or move to an
* allowed channel.*/
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
#endif
#endif
memset(&priv->phandle->country_code, 0, memset(&priv->phandle->country_code, 0,
sizeof(priv->phandle->country_code)); sizeof(priv->phandle->country_code));
priv->phandle->dfs_region = NXP_DFS_UNKNOWN; priv->phandle->dfs_region = NXP_DFS_UNKNOWN;