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/.
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 6.4.7.
The driver code supports Linux kernel from 2.6.32 to 6.5.4.
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(
pmadapter, DFS_TS_REPR_NOP_START,
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(
priv, BAND_A,

View file

@ -169,21 +169,48 @@ static INLINE void wlan_11n_update_pktlen_amsdu_txpd(mlan_private *priv,
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
*
* @param priv A pointer to mlan_private structure
* @param data A pointer to packet data
* @param total_pkt_len Total packet length
* @param forward A pointer forward flag
*
* @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;
t_u8 hdr_len = sizeof(Eth803Hdr_t);
t_u8 forward_flag = MFALSE;
ENTER();
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 */
pkt_len = mlan_ntohs(
(*(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);
++pkt_count;
}
*forward = forward_flag;
LEAVE();
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,
0x00, 0x00, 0x00};
t_u8 hdr_len = sizeof(Eth803Hdr_t);
t_u8 forward = MFALSE;
t_u8 eapol_type[2] = {0x88, 0x8e};
t_u8 tdls_action_type[2] = {0x89, 0x0d};
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 copy_delay = 0;
t_u32 delay = 0;
t_u8 num_subframes = 0;
ENTER();
@ -270,7 +300,8 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf)
if (pmadapter->tp_state_on)
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);
num_subframes = pmbuf->use_count =
wlan_11n_get_num_aggrpkts(priv, data, total_pkt_len, &forward);
// rx_trace 7
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*/)
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)) {
/** check if packet need send to host only */
if (pmbuf->pdesc && !forward) {
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->msdu_in_rx_amsdu_cnt += num_subframes;
priv->amsdu_rx_cnt++;
return ret;
}

View file

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

View file

@ -1219,7 +1219,7 @@ enum host_cmd_id {
#define FW_CAPINFO_EXT_CHAN_TRACK MBIT(13)
/** FW cap info bit 14: 6G Support */
#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)
/** FW cap info bit 19: security rgpower table */
#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)
/** Check if 6G supported by firmware */
#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) \
(_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) \
(_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_DEFAULT
};
#define MLAN_ACT_PASN_KEY_DNLD 7
#define MLAN_ACT_PASN_SET_KEY 0
/** Enumeration for generic enable/disable */
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;
/** Corresponds to port_open member of mlan_private */
t_u8 port_open;
/** Corresponds to tx_pause member of mlan_private */
t_u8 tx_pause;
/** bypass pkt count */
t_u32 bypass_pkt_count;
/** 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->tx_lock_flag = pmadapter->tx_lock_flag;
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->scan_processing = pmadapter->scan_processing;
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++) {
if (pmadapter->pscan_table[i].channel == channel) {
if (rssi == 0)
rssi = (t_s32)pmadapter->pscan_table[i].rssi;
rssi = (t_u8)pmadapter->pscan_table[i].rssi;
else {
if (min_flag)
rssi = MIN(
rssi = (t_u8)MIN(
rssi,
pmadapter->pscan_table[i].rssi);
else
rssi = MAX(
rssi = (t_u8)MAX(
rssi,
pmadapter->pscan_table[i].rssi);
}

View file

@ -2269,10 +2269,6 @@ poll_fw:
LEAVE();
return ret;
}
#ifdef SD9177
if (IS_SD9177(pmadapter->card_type))
wlan_mdelay(pmadapter, 1000);
#endif
done:
/* 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;
}
/**
* @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
*
@ -1512,8 +1528,9 @@ mlan_status mlan_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
ENTER();
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_free_txrx(pmadapter);
goto exit;
}
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",
MAC2STR(tx_pause_tlv->peermac),
tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
if (bssid &&
!memcmp(priv->adapter, bssid, tx_pause_tlv->peermac,
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);
status = wlan_get_tdls_link_status(
priv, tx_pause_tlv->peermac);
if (status != TDLS_NOT_SETUP) {
if (MTRUE == wlan_is_tdls_link_setup(status)) {
sta_ptr = wlan_get_station_entry(
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);

View file

@ -3122,6 +3122,7 @@ static mlan_status wlan_sec_ioctl_encrypt_key(pmlan_adapter pmadapter,
ENTER();
sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
if ((pioctl_req->action == MLAN_ACT_SET) ||
(pioctl_req->action == MLAN_ACT_PASN_KEY_DNLD) ||
(pioctl_req->action == MLAN_ACT_CLEAR)) {
if (sec->param.encrypt_key.is_wapi_key)
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();
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,
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
(t_void *)&bss->param.deauth_param);
@ -1042,7 +1049,8 @@ wlan_uap_sec_ioctl_set_encrypt_key(pmlan_adapter pmadapter,
ENTER();
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;
LEAVE();
return MLAN_STATUS_FAILURE;

View file

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

View file

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

View file

@ -395,6 +395,8 @@ enum _mlan_act_ioctl {
MLAN_ACT_RESET,
MLAN_ACT_DEFAULT
};
#define MLAN_ACT_PASN_KEY_DNLD 7
#define MLAN_ACT_PASN_SET_KEY 0
/** Enumeration for generic enable/disable */
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;
/** Corresponds to port_open member of mlan_private */
t_u8 port_open;
/** Corresponds to tx_pause member of mlan_private */
t_u8 tx_pause;
/** bypass pkt count */
t_u32 bypass_pkt_count;
/** 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_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
static const struct nla_policy
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 max_msec = (t_u64)24 * (t_u64)24 * (t_u64)3600 * (t_u64)1000;
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 */
req = woal_alloc_mlan_ioctl_req(sizeof(t_u32) + BUF_MAXLEN);
@ -3934,6 +3946,181 @@ done:
LEAVE();
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
*
@ -5487,6 +5674,19 @@ static const struct wiphy_vendor_command vendor_commands[] = {
#if KERNEL_VERSION(5, 3, 0) <= CFG80211_VERSION_CODE
.policy = woal_attr_policy,
.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
},
{

View file

@ -616,6 +616,21 @@ typedef enum wifi_attr {
ATTR_WIFI_AFTER_LAST,
ATTR_WIFI_MAX = ATTR_WIFI_AFTER_LAST - 1
} 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 {
MRVL_WLAN_VENDOR_ATTR_NAME = 10,
};
@ -708,6 +723,7 @@ enum vendor_sub_command {
sub_cmd_dfs_capability = 0x0005,
sub_cmd_set_scan_mac_oui = 0x0007,
sub_cmd_set_scan_band = 0x0008,
sub_cmd_secure_ranging_ctx = 0x0009,
sub_cmd_set_packet_filter = 0x0011,
sub_cmd_get_packet_filter_capability,
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),
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),
item_addr(bypass_pkt_count), INFO_ADDR},
{"scan_processing", item_size(scan_processing),
@ -309,6 +310,7 @@ static struct debug_data uap_items[] = {
INFO_ADDR},
{"tx_pkts_queued", item_size(tx_pkts_queued), item_addr(tx_pkts_queued),
INFO_ADDR},
{"tx_pause", item_size(tx_pause), item_addr(tx_pause), INFO_ADDR},
{"bypass_pkt_count", item_size(bypass_pkt_count),
item_addr(bypass_pkt_count), INFO_ADDR},
{"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)
unregister_netdev(dev);
woal_sched_timeout(100);
if (priv->mclist_workqueue) {
flush_workqueue(priv->mclist_workqueue);
destroy_workqueue(priv->mclist_workqueue);
@ -6690,6 +6691,7 @@ void woal_mlan_debug_info(moal_private *priv)
info->sleep_pd);
PRINTM(MERROR, "tx_lock_flag = %d\n", info->tx_lock_flag);
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_state = 0x%x\n", info->scan_state);
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++;
PRINTM(MERROR, "%lu : %s (bss=%d): Tx timeout (%d)\n", jiffies,
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);
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",
info->tx_lock_flag);
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",
info->scan_processing);
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)
/**
* @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
*
@ -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);
woal_reset_intf(priv, MOAL_IOCTL_WAIT, MTRUE);
woal_clean_up(handle);
mlan_ioctl(handle->pmlan_adapter, NULL);
/* Shutdown firmware */
handle->init_wait_q_woken = MFALSE;
@ -830,6 +874,12 @@ static void woal_pcie_reset_prepare(struct pci_dev *pdev)
}
}
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);
if (ref_handle) {
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.
*/
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);
if (ref_handle) {
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);
card = sdio_get_drvdata(func);
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
woal_unregist_oob_wakeup_irq(card->handle);
#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 *)(pmevent->event_buf + 4);
struct tx_status_info *tx_info = NULL;
PRINTM(MINFO,
"Receive Tx status: tx_token=%d, pkt_type=0x%x, status=%d tx_seq_num=%d\n",
PRINTM(MEVENT,
"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->status, priv->tx_seq_num);
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;
}
#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);
priv->phandle->scan_request = request;
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(
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),
sizeof(struct ieee80211_tdls_data)) +
50 + /* supported rates */
sizeof(IEEEtypes_ExtCap_t) + /* ext capab */
extra_ies_len + sizeof(IEEEtypes_tdls_linkie));
sizeof(struct ieee80211_tdls_data))) +
50 + /* supported rates */
sizeof(IEEEtypes_ExtCap_t) + /* ext capab */
extra_ies_len + sizeof(IEEEtypes_tdls_linkie))));
if (!pmbuf) {
PRINTM(MERROR, "Fail to allocate mlan_buffer\n");
ret = -ENOMEM;
@ -10433,7 +10443,8 @@ mlan_status woal_register_cfg80211(moal_private *priv)
PRINTM(MIOCTL, "Follow countryIE provided by AP.\n");
}
#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
* 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
@ -10441,7 +10452,18 @@ mlan_status woal_register_cfg80211(moal_private *priv)
* allowed channel.*/
wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
#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,
sizeof(priv->phandle->country_code));
priv->phandle->dfs_region = NXP_DFS_UNKNOWN;