mxm_wifiex: update to mxm6x17437.p24 release

Corresponding firmware version:
SDIO-UART W8987 Firmware version 16.92.21.p137
PCIE-UART W8997 Firmware version 16.92.21.p137.1
SDIO-UART W8997 Firmware version 16.92.21.p137.1
SDIO-UART IW416 Firmware version 16.92.21.p137
SDIO_UART IW612 Firmware version 18.99.3.p15
SDIO-UART W8801 Firmware version 14.92.36.p192
SDIO-UART W9098 Firmware version 17.92.1.p149.44
PCIE-UART W9098 Firmware version 17.92.1.p149.44

Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
This commit is contained in:
Luke Wang 2024-07-30 17:55:02 +08:00
parent 88372772ba
commit 5fe38ed6c6
54 changed files with 1075 additions and 166 deletions

View file

@ -186,7 +186,7 @@ APPDIR= $(shell if test -d "mapp"; then echo mapp; fi)
############################################################################# #############################################################################
ccflags-y += -I$(KERNELDIR)/include ccflags-y += -I$(KERNELDIR)/include
ccflags-y += -DMLAN_RELEASE_VERSION='"437.p21"' ccflags-y += -DMLAN_RELEASE_VERSION='"437.p24"'
ccflags-y += -DFPNUM='"92"' ccflags-y += -DFPNUM='"92"'

2
README
View file

@ -11,7 +11,7 @@
Goto source code directory. Goto source code directory.
make [clean] build make [clean] build
The driver and utility binaries can be found in bin_wlan directory. The driver and utility binaries can be found in bin_wlan directory.
The driver code supports Linux kernel from 2.6.32 to 6.7.0. The driver code supports Linux kernel from 2.6.32 to 6.8.4.
2) FOR DRIVER INSTALL 2) FOR DRIVER INSTALL

View file

@ -3,7 +3,7 @@
* @brief This file contains the functions for 11ax related features. * @brief This file contains the functions for 11ax related features.
* *
* *
* Copyright 2018-2022 NXP * Copyright 2018-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -3,7 +3,7 @@
* @brief This file contains functions for 802.11D. * @brief This file contains functions for 802.11D.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -3,7 +3,7 @@
* @brief This file contains functions for 11n handling. * @brief This file contains functions for 11n handling.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -3,7 +3,7 @@
* @brief This file contains functions for 11n Aggregation. * @brief This file contains functions for 11n Aggregation.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -114,7 +114,8 @@ static void wlan_11n_form_amsdu_txpd(mlan_private *priv, mlan_buffer *mbuf)
ENTER(); ENTER();
ptx_pd = (TxPD *)mbuf->pbuf; ptx_pd = (TxPD *)mbuf->pbuf;
memset(pmadapter, ptx_pd, 0, sizeof(TxPD)); // coverity[bad_memset:SUPPRESS]
memset(pmadapter, ptx_pd, 0, Tx_PD_SIZEOF(pmadapter));
/* /*
* Original priority has been overwritten * Original priority has been overwritten
@ -123,7 +124,7 @@ static void wlan_11n_form_amsdu_txpd(mlan_private *priv, mlan_buffer *mbuf)
ptx_pd->bss_num = GET_BSS_NUM(priv); ptx_pd->bss_num = GET_BSS_NUM(priv);
ptx_pd->bss_type = priv->bss_type; ptx_pd->bss_type = priv->bss_type;
/* Always zero as the data is followed by TxPD */ /* Always zero as the data is followed by TxPD */
ptx_pd->tx_pkt_offset = sizeof(TxPD); ptx_pd->tx_pkt_offset = Tx_PD_SIZEOF(pmadapter);
ptx_pd->tx_pkt_type = PKT_TYPE_AMSDU; ptx_pd->tx_pkt_type = PKT_TYPE_AMSDU;
if (mbuf->flags & MLAN_BUF_FLAG_TDLS) if (mbuf->flags & MLAN_BUF_FLAG_TDLS)
ptx_pd->flags = MRVDRV_TxPD_FLAGS_TDLS_PACKET; ptx_pd->flags = MRVDRV_TxPD_FLAGS_TDLS_PACKET;
@ -184,10 +185,11 @@ static t_u16 wlan_form_amsdu_txpd(mlan_private *priv, mlan_buffer *pmbuf,
t_u16 data_len = pmbuf->data_len; t_u16 data_len = pmbuf->data_len;
ENTER(); ENTER();
head_ptr = pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - head_ptr = pmbuf->pbuf + pmbuf->data_offset - Tx_PD_SIZEOF(pmadapter) -
priv->intf_hr_len; priv->intf_hr_len;
ptx_pd = (TxPD *)(head_ptr + priv->intf_hr_len); ptx_pd = (TxPD *)(head_ptr + priv->intf_hr_len);
memset(pmadapter, ptx_pd, 0, sizeof(TxPD)); // coverity[bad_memset:SUPPRESS]
memset(pmadapter, ptx_pd, 0, Tx_PD_SIZEOF(pmadapter));
/* Set the BSS number to TxPD */ /* Set the BSS number to TxPD */
ptx_pd->bss_num = GET_BSS_NUM(priv); ptx_pd->bss_num = GET_BSS_NUM(priv);
@ -219,7 +221,7 @@ static t_u16 wlan_form_amsdu_txpd(mlan_private *priv, mlan_buffer *pmbuf,
PRINTM(MDATA, "amsdu_pkt_len=%d, extra_len=%d\n", amsdu_pkt_len, PRINTM(MDATA, "amsdu_pkt_len=%d, extra_len=%d\n", amsdu_pkt_len,
pmbuf->data_len - data_len); pmbuf->data_len - data_len);
DBG_HEXDUMP(MDAT_D, "AMSDU TxPD", ptx_pd, sizeof(TxPD)); DBG_HEXDUMP(MDAT_D, "AMSDU TxPD", ptx_pd, Tx_PD_SIZEOF(pmadapter));
LEAVE(); LEAVE();
return (pmbuf->data_len - data_len); return (pmbuf->data_len - data_len);
@ -302,8 +304,8 @@ static INLINE void wlan_11n_update_pktlen_amsdu_txpd(mlan_private *priv,
ENTER(); ENTER();
ptx_pd = (TxPD *)mbuf->pbuf; ptx_pd = (TxPD *)mbuf->pbuf;
ptx_pd->tx_pkt_length = ptx_pd->tx_pkt_length = (t_u16)wlan_cpu_to_le16(
(t_u16)wlan_cpu_to_le16(mbuf->data_len - sizeof(TxPD)); mbuf->data_len - Tx_PD_SIZEOF(priv->adapter));
ptx_pd->pkt_delay_2ms = ptx_pd->pkt_delay_2ms =
wlan_wmm_compute_driver_packet_delay(priv, mbuf); wlan_wmm_compute_driver_packet_delay(priv, mbuf);
@ -643,8 +645,9 @@ done:
* *
* @return Final packet size or MLAN_STATUS_FAILURE * @return Final packet size or MLAN_STATUS_FAILURE
*/ */
int wlan_send_amsdu_subframe_list(mlan_private *priv, raListTbl *pra_list, static int wlan_send_amsdu_subframe_list(mlan_private *priv,
int headroom, int ptrindex) raListTbl *pra_list, int headroom,
int ptrindex)
{ {
int pkt_size = 0; int pkt_size = 0;
pmlan_adapter pmadapter = priv->adapter; pmlan_adapter pmadapter = priv->adapter;
@ -681,7 +684,8 @@ int wlan_send_amsdu_subframe_list(mlan_private *priv, raListTbl *pra_list,
&pra_list->buf_head, &pra_list->buf_head,
MNULL, MNULL); MNULL, MNULL);
/* Collects TP statistics */ /* Collects TP statistics */
if (pmadapter->tp_state_on && (pkt_size > sizeof(TxPD))) if (pmadapter->tp_state_on &&
(pkt_size > Tx_PD_SIZEOF(pmadapter)))
pmadapter->callbacks.moal_tp_accounting( pmadapter->callbacks.moal_tp_accounting(
pmadapter->pmoal_handle, pmbuf_src, 3); pmadapter->pmoal_handle, pmbuf_src, 3);
pra_list->total_pkts--; pra_list->total_pkts--;
@ -849,7 +853,7 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list,
} }
/* Form AMSDU */ /* Form AMSDU */
wlan_11n_form_amsdu_txpd(priv, pmbuf_aggr); wlan_11n_form_amsdu_txpd(priv, pmbuf_aggr);
pkt_size = sizeof(TxPD); pkt_size = Tx_PD_SIZEOF(pmadapter);
#ifdef STA_SUPPORT #ifdef STA_SUPPORT
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA)
ptx_pd = (TxPD *)pmbuf_aggr->pbuf; ptx_pd = (TxPD *)pmbuf_aggr->pbuf;
@ -868,7 +872,8 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list,
&pra_list->buf_head, &pra_list->buf_head,
MNULL, MNULL); MNULL, MNULL);
/* Collects TP statistics */ /* Collects TP statistics */
if (pmadapter->tp_state_on && (pkt_size > sizeof(TxPD))) if (pmadapter->tp_state_on &&
(pkt_size > Tx_PD_SIZEOF(pmadapter)))
pmadapter->callbacks.moal_tp_accounting( pmadapter->callbacks.moal_tp_accounting(
pmadapter->pmoal_handle, pmbuf_src, 3); pmadapter->pmoal_handle, pmbuf_src, 3);
pra_list->total_pkts--; pra_list->total_pkts--;
@ -922,7 +927,8 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list,
pmbuf_aggr->data_len += headroom; pmbuf_aggr->data_len += headroom;
pmbuf_aggr->pbuf = data - headroom; pmbuf_aggr->pbuf = data - headroom;
tx_param.next_pkt_len = tx_param.next_pkt_len =
((pmbuf_src) ? pmbuf_src->data_len + sizeof(TxPD) : 0); ((pmbuf_src) ? pmbuf_src->data_len + Tx_PD_SIZEOF(pmadapter) :
0);
/* Collects TP statistics */ /* Collects TP statistics */
if (pmadapter->tp_state_on) { if (pmadapter->tp_state_on) {
pmadapter->callbacks.moal_tp_accounting(pmadapter->pmoal_handle, pmadapter->callbacks.moal_tp_accounting(pmadapter->pmoal_handle,

View file

@ -3221,6 +3221,67 @@ static void wlan_sort_cfp_otp_table(mlan_adapter *pmadapter)
} }
} }
/**
* @brief Set max tx power value per channel in otp tables
*
* @param pmapdater a pointer to mlan_adapter structure
* @param is6g 6g table true or false
*
* @return
* None
*/
static void wlan_set_otp_cfp_max_tx_pwr(mlan_adapter *pmadapter, t_bool is6g)
{
t_u8 i, j;
t_u8 rows, cols, max = 0;
if (!pmadapter->otp_region)
return;
if (!is6g && pmadapter->cfp_otp_bg && pmadapter->tx_power_table_bg) {
rows = pmadapter->tx_power_table_bg_rows;
cols = pmadapter->tx_power_table_bg_cols;
if (pmadapter->tx_power_table_bg_size < (rows * cols))
goto table_a;
for (i = 0; i < rows; i++) {
max = 0;
if ((pmadapter->cfp_otp_bg + i)->dynamic.flags &
NXP_CHANNEL_DISABLED)
continue;
/* get the max value among all mod group for this
* channel */
for (j = 1; j < cols; j++)
max = MAX(
max,
pmadapter->tx_power_table_bg[i * cols +
j]);
(pmadapter->cfp_otp_bg + i)->max_tx_power = max;
}
}
table_a:
if (!is6g && pmadapter->cfp_otp_a && pmadapter->tx_power_table_a) {
rows = pmadapter->tx_power_table_a_rows;
cols = pmadapter->tx_power_table_a_cols;
if (pmadapter->tx_power_table_a_size < (rows * cols))
return;
for (i = 0; i < rows; i++) {
max = 0;
if ((pmadapter->cfp_otp_a + i)->dynamic.flags &
NXP_CHANNEL_DISABLED)
continue;
/* get the max value among all mod group for this
* channel */
for (j = 1; j < cols; j++)
max = MAX(max,
pmadapter->tx_power_table_a[i * cols +
j]);
(pmadapter->cfp_otp_a + i)->max_tx_power = max;
}
}
}
/** /**
* @brief Update CFP tables and power tables from FW * @brief Update CFP tables and power tables from FW
* *
@ -3550,6 +3611,9 @@ void wlan_add_fw_cfp_tables(pmlan_private pmpriv, t_u8 *buf, t_u16 buf_left)
} }
if (!pmadapter->cfp_otp_bg || !pmadapter->tx_power_table_bg) if (!pmadapter->cfp_otp_bg || !pmadapter->tx_power_table_bg)
goto out; goto out;
wlan_set_otp_cfp_max_tx_pwr(pmadapter, MFALSE);
/* Set remaining flags for BG */ /* Set remaining flags for BG */
rows = pmadapter->tx_power_table_bg_rows; rows = pmadapter->tx_power_table_bg_rows;
cols = pmadapter->tx_power_table_bg_cols; cols = pmadapter->tx_power_table_bg_cols;

View file

@ -5122,6 +5122,15 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter)
&dmcs_policy); &dmcs_policy);
} }
if (pmadapter->init_para.reject_addba_req) {
mlan_ds_reject_addba_req rej_addba_req_cfg;
rej_addba_req_cfg.conditions =
pmadapter->init_para.reject_addba_req;
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_REJECT_ADDBA_REQ,
HostCmd_ACT_GEN_SET, 0, (t_void *)MNULL,
&rej_addba_req_cfg);
}
#define DEF_AUTO_NULL_PKT_PERIOD 30 #define DEF_AUTO_NULL_PKT_PERIOD 30
if (pmpriv_sta) { if (pmpriv_sta) {
t_u32 value = DEF_AUTO_NULL_PKT_PERIOD; t_u32 value = DEF_AUTO_NULL_PKT_PERIOD;
@ -10577,15 +10586,17 @@ mlan_status wlan_cmd_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
data_len -= sizeof(pkt_type) + sizeof(tx_control); data_len -= sizeof(pkt_type) + sizeof(tx_control);
pdata += sizeof(pkt_type) + sizeof(tx_control); pdata += sizeof(pkt_type) + sizeof(tx_control);
} }
memcpy_ext(pmpriv->adapter, tx_frame_cmd->buffer + sizeof(TxPD), pdata, memcpy_ext(pmpriv->adapter,
tx_frame_cmd->buffer + Tx_PD_SIZEOF(pmpriv->adapter), pdata,
data_len, data_len); data_len, data_len);
memset(pmpriv->adapter, plocal_tx_pd, 0, sizeof(TxPD)); // coverity[bad_memset:SUPPRESS]
memset(pmpriv->adapter, plocal_tx_pd, 0, Tx_PD_SIZEOF(pmpriv->adapter));
plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv);
plocal_tx_pd->bss_type = pmpriv->bss_type; plocal_tx_pd->bss_type = pmpriv->bss_type;
plocal_tx_pd->tx_pkt_length = (t_u16)data_len; plocal_tx_pd->tx_pkt_length = (t_u16)data_len;
plocal_tx_pd->priority = (t_u8)tx_frame->priority; plocal_tx_pd->priority = (t_u8)tx_frame->priority;
plocal_tx_pd->tx_pkt_offset = sizeof(TxPD); plocal_tx_pd->tx_pkt_offset = Tx_PD_SIZEOF(pmpriv->adapter);
plocal_tx_pd->pkt_delay_2ms = 0xff; plocal_tx_pd->pkt_delay_2ms = 0xff;
if (tx_frame->buf_type == MLAN_BUF_TYPE_RAW_DATA) { if (tx_frame->buf_type == MLAN_BUF_TYPE_RAW_DATA) {
@ -10599,7 +10610,7 @@ mlan_status wlan_cmd_tx_frame(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
} }
endian_convert_TxPD(plocal_tx_pd); endian_convert_TxPD(plocal_tx_pd);
cmd_size += sizeof(TxPD) + data_len; cmd_size += Tx_PD_SIZEOF(pmpriv->adapter) + data_len;
cmd->size = wlan_cpu_to_le16(cmd_size); cmd->size = wlan_cpu_to_le16(cmd_size);
LEAVE(); LEAVE();

View file

@ -3,7 +3,7 @@
* @brief This file declares the generic data structures and APIs. * @brief This file declares the generic data structures and APIs.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -2762,6 +2762,8 @@ typedef struct _mlan_device {
t_u32 antcfg; t_u32 antcfg;
/** dmcs */ /** dmcs */
t_u8 dmcs; t_u8 dmcs;
t_u32 reject_addba_req;
} mlan_device, *pmlan_device; } mlan_device, *pmlan_device;
/** MLAN API function prototype */ /** MLAN API function prototype */

View file

@ -3,7 +3,7 @@
* @brief This file contains FW event ID definitions. * @brief This file contains FW event ID definitions.
* *
* *
* Copyright 2023 NXP * Copyright 2023-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -5,7 +5,7 @@
* in MLAN module. * in MLAN module.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -257,8 +257,8 @@ typedef enum _KEY_INFO_WAPI {
#define EXTRA_LEN 256 #define EXTRA_LEN 256
/** Buffer size for ethernet Tx packets */ /** Buffer size for ethernet Tx packets */
#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \ #define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE(_adapter) \
(MV_ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN) (MV_ETH_FRAME_LEN + Tx_PD_SIZEOF(_adapter) + EXTRA_LEN)
/** Buffer size for ethernet Rx packets */ /** Buffer size for ethernet Rx packets */
#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \ #define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
@ -1215,6 +1215,8 @@ enum host_cmd_id {
#define FW_CAPINFO_EXT_SEC_RG_POWER MBIT(19) #define FW_CAPINFO_EXT_SEC_RG_POWER MBIT(19)
/** FW cap info bit 20: RX_SW_INT */ /** FW cap info bit 20: RX_SW_INT */
#define FW_CAPINFO_EXT_RX_SW_INT MBIT(20) #define FW_CAPINFO_EXT_RX_SW_INT MBIT(20)
/** FW cap info bit 21: EASY_MESH_SUPPORT */
#define FW_CAPINFO_EASY_MESH MBIT(21)
/** Check if 5G 1x1 only is supported by firmware */ /** Check if 5G 1x1 only is supported by firmware */
#define IS_FW_SUPPORT_5G_1X1_ONLY(_adapter) \ #define IS_FW_SUPPORT_5G_1X1_ONLY(_adapter) \
@ -1261,6 +1263,12 @@ enum host_cmd_id {
(_adapter->fw_cap_ext & FW_CAPINFO_EXT_SEC_RG_POWER) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_SEC_RG_POWER)
#define IS_FW_SUPPORT_RX_SW_INT(_adapter) \ #define IS_FW_SUPPORT_RX_SW_INT(_adapter) \
(_adapter->fw_cap_ext & FW_CAPINFO_EXT_RX_SW_INT) (_adapter->fw_cap_ext & FW_CAPINFO_EXT_RX_SW_INT)
/** Check if easy mesh supported by firmware */
#define IS_FW_SUPPORT_EASY_MESH(_adapter) \
(_adapter->fw_cap_ext & FW_CAPINFO_EASY_MESH)
#define Tx_PD_SIZEOF(_adapter) \
(IS_FW_SUPPORT_EASY_MESH(_adapter) ? sizeof(TxPD) : (sizeof(TxPD) - 8))
/** MrvlIEtypes_PrevBssid_t */ /** MrvlIEtypes_PrevBssid_t */
typedef MLAN_PACK_START struct _MrvlIEtypes_PrevBssid_t { typedef MLAN_PACK_START struct _MrvlIEtypes_PrevBssid_t {
@ -1442,6 +1450,11 @@ typedef enum _ENH_PS_MODES {
/** Command RET code, MSB is set to 1 */ /** Command RET code, MSB is set to 1 */
#define HostCmd_RET_BIT 0x8000 #define HostCmd_RET_BIT 0x8000
/** Special purpose action : Set */
#define HostCmd_ACT_SPC_AUTO_SET 0x8002
/** Special purpose action : Set */
#define HostCmd_ACT_SPC_AUTO_NOSET 0x8003
/** General purpose action : Get */ /** General purpose action : Get */
#define HostCmd_ACT_GEN_GET 0x0000 #define HostCmd_ACT_GEN_GET 0x0000
/** General purpose action : Set */ /** General purpose action : Set */
@ -4879,6 +4892,32 @@ typedef MLAN_PACK_START struct {
t_u8 wmm_param_tlv[sizeof(IEEEtypes_WmmParameter_t) + 2]; t_u8 wmm_param_tlv[sizeof(IEEEtypes_WmmParameter_t) + 2];
} MLAN_PACK_END HostCmd_DS_WMM_GET_STATUS; } MLAN_PACK_END HostCmd_DS_WMM_GET_STATUS;
/**
* @brief Command structure for the HostCmd_CMD_WMM_HOST_ADDTS_REQ firmware
* command
*/
typedef MLAN_PACK_START struct {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer_addr[MLAN_MAC_ADDR_LENGTH];
/* User priority (UP) */
t_u8 user_prio;
/* Admitted Air time for UP */
t_u16 admitted_time;
} MLAN_PACK_END HostCmd_DS_WMM_HOST_ADDTS_REQ;
/**
* @brief Command structure for the HostCmd_CMD_WMM_HOST_DELTS_REQ firmware
* command
*/
typedef MLAN_PACK_START struct {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer_addr[MLAN_MAC_ADDR_LENGTH];
} MLAN_PACK_END HostCmd_DS_WMM_HOST_DELTS_REQ;
/** /**
* @brief Command structure for the HostCmd_CMD_WMM_ADDTS_REQ firmware command * @brief Command structure for the HostCmd_CMD_WMM_ADDTS_REQ firmware command
*/ */
@ -7186,7 +7225,8 @@ typedef MLAN_PACK_START struct _HostCmd_DS_SENSOR_TEMP {
#define TLV_TYPE_IPV6_RA_OFFLOAD (PROPRIETARY_TLV_BASE_ID + 0xE6) /** 0x1E6*/ #define TLV_TYPE_IPV6_RA_OFFLOAD (PROPRIETARY_TLV_BASE_ID + 0xE6) /** 0x1E6*/
typedef MLAN_PACK_START struct { typedef MLAN_PACK_START struct {
MrvlIEtypesHeader_t Header; MrvlIEtypesHeader_t Header;
t_u8 ipv6_addr[16]; /** ipv6 address buffer */
t_u8 ipv6_addrs[];
} MLAN_PACK_END MrvlIETypes_IPv6AddrParamSet_t; } MLAN_PACK_END MrvlIETypes_IPv6AddrParamSet_t;
typedef MLAN_PACK_START struct _HostCmd_DS_IPV6_RA_OFFLOAD { typedef MLAN_PACK_START struct _HostCmd_DS_IPV6_RA_OFFLOAD {
@ -7196,6 +7236,8 @@ typedef MLAN_PACK_START struct _HostCmd_DS_IPV6_RA_OFFLOAD {
t_u16 action; t_u16 action;
/** 0x00: disable IPv6 RA Offload; 0x01: enable IPv6 RA offload */ /** 0x00: disable IPv6 RA Offload; 0x01: enable IPv6 RA offload */
t_u8 enable; t_u8 enable;
/** Number of IPv6 address configured in FW */
t_u8 ipv6_addr_count;
MrvlIETypes_IPv6AddrParamSet_t ipv6_addr_param; MrvlIETypes_IPv6AddrParamSet_t ipv6_addr_param;
} MLAN_PACK_END HostCmd_DS_IPV6_RA_OFFLOAD; } MLAN_PACK_END HostCmd_DS_IPV6_RA_OFFLOAD;
@ -7994,6 +8036,11 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND {
HostCmd_DS_EDMAC_CFG ed_mac_cfg; HostCmd_DS_EDMAC_CFG ed_mac_cfg;
HostCmd_gpio_cfg_ops gpio_cfg_ops; HostCmd_gpio_cfg_ops gpio_cfg_ops;
/** WMM HOST ADDTS */
HostCmd_DS_WMM_HOST_ADDTS_REQ host_add_ts;
/** WMM HOST DELTS */
HostCmd_DS_WMM_HOST_DELTS_REQ host_del_ts;
} params; } params;
} MLAN_PACK_END HostCmd_DS_COMMAND, *pHostCmd_DS_COMMAND; } MLAN_PACK_END HostCmd_DS_COMMAND, *pHostCmd_DS_COMMAND;

View file

@ -3,7 +3,7 @@
* @brief This file contains host command ID definitions. * @brief This file contains host command ID definitions.
* *
* *
* Copyright 2023 NXP * Copyright 2023-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -457,5 +457,10 @@ ENUM_ELEMENT(HostCmd_CMD_GET_HW_SPEC, 0x0003),
/** Host Command ID: PCIE ADMA INIT */ /** Host Command ID: PCIE ADMA INIT */
ENUM_ELEMENT(HostCmd_CMD_PCIE_ADMA_INIT, 0x0284), ENUM_ELEMENT(HostCmd_CMD_PCIE_ADMA_INIT, 0x0284),
/** Host Command ID : WMM HOST ADDTS req */
ENUM_ELEMENT(HostCmd_CMD_WMM_HOST_ADDTS_REQ, 0x0287),
/** Host Command ID : WMM HOST DELTS req */
ENUM_ELEMENT(HostCmd_CMD_WMM_HOST_DELTS_REQ, 0x0288),
/* Always keep this last */ /* Always keep this last */
ENUM_ELEMENT_LAST(__HostCmd_CMD_Last) ENUM_ELEMENT_LAST(__HostCmd_CMD_Last)

View file

@ -4,7 +4,7 @@
* definitions used in MLAN and MOAL module. * definitions used in MLAN and MOAL module.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -884,6 +884,27 @@ typedef MLAN_PACK_START enum _IEEEtypes_WMM_Tspec_Action_e {
} MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_e; } MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_e;
/** NAN SDF vendor oui size */
#define NAN_SDF_VENDOR_SIZE 4
/** NAN service descriptor attribute offset */
#define NAN_SDA_OFFSET 5
/** NAN service control type offset */
#define NAN_SRVC_CTRL_OFFSET 11
/** Service control field */
#define NAN_SRV_CTRL_TYPE_MASK (BIT(0) | BIT(1))
/** NAN publish frame */
#define NAN_PUBLISH 0
/** NAN Attribute ID list */
typedef MLAN_PACK_START enum _Nan_AttrId_e {
NAN_ATTR_SDA = 0x03
} MLAN_PACK_END Nan_AttrId_e;
/** Public Action Codes */
typedef MLAN_PACK_START enum _IEEEtypes_Public_ActionCategory_e {
IEEE_PUBLIC_ACTION_CATEGORY_VENDOR_SPECIFIC = 9
} MLAN_PACK_END IEEEtypes_Public_ActionCategory_e;
/** WMM TSPEC Category Action Base */ /** WMM TSPEC Category Action Base */
typedef MLAN_PACK_START struct { typedef MLAN_PACK_START struct {
IEEEtypes_ActionCategory_e category; IEEEtypes_ActionCategory_e category;

View file

@ -4,7 +4,7 @@
* and HW. * and HW.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -3,7 +3,7 @@
* @brief This file declares the IOCTL data structures and APIs. * @brief This file declares the IOCTL data structures and APIs.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -183,6 +183,8 @@ enum _mlan_ioctl_req_id {
MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006, MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006,
MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007, MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007,
MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008, MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008,
MLAN_OID_WMM_CFG_HOST_ADDTS = 0x000A000A,
MLAN_OID_WMM_CFG_HOST_DELTS = 0x000A000B,
/* WPS Configuration Group */ /* WPS Configuration Group */
MLAN_IOCTL_WPS_CFG = 0x000B0000, MLAN_IOCTL_WPS_CFG = 0x000B0000,
@ -2986,6 +2988,8 @@ typedef struct _mlan_data_rate {
typedef struct _mlan_ds_rate { typedef struct _mlan_ds_rate {
/** Sub-command */ /** Sub-command */
t_u32 sub_command; t_u32 sub_command;
/** Only set auto tx fix rate */
t_u16 auto_null_fixrate_enable;
/** Rate configuration parameter */ /** Rate configuration parameter */
union { union {
/** Rate configuration for MLAN_OID_RATE_CFG */ /** Rate configuration for MLAN_OID_RATE_CFG */
@ -3609,6 +3613,26 @@ typedef struct _mlan_ds_wmm_queue_config {
t_u8 reserved[10]; t_u8 reserved[10];
} mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config; } mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config;
/** WMM HOST ADDTS configuration parameters */
typedef struct _mlan_ds_tx_addts {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer[MLAN_MAC_ADDR_LENGTH];
/* User priority (UP) */
t_u8 user_prio;
/* Admitted Air time for UP */
t_u16 admitted_time;
} mlan_ds_tx_addts_cfg;
/** WMM HOST DELTS configuration parameters */
typedef struct _mlan_ds_tx_delts {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer[MLAN_MAC_ADDR_LENGTH];
} mlan_ds_tx_delts_cfg;
/** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */ /** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */
typedef struct _mlan_ds_wmm_cfg { typedef struct _mlan_ds_wmm_cfg {
/** Sub-command */ /** Sub-command */
@ -3623,6 +3647,10 @@ typedef struct _mlan_ds_wmm_cfg {
mlan_ds_wmm_addts addts; mlan_ds_wmm_addts addts;
/** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */ /** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */
mlan_ds_wmm_delts delts; mlan_ds_wmm_delts delts;
/** WMM add TS for host config */
mlan_ds_tx_addts_cfg host_addts;
/** WMM del TS for host config */
mlan_ds_tx_delts_cfg host_delts;
/** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */ /** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */
mlan_ds_wmm_queue_config q_cfg; mlan_ds_wmm_queue_config q_cfg;
/** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI,
@ -4138,7 +4166,7 @@ typedef struct _mlan_ds_11ax_rutxpwr_cmd {
* and 6 for other SOCs */ * and 6 for other SOCs */
t_u8 col; t_u8 col;
/**ru tx data */ /**ru tx data */
t_u8 rutxSubPwr[89]; t_s8 rutxSubPwr[89];
} mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd; } mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd;
/** Type definition of mlan_ds_11ax_cmd_cfg for MLAN_OID_11AX_CMD_CFG */ /** Type definition of mlan_ds_11ax_cmd_cfg for MLAN_OID_11AX_CMD_CFG */
@ -4787,7 +4815,10 @@ typedef struct _mlan_ds_misc_ipaddr_cfg {
typedef struct _mlan_ds_misc_ipv6_ra_offload { typedef struct _mlan_ds_misc_ipv6_ra_offload {
/** 0: disable; 1: enable*/ /** 0: disable; 1: enable*/
t_u8 enable; t_u8 enable;
t_u8 ipv6_addr[16]; /** Number of IPv6 address configured in FW */
t_u8 ipv6_addrs_count;
/** Ipv6 address array */
t_u8 ipv6_addrs[];
} mlan_ds_misc_ipv6_ra_offload; } mlan_ds_misc_ipv6_ra_offload;
/* MEF configuration disable */ /* MEF configuration disable */

View file

@ -8,7 +8,7 @@
* both adhoc and infrastructure networks * both adhoc and infrastructure networks
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -5,7 +5,7 @@
* in MLAN module. * in MLAN module.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -1948,6 +1948,7 @@ typedef struct _mlan_init_para {
t_u32 antcfg; t_u32 antcfg;
/** dmcs*/ /** dmcs*/
t_u8 dmcs; t_u8 dmcs;
t_u32 reject_addba_req;
} mlan_init_para, *pmlan_init_para; } mlan_init_para, *pmlan_init_para;
#ifdef SDIO #ifdef SDIO

View file

@ -4809,9 +4809,24 @@ static mlan_status wlan_rate_ioctl_set_rate_index(pmlan_adapter pmadapter,
pmpriv->is_data_rate_auto, pmpriv->data_rate); pmpriv->is_data_rate_auto, pmpriv->data_rate);
/* Send request to firmware */ /* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, if (ds_rate->auto_null_fixrate_enable == 1) {
HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req, ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
(t_void *)bitmap_rates); HostCmd_ACT_SPC_AUTO_SET, 0,
(t_void *)pioctl_req,
(t_void *)bitmap_rates);
ds_rate->auto_null_fixrate_enable = 0xff;
} else if (ds_rate->auto_null_fixrate_enable == 0) {
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
HostCmd_ACT_SPC_AUTO_NOSET, 0,
(t_void *)pioctl_req,
(t_void *)bitmap_rates);
ds_rate->auto_null_fixrate_enable = 0xff;
} else
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
HostCmd_ACT_GEN_SET, 0,
(t_void *)pioctl_req,
(t_void *)bitmap_rates);
if (ret == MLAN_STATUS_SUCCESS) if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING; ret = MLAN_STATUS_PENDING;

View file

@ -3,7 +3,7 @@
* @brief This file contains PCI-E specific code * @brief This file contains PCI-E specific code
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -2849,7 +2849,7 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
t_u32 rdptr, rd_index; t_u32 rdptr, rd_index;
mlan_buffer *pmbuf = MNULL; mlan_buffer *pmbuf = MNULL;
t_u32 txbd_val = 0; t_u32 txbd_val = 0;
t_u16 rx_len, rx_type; t_u16 rx_len = 0, rx_type;
const t_u32 num_rx_buffs = pmadapter->pcard_pcie->txrx_bd_size; const t_u32 num_rx_buffs = pmadapter->pcard_pcie->txrx_bd_size;
t_u32 reg_rxbd_rdptr = pmadapter->pcard_pcie->reg->reg_rxbd_rdptr; t_u32 reg_rxbd_rdptr = pmadapter->pcard_pcie->reg->reg_rxbd_rdptr;
#if defined(PCIE8997) || defined(PCIE8897) #if defined(PCIE8997) || defined(PCIE8897)
@ -2902,6 +2902,14 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
goto done; goto done;
} }
pmbuf = pmadapter->pcard_pcie->rx_buf_list[rd_index]; pmbuf = pmadapter->pcard_pcie->rx_buf_list[rd_index];
/* if in previous Interrupt, SKB allocation fails, then there
* will be no valid pmbuf in RxRing at the current index. we can
* attempt reattch a valid pmbuf at same index and continue Rx.
*/
if (!pmbuf) {
PRINTM(MDAT_D, "RECV DATA: invalid pmbuf");
goto reattach;
}
if (MLAN_STATUS_FAILURE == if (MLAN_STATUS_FAILURE ==
pcb->moal_unmap_memory(pmadapter->pmoal_handle, pcb->moal_unmap_memory(pmadapter->pmoal_handle,
pmbuf->pbuf + pmbuf->data_offset, pmbuf->pbuf + pmbuf->data_offset,
@ -2972,6 +2980,13 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
pmadapter->data_received = MTRUE; pmadapter->data_received = MTRUE;
} }
} else {
/* Queue the mlan_buffer again */
PRINTM(MERROR, "PCIE: Drop invalid packet, length=%d",
rx_len);
}
reattach:
if ((rx_len <= MLAN_RX_DATA_BUF_SIZE) || (!pmbuf)) {
/* Create new buffer and attach it to Rx Ring */ /* Create new buffer and attach it to Rx Ring */
pmbuf = wlan_alloc_mlan_buffer(pmadapter, pmbuf = wlan_alloc_mlan_buffer(pmadapter,
MLAN_RX_DATA_BUF_SIZE, MLAN_RX_DATA_BUF_SIZE,
@ -2983,10 +2998,6 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter)
ret = MLAN_STATUS_FAILURE; ret = MLAN_STATUS_FAILURE;
goto done; goto done;
} }
} else {
/* Queue the mlan_buffer again */
PRINTM(MERROR, "PCIE: Drop invalid packet, length=%d",
rx_len);
} }
if (MLAN_STATUS_FAILURE == if (MLAN_STATUS_FAILURE ==
@ -5191,6 +5202,9 @@ static mlan_status wlan_pcie_interrupt_ext(t_u16 msg_id,
ENTER(); ENTER();
ret = wlan_pcie_interrupt(msg_id, pmadapter); ret = wlan_pcie_interrupt(msg_id, pmadapter);
if (ret == MLAN_STATUS_SUCCESS) { if (ret == MLAN_STATUS_SUCCESS) {
/* if we get interrupt, it means device wakes up, no need to
* wake up */
pmadapter->pm_wakeup_timeout = 0;
wlan_process_pcie_int_status(pmadapter); wlan_process_pcie_int_status(pmadapter);
} }
LEAVE(); LEAVE();

View file

@ -6,7 +6,7 @@
* for sending scan commands to the firmware. * for sending scan commands to the firmware.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -6444,8 +6444,7 @@ mlan_status wlan_cmd_bgscan_config(mlan_private *pmpriv,
pscan_gap_tlv->header.type = pscan_gap_tlv->header.type =
wlan_cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP); wlan_cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP);
pscan_gap_tlv->header.len = sizeof(pscan_gap_tlv->gap); pscan_gap_tlv->header.len = sizeof(pscan_gap_tlv->gap);
pscan_gap_tlv->gap = pscan_gap_tlv->gap = wlan_cpu_to_le16((t_u16)scan_chan_gap);
wlan_cpu_to_le16((t_u16)pmadapter->scan_chan_gap);
/** indicate FW, gap is optional */ /** indicate FW, gap is optional */
pscan_gap_tlv->gap |= GAP_FLAG_OPTIONAL; pscan_gap_tlv->gap |= GAP_FLAG_OPTIONAL;
tlv += sizeof(pscan_gap_tlv->header) + tlv += sizeof(pscan_gap_tlv->header) +

View file

@ -3,7 +3,7 @@
* @brief This file contains APIs to MOAL module. * @brief This file contains APIs to MOAL module.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -328,6 +328,7 @@ mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
pmadapter->init_para.wacp_mode = pmdevice->wacp_mode; pmadapter->init_para.wacp_mode = pmdevice->wacp_mode;
pmadapter->init_para.mcs32 = pmdevice->mcs32; pmadapter->init_para.mcs32 = pmdevice->mcs32;
pmadapter->init_para.antcfg = pmdevice->antcfg; pmadapter->init_para.antcfg = pmdevice->antcfg;
pmadapter->init_para.reject_addba_req = pmdevice->reject_addba_req;
pmadapter->init_para.dmcs = pmdevice->dmcs; pmadapter->init_para.dmcs = pmdevice->dmcs;
#ifdef SDIO #ifdef SDIO

View file

@ -2972,6 +2972,8 @@ static mlan_status wlan_cmd_ipv6_ra_offload(mlan_private *pmpriv,
mlan_ds_misc_ipv6_ra_offload *ipv6_ra_offload = mlan_ds_misc_ipv6_ra_offload *ipv6_ra_offload =
(mlan_ds_misc_ipv6_ra_offload *)pdata_buf; (mlan_ds_misc_ipv6_ra_offload *)pdata_buf;
MrvlIEtypesHeader_t *ie = &ipv6_ra_cfg->ipv6_addr_param.Header; MrvlIEtypesHeader_t *ie = &ipv6_ra_cfg->ipv6_addr_param.Header;
t_u8 *pipv6addrs = ipv6_ra_cfg->ipv6_addr_param.ipv6_addrs;
t_u8 *psrcipv6addr = ipv6_ra_offload->ipv6_addrs;
ENTER(); ENTER();
@ -2980,13 +2982,16 @@ static mlan_status wlan_cmd_ipv6_ra_offload(mlan_private *pmpriv,
if (cmd_action == HostCmd_ACT_GEN_SET) { if (cmd_action == HostCmd_ACT_GEN_SET) {
ipv6_ra_cfg->enable = ipv6_ra_offload->enable; ipv6_ra_cfg->enable = ipv6_ra_offload->enable;
ie->type = wlan_cpu_to_le16(TLV_TYPE_IPV6_RA_OFFLOAD); ie->type = wlan_cpu_to_le16(TLV_TYPE_IPV6_RA_OFFLOAD);
ie->len = wlan_cpu_to_le16(16); ipv6_ra_cfg->ipv6_addr_count =
memcpy_ext(pmpriv->adapter, ipv6_ra_offload->ipv6_addrs_count;
ipv6_ra_cfg->ipv6_addr_param.ipv6_addr, memcpy_ext(pmpriv->adapter, pipv6addrs, psrcipv6addr,
ipv6_ra_offload->ipv6_addr, 16, (ipv6_ra_offload->ipv6_addrs_count * IPADDR_LEN),
sizeof(ipv6_ra_cfg->ipv6_addr_param.ipv6_addr)); (ipv6_ra_offload->ipv6_addrs_count * IPADDR_LEN));
ie->len = wlan_cpu_to_le16(16 *
ipv6_ra_offload->ipv6_addrs_count);
pcmd->size = wlan_cpu_to_le16( pcmd->size = wlan_cpu_to_le16(
S_DS_GEN + sizeof(HostCmd_DS_IPV6_RA_OFFLOAD)); S_DS_GEN + sizeof(HostCmd_DS_IPV6_RA_OFFLOAD) +
(IPADDR_LEN * ipv6_ra_cfg->ipv6_addr_count));
} else if (cmd_action == HostCmd_ACT_GEN_GET) } else if (cmd_action == HostCmd_ACT_GEN_GET)
pcmd->size = wlan_cpu_to_le16(S_DS_GEN + pcmd->size = wlan_cpu_to_le16(S_DS_GEN +
sizeof(ipv6_ra_cfg->action)); sizeof(ipv6_ra_cfg->action));
@ -3886,6 +3891,12 @@ mlan_status wlan_ops_sta_prepare_cmd(t_void *priv, t_u16 cmd_no,
case HostCmd_CMD_WMM_DELTS_REQ: case HostCmd_CMD_WMM_DELTS_REQ:
ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf); ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf);
break; break;
case HostCmd_CMD_WMM_HOST_ADDTS_REQ:
ret = wlan_cmd_wmm_host_addts_req(pmpriv, cmd_ptr, pdata_buf);
break;
case HostCmd_CMD_WMM_HOST_DELTS_REQ:
ret = wlan_cmd_wmm_host_delts_req(pmpriv, cmd_ptr, pdata_buf);
break;
case HostCmd_CMD_WMM_QUEUE_CONFIG: case HostCmd_CMD_WMM_QUEUE_CONFIG:
ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf); ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
break; break;

View file

@ -2521,9 +2521,11 @@ static mlan_status wlan_ret_ipv6_ra_offload(pmlan_private pmpriv,
ipv6_ra = (mlan_ds_misc_ipv6_ra_offload *)&misc->param ipv6_ra = (mlan_ds_misc_ipv6_ra_offload *)&misc->param
.ipv6_ra_offload; .ipv6_ra_offload;
ipv6_ra->enable = ipv6_ra_resp->enable; ipv6_ra->enable = ipv6_ra_resp->enable;
memcpy_ext(pmpriv->adapter, ipv6_ra->ipv6_addr, ipv6_ra->ipv6_addrs_count = ipv6_ra_resp->ipv6_addr_count;
ipv6_ra_resp->ipv6_addr_param.ipv6_addr, 16, memcpy_ext(pmpriv->adapter, ipv6_ra->ipv6_addrs,
sizeof(ipv6_ra->ipv6_addr)); ipv6_ra_resp->ipv6_addr_param.ipv6_addrs,
(ipv6_ra->ipv6_addrs_count * IPADDR_LEN),
(ipv6_ra->ipv6_addrs_count * IPADDR_LEN));
} }
LEAVE(); LEAVE();
@ -3404,6 +3406,9 @@ mlan_status wlan_ops_sta_process_cmdresp(t_void *priv, t_u16 cmdresp_no,
case HostCmd_CMD_WMM_DELTS_REQ: case HostCmd_CMD_WMM_DELTS_REQ:
ret = wlan_ret_wmm_delts_req(pmpriv, resp, pioctl_buf); ret = wlan_ret_wmm_delts_req(pmpriv, resp, pioctl_buf);
break; break;
case HostCmd_CMD_WMM_HOST_ADDTS_REQ:
case HostCmd_CMD_WMM_HOST_DELTS_REQ:
break;
case HostCmd_CMD_WMM_QUEUE_CONFIG: case HostCmd_CMD_WMM_QUEUE_CONFIG:
ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf); ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf);
break; break;

View file

@ -3,7 +3,7 @@
* @brief This file contains MLAN event handling. * @brief This file contains MLAN event handling.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -5312,7 +5312,7 @@ mlan_status wlan_scan_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
LEAVE(); LEAVE();
return MLAN_STATUS_FAILURE; return MLAN_STATUS_FAILURE;
} }
if (pmadapter->remain_on_channel if (pmadapter->remain_on_channel && pioctl_req->action == MLAN_ACT_SET
#ifdef WIFI_DIRECT_SUPPORT #ifdef WIFI_DIRECT_SUPPORT
&& (pmpriv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT) && (pmpriv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT)
#endif #endif

View file

@ -4,7 +4,7 @@
* module. * module.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -4,7 +4,7 @@
* transmission in MLAN module. * transmission in MLAN module.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -85,22 +85,24 @@ t_void *wlan_ops_sta_process_txpd(t_void *priv, pmlan_buffer pmbuf)
} }
if (pmbuf->data_offset < if (pmbuf->data_offset <
(sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { (Tx_PD_SIZEOF(pmadapter) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) {
PRINTM(MERROR, PRINTM(MERROR,
"not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n", "not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n",
pmbuf->data_offset, pmbuf->data_len, pmbuf->data_offset, pmbuf->data_len,
sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT); Tx_PD_SIZEOF(pmadapter) + pmpriv->intf_hr_len +
DMA_ALIGNMENT);
pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
goto done; goto done;
} }
/* head_ptr should be aligned */ /* head_ptr should be aligned */
head_ptr = pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - head_ptr = pmbuf->pbuf + pmbuf->data_offset - Tx_PD_SIZEOF(pmadapter) -
pmpriv->intf_hr_len; pmpriv->intf_hr_len;
head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1))); head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1)));
plocal_tx_pd = (TxPD *)(head_ptr + pmpriv->intf_hr_len); plocal_tx_pd = (TxPD *)(head_ptr + pmpriv->intf_hr_len);
memset(pmadapter, plocal_tx_pd, 0, sizeof(TxPD)); // coverity[bad_memset:SUPPRESS]
memset(pmadapter, plocal_tx_pd, 0, Tx_PD_SIZEOF(pmadapter));
/* Set the BSS number to TxPD */ /* Set the BSS number to TxPD */
plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv);
plocal_tx_pd->bss_type = pmpriv->bss_type; plocal_tx_pd->bss_type = pmpriv->bss_type;
@ -230,7 +232,7 @@ mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
{ {
pmlan_adapter pmadapter = MNULL; pmlan_adapter pmadapter = MNULL;
TxPD *ptx_pd; TxPD *ptx_pd;
/* sizeof(TxPD) + Interface specific header */ /* Tx_PD_SIZEOF(pmadapter) + Interface specific header */
#define NULL_PACKET_HDR 256 #define NULL_PACKET_HDR 256
t_u32 data_len = NULL_PACKET_HDR; t_u32 data_len = NULL_PACKET_HDR;
pmlan_buffer pmbuf = MNULL; pmlan_buffer pmbuf = MNULL;
@ -280,12 +282,12 @@ mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
pmbuf->buf_type = MLAN_BUF_TYPE_DATA; pmbuf->buf_type = MLAN_BUF_TYPE_DATA;
pmbuf->flags |= MLAN_BUF_FLAG_NULL_PKT; pmbuf->flags |= MLAN_BUF_FLAG_NULL_PKT;
ptr = pmbuf->pbuf + pmbuf->data_offset; ptr = pmbuf->pbuf + pmbuf->data_offset;
pmbuf->data_len = sizeof(TxPD) + priv->intf_hr_len; pmbuf->data_len = Tx_PD_SIZEOF(pmadapter) + priv->intf_hr_len;
ptx_pd = (TxPD *)(ptr + priv->intf_hr_len); ptx_pd = (TxPD *)(ptr + priv->intf_hr_len);
ptx_pd->tx_control = priv->pkt_tx_ctrl; ptx_pd->tx_control = priv->pkt_tx_ctrl;
ptx_pd->flags = flags; ptx_pd->flags = flags;
ptx_pd->priority = WMM_HIGHEST_PRIORITY; ptx_pd->priority = WMM_HIGHEST_PRIORITY;
ptx_pd->tx_pkt_offset = sizeof(TxPD); ptx_pd->tx_pkt_offset = Tx_PD_SIZEOF(pmadapter);
/* Set the BSS number to TxPD */ /* Set the BSS number to TxPD */
ptx_pd->bss_num = GET_BSS_NUM(priv); ptx_pd->bss_num = GET_BSS_NUM(priv);
ptx_pd->bss_type = priv->bss_type; ptx_pd->bss_type = priv->bss_type;
@ -325,7 +327,8 @@ mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); PRINTM_GET_SYS_TIME(MDATA, &sec, &usec);
PRINTM_NETINTF(MDATA, priv); PRINTM_NETINTF(MDATA, priv);
PRINTM(MDATA, "%lu.%06lu : Null data => FW\n", sec, usec); PRINTM(MDATA, "%lu.%06lu : Null data => FW\n", sec, usec);
DBG_HEXDUMP(MDAT_D, "Null data", ptr, sizeof(TxPD) + priv->intf_hr_len); DBG_HEXDUMP(MDAT_D, "Null data", ptr,
Tx_PD_SIZEOF(pmadapter) + priv->intf_hr_len);
done: done:
LEAVE(); LEAVE();
return ret; return ret;

View file

@ -203,8 +203,8 @@ mlan_status wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf,
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA)
plocal_tx_pd = (TxPD *)(head_ptr + priv->intf_hr_len); plocal_tx_pd = (TxPD *)(head_ptr + priv->intf_hr_len);
#endif #endif
dest_mac_first_octet = *(head_ptr + priv->intf_hr_len + sizeof(TxPD) + dest_mac_first_octet = *(head_ptr + priv->intf_hr_len +
DEST_MAC_OFFSET); Tx_PD_SIZEOF(pmadapter) + DEST_MAC_OFFSET);
if (dest_mac_first_octet & 0x01) if (dest_mac_first_octet & 0x01)
wlan_drv_mcast_cycle_delay_calulation(pmadapter, pmbuf); wlan_drv_mcast_cycle_delay_calulation(pmadapter, pmbuf);
@ -223,7 +223,7 @@ done:
case MLAN_STATUS_PRESOURCE: case MLAN_STATUS_PRESOURCE:
PRINTM(MINFO, "MLAN_STATUS_PRESOURCE is returned\n"); PRINTM(MINFO, "MLAN_STATUS_PRESOURCE is returned\n");
DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len, DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len,
MIN(pmbuf->data_len + sizeof(TxPD), MIN(pmbuf->data_len + Tx_PD_SIZEOF(pmadapter),
MAX_DATA_DUMP_LEN)); MAX_DATA_DUMP_LEN));
break; break;
#endif #endif
@ -246,12 +246,12 @@ done:
break; break;
case MLAN_STATUS_PENDING: case MLAN_STATUS_PENDING:
DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len, DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len,
MIN(pmbuf->data_len + sizeof(TxPD), MIN(pmbuf->data_len + Tx_PD_SIZEOF(pmadapter),
MAX_DATA_DUMP_LEN)); MAX_DATA_DUMP_LEN));
break; break;
case MLAN_STATUS_SUCCESS: case MLAN_STATUS_SUCCESS:
DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len, DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + priv->intf_hr_len,
MIN(pmbuf->data_len + sizeof(TxPD), MIN(pmbuf->data_len + Tx_PD_SIZEOF(pmadapter),
MAX_DATA_DUMP_LEN)); MAX_DATA_DUMP_LEN));
wlan_write_data_complete(pmadapter, pmbuf, ret); wlan_write_data_complete(pmadapter, pmbuf, ret);
break; break;

View file

@ -5690,6 +5690,8 @@ mlan_status wlan_ops_uap_process_event(t_void *priv)
wlan_delete_station_list(pmpriv); wlan_delete_station_list(pmpriv);
pmpriv->port_open = MFALSE; pmpriv->port_open = MFALSE;
pmpriv->amsdu_disable = MFALSE; pmpriv->amsdu_disable = MFALSE;
pmpriv->rxpd_rate_info = 0;
pmpriv->rxpd_rate = 0;
pmpriv->tx_pause = MFALSE; pmpriv->tx_pause = MFALSE;
break; break;
case EVENT_MICRO_AP_MIC_COUNTERMEASURES: case EVENT_MICRO_AP_MIC_COUNTERMEASURES:

View file

@ -3,7 +3,7 @@
* @brief This file contains AP mode transmit and receive functions * @brief This file contains AP mode transmit and receive functions
* *
* *
* Copyright 2009-2021 NXP * Copyright 2009-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -189,12 +189,13 @@ t_void *wlan_ops_uap_process_txpd(t_void *priv, pmlan_buffer pmbuf)
pmbuf->data_offset += sizeof(pkt_type) + sizeof(tx_control); pmbuf->data_offset += sizeof(pkt_type) + sizeof(tx_control);
pmbuf->data_len -= sizeof(pkt_type) + sizeof(tx_control); pmbuf->data_len -= sizeof(pkt_type) + sizeof(tx_control);
} }
if (pmbuf->data_offset < if (pmbuf->data_offset < (Tx_PD_SIZEOF(pmpriv->adapter) +
(sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { pmpriv->intf_hr_len + DMA_ALIGNMENT)) {
PRINTM(MERROR, PRINTM(MERROR,
"not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n", "not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n",
pmbuf->data_offset, pmbuf->data_len, pmbuf->data_offset, pmbuf->data_len,
sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT); Tx_PD_SIZEOF(pmpriv->adapter) + pmpriv->intf_hr_len +
DMA_ALIGNMENT);
DBG_HEXDUMP(MDAT_D, "drop pkt", DBG_HEXDUMP(MDAT_D, "drop pkt",
pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len); pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len);
pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID; pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
@ -202,12 +203,13 @@ t_void *wlan_ops_uap_process_txpd(t_void *priv, pmlan_buffer pmbuf)
} }
/* head_ptr should be aligned */ /* head_ptr should be aligned */
head_ptr = pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - head_ptr = pmbuf->pbuf + pmbuf->data_offset -
pmpriv->intf_hr_len; Tx_PD_SIZEOF(pmpriv->adapter) - pmpriv->intf_hr_len;
head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1))); head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1)));
plocal_tx_pd = (TxPD *)(head_ptr + pmpriv->intf_hr_len); plocal_tx_pd = (TxPD *)(head_ptr + pmpriv->intf_hr_len);
memset(pmpriv->adapter, plocal_tx_pd, 0, sizeof(TxPD)); // coverity[bad_memset:SUPPRESS]
memset(pmpriv->adapter, plocal_tx_pd, 0, Tx_PD_SIZEOF(pmpriv->adapter));
/* Set the BSS number to TxPD */ /* Set the BSS number to TxPD */
plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv);
@ -668,8 +670,8 @@ mlan_status wlan_uap_recv_packet(mlan_private *priv, pmlan_buffer pmbuf)
newbuf->in_ts_sec = pmbuf->in_ts_sec; newbuf->in_ts_sec = pmbuf->in_ts_sec;
newbuf->in_ts_usec = pmbuf->in_ts_usec; newbuf->in_ts_usec = pmbuf->in_ts_usec;
newbuf->data_offset = newbuf->data_offset =
(sizeof(TxPD) + priv->intf_hr_len + (Tx_PD_SIZEOF(pmadapter) +
DMA_ALIGNMENT); priv->intf_hr_len + DMA_ALIGNMENT);
util_scalar_increment( util_scalar_increment(
pmadapter->pmoal_handle, pmadapter->pmoal_handle,
&pmadapter->pending_bridge_pkts, &pmadapter->pending_bridge_pkts,
@ -716,8 +718,8 @@ mlan_status wlan_uap_recv_packet(mlan_private *priv, pmlan_buffer pmbuf)
newbuf->in_ts_sec = pmbuf->in_ts_sec; newbuf->in_ts_sec = pmbuf->in_ts_sec;
newbuf->in_ts_usec = pmbuf->in_ts_usec; newbuf->in_ts_usec = pmbuf->in_ts_usec;
newbuf->data_offset = newbuf->data_offset =
(sizeof(TxPD) + priv->intf_hr_len + (Tx_PD_SIZEOF(pmadapter) +
DMA_ALIGNMENT); priv->intf_hr_len + DMA_ALIGNMENT);
util_scalar_increment( util_scalar_increment(
pmadapter->pmoal_handle, pmadapter->pmoal_handle,
&pmadapter->pending_bridge_pkts, &pmadapter->pending_bridge_pkts,
@ -826,8 +828,8 @@ mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf)
newbuf->in_ts_sec = pmbuf->in_ts_sec; newbuf->in_ts_sec = pmbuf->in_ts_sec;
newbuf->in_ts_usec = pmbuf->in_ts_usec; newbuf->in_ts_usec = pmbuf->in_ts_usec;
newbuf->data_offset = newbuf->data_offset =
(sizeof(TxPD) + priv->intf_hr_len + (Tx_PD_SIZEOF(pmadapter) +
DMA_ALIGNMENT); priv->intf_hr_len + DMA_ALIGNMENT);
util_scalar_increment( util_scalar_increment(
pmadapter->pmoal_handle, pmadapter->pmoal_handle,
&pmadapter->pending_bridge_pkts, &pmadapter->pending_bridge_pkts,
@ -884,7 +886,8 @@ mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf)
newbuf->in_ts_usec = newbuf->in_ts_usec =
pmbuf->in_ts_usec; pmbuf->in_ts_usec;
newbuf->data_offset = newbuf->data_offset =
(sizeof(TxPD) + (Tx_PD_SIZEOF(
pmadapter) +
priv->intf_hr_len + priv->intf_hr_len +
DMA_ALIGNMENT); DMA_ALIGNMENT);
util_scalar_increment( util_scalar_increment(

View file

@ -3,7 +3,7 @@
* @brief This file contains USB specific code * @brief This file contains USB specific code
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -3,7 +3,7 @@
* @brief This file contains functions for WMM. * @brief This file contains functions for WMM.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -856,7 +856,8 @@ static INLINE void wlan_send_single_packet(pmlan_private priv, raListTbl *ptr,
pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
tx_param.next_pkt_len = tx_param.next_pkt_len =
((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : ((pmbuf_next) ? pmbuf_next->data_len +
Tx_PD_SIZEOF(pmadapter) :
0); 0);
status = wlan_process_tx(priv, pmbuf, &tx_param); status = wlan_process_tx(priv, pmbuf, &tx_param);
@ -962,7 +963,8 @@ static INLINE void wlan_send_processed_packet(pmlan_private priv,
pmadapter->callbacks.moal_spin_unlock( pmadapter->callbacks.moal_spin_unlock(
pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
tx_param.next_pkt_len = tx_param.next_pkt_len =
((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : ((pmbuf_next) ? pmbuf_next->data_len +
Tx_PD_SIZEOF(pmadapter) :
0); 0);
ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, pmbuf, ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, pmbuf,
@ -1007,10 +1009,10 @@ static INLINE void wlan_send_processed_packet(pmlan_private priv,
case MLAN_STATUS_PENDING: case MLAN_STATUS_PENDING:
break; break;
case MLAN_STATUS_SUCCESS: case MLAN_STATUS_SUCCESS:
DBG_HEXDUMP(MDAT_D, "Tx", DBG_HEXDUMP(
pmbuf->pbuf + pmbuf->data_offset, MDAT_D, "Tx", pmbuf->pbuf + pmbuf->data_offset,
MIN(pmbuf->data_len + sizeof(TxPD), MIN(pmbuf->data_len + Tx_PD_SIZEOF(pmadapter),
MAX_DATA_DUMP_LEN)); MAX_DATA_DUMP_LEN));
wlan_write_data_complete(pmadapter, pmbuf, ret); wlan_write_data_complete(pmadapter, pmbuf, ret);
break; break;
default: default:
@ -2877,6 +2879,69 @@ t_void wlan_restore_tdls_packets(pmlan_private priv, t_u8 *mac,
LEAVE(); LEAVE();
} }
/**
* @brief This function prepares the command of HOST ADDTS
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param pdata_buf A pointer to data buffer
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_wmm_host_addts_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_void *pdata_buf)
{
mlan_ds_tx_addts_cfg *paddts = (mlan_ds_tx_addts_cfg *)pdata_buf;
HostCmd_DS_WMM_HOST_ADDTS_REQ *pcmd_addts = &cmd->params.host_add_ts;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_HOST_ADDTS_REQ);
cmd->size = wlan_cpu_to_le16(sizeof(*pcmd_addts) + S_DS_GEN);
cmd->result = 0;
pcmd_addts->tsid = paddts->tsid;
;
pcmd_addts->user_prio = paddts->user_prio;
pcmd_addts->admitted_time = wlan_cpu_to_le16(paddts->admitted_time);
memcpy_ext(pmpriv->adapter, pcmd_addts->peer_addr, paddts->peer,
sizeof(pcmd_addts->peer_addr), MLAN_MAC_ADDR_LENGTH);
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares the command of HOST DELTS
*
* @param pmpriv A pointer to mlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param pdata_buf A pointer to data buffer
* @return MLAN_STATUS_SUCCESS
*/
mlan_status wlan_cmd_wmm_host_delts_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_void *pdata_buf)
{
mlan_ds_tx_delts_cfg *pdelts = (mlan_ds_tx_delts_cfg *)pdata_buf;
HostCmd_DS_WMM_HOST_DELTS_REQ *pcmd_delts = &cmd->params.host_del_ts;
ENTER();
cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_HOST_DELTS_REQ);
cmd->size = wlan_cpu_to_le16(sizeof(*pcmd_delts) + S_DS_GEN);
cmd->result = 0;
pcmd_delts->tsid = pdelts->tsid;
memcpy_ext(pmpriv->adapter, pcmd_delts->peer_addr, pdelts->peer,
sizeof(pcmd_delts->peer_addr), sizeof(MLAN_MAC_ADDR_LENGTH));
LEAVE();
return MLAN_STATUS_SUCCESS;
}
/** /**
* @brief This function prepares the command of ADDTS * @brief This function prepares the command of ADDTS
* *
@ -3309,6 +3374,67 @@ static mlan_status wlan_wmm_ioctl_delts_req(pmlan_adapter pmadapter,
return ret; return ret;
} }
/**
* @brief Request for add a TSPEC
*
* @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_wmm_ioctl_host_addts_req(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_wmm_cfg *cfg = MNULL;
ENTER();
cfg = (mlan_ds_wmm_cfg *)pioctl_req->pbuf;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_HOST_ADDTS_REQ, 0, 0,
(t_void *)pioctl_req,
(t_void *)&cfg->param.host_addts);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/**
* @brief Request for delete a TSPEC
*
* @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_wmm_ioctl_host_delts_req(pmlan_adapter pmadapter,
pmlan_ioctl_req pioctl_req)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
mlan_ds_wmm_cfg *cfg = MNULL;
ENTER();
cfg = (mlan_ds_wmm_cfg *)pioctl_req->pbuf;
/* Send request to firmware */
ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_HOST_DELTS_REQ, 0, 0,
(t_void *)pioctl_req,
(t_void *)&cfg->param.host_delts);
if (ret == MLAN_STATUS_SUCCESS)
ret = MLAN_STATUS_PENDING;
LEAVE();
return ret;
}
/** /**
* @brief To get and start/stop queue stats on a WMM AC * @brief To get and start/stop queue stats on a WMM AC
* *
@ -3619,6 +3745,12 @@ mlan_status wlan_wmm_cfg_ioctl(pmlan_adapter pmadapter,
case MLAN_OID_WMM_CFG_DELTS: case MLAN_OID_WMM_CFG_DELTS:
status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req); status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req);
break; break;
case MLAN_OID_WMM_CFG_HOST_ADDTS:
status = wlan_wmm_ioctl_host_addts_req(pmadapter, pioctl_req);
break;
case MLAN_OID_WMM_CFG_HOST_DELTS:
status = wlan_wmm_ioctl_host_delts_req(pmadapter, pioctl_req);
break;
case MLAN_OID_WMM_CFG_QUEUE_STATS: case MLAN_OID_WMM_CFG_QUEUE_STATS:
status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req); status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req);
break; break;

View file

@ -4,7 +4,7 @@
* of wmm functionalities * of wmm functionalities
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -203,6 +203,14 @@ extern mlan_status wlan_cmd_wmm_queue_stats(pmlan_private pmpriv,
extern mlan_status wlan_cmd_wmm_ts_status(pmlan_private pmpriv, extern mlan_status wlan_cmd_wmm_ts_status(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd, HostCmd_DS_COMMAND *cmd,
t_void *pdata_buf); t_void *pdata_buf);
/** WMM HOST ADDTS request command handler */
extern mlan_status wlan_cmd_wmm_host_addts_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_void *pdata_buf);
/** WMM HOST DELTS request command handler */
extern mlan_status wlan_cmd_wmm_host_delts_req(pmlan_private pmpriv,
HostCmd_DS_COMMAND *cmd,
t_void *pdata_buf);
/* /*
* Functions used in the cmdresp handling routine * Functions used in the cmdresp handling routine

View file

@ -3,7 +3,7 @@
* @brief This file declares the generic data structures and APIs. * @brief This file declares the generic data structures and APIs.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -2762,6 +2762,8 @@ typedef struct _mlan_device {
t_u32 antcfg; t_u32 antcfg;
/** dmcs */ /** dmcs */
t_u8 dmcs; t_u8 dmcs;
t_u32 reject_addba_req;
} mlan_device, *pmlan_device; } mlan_device, *pmlan_device;
/** MLAN API function prototype */ /** MLAN API function prototype */

View file

@ -4,7 +4,7 @@
* definitions used in MLAN and MOAL module. * definitions used in MLAN and MOAL module.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -884,6 +884,27 @@ typedef MLAN_PACK_START enum _IEEEtypes_WMM_Tspec_Action_e {
} MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_e; } MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_e;
/** NAN SDF vendor oui size */
#define NAN_SDF_VENDOR_SIZE 4
/** NAN service descriptor attribute offset */
#define NAN_SDA_OFFSET 5
/** NAN service control type offset */
#define NAN_SRVC_CTRL_OFFSET 11
/** Service control field */
#define NAN_SRV_CTRL_TYPE_MASK (BIT(0) | BIT(1))
/** NAN publish frame */
#define NAN_PUBLISH 0
/** NAN Attribute ID list */
typedef MLAN_PACK_START enum _Nan_AttrId_e {
NAN_ATTR_SDA = 0x03
} MLAN_PACK_END Nan_AttrId_e;
/** Public Action Codes */
typedef MLAN_PACK_START enum _IEEEtypes_Public_ActionCategory_e {
IEEE_PUBLIC_ACTION_CATEGORY_VENDOR_SPECIFIC = 9
} MLAN_PACK_END IEEEtypes_Public_ActionCategory_e;
/** WMM TSPEC Category Action Base */ /** WMM TSPEC Category Action Base */
typedef MLAN_PACK_START struct { typedef MLAN_PACK_START struct {
IEEEtypes_ActionCategory_e category; IEEEtypes_ActionCategory_e category;

View file

@ -3,7 +3,7 @@
* @brief This file declares the IOCTL data structures and APIs. * @brief This file declares the IOCTL data structures and APIs.
* *
* *
* Copyright 2008-2023 NXP * Copyright 2008-2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -183,6 +183,8 @@ enum _mlan_ioctl_req_id {
MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006, MLAN_OID_WMM_CFG_QUEUE_STATS = 0x000A0006,
MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007, MLAN_OID_WMM_CFG_QUEUE_STATUS = 0x000A0007,
MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008, MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008,
MLAN_OID_WMM_CFG_HOST_ADDTS = 0x000A000A,
MLAN_OID_WMM_CFG_HOST_DELTS = 0x000A000B,
/* WPS Configuration Group */ /* WPS Configuration Group */
MLAN_IOCTL_WPS_CFG = 0x000B0000, MLAN_IOCTL_WPS_CFG = 0x000B0000,
@ -2986,6 +2988,8 @@ typedef struct _mlan_data_rate {
typedef struct _mlan_ds_rate { typedef struct _mlan_ds_rate {
/** Sub-command */ /** Sub-command */
t_u32 sub_command; t_u32 sub_command;
/** Only set auto tx fix rate */
t_u16 auto_null_fixrate_enable;
/** Rate configuration parameter */ /** Rate configuration parameter */
union { union {
/** Rate configuration for MLAN_OID_RATE_CFG */ /** Rate configuration for MLAN_OID_RATE_CFG */
@ -3609,6 +3613,26 @@ typedef struct _mlan_ds_wmm_queue_config {
t_u8 reserved[10]; t_u8 reserved[10];
} mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config; } mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config;
/** WMM HOST ADDTS configuration parameters */
typedef struct _mlan_ds_tx_addts {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer[MLAN_MAC_ADDR_LENGTH];
/* User priority (UP) */
t_u8 user_prio;
/* Admitted Air time for UP */
t_u16 admitted_time;
} mlan_ds_tx_addts_cfg;
/** WMM HOST DELTS configuration parameters */
typedef struct _mlan_ds_tx_delts {
/* TS id - unique per tid, TA, RA combination */
t_u8 tsid;
/* RA BSSID */
t_u8 peer[MLAN_MAC_ADDR_LENGTH];
} mlan_ds_tx_delts_cfg;
/** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */ /** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */
typedef struct _mlan_ds_wmm_cfg { typedef struct _mlan_ds_wmm_cfg {
/** Sub-command */ /** Sub-command */
@ -3623,6 +3647,10 @@ typedef struct _mlan_ds_wmm_cfg {
mlan_ds_wmm_addts addts; mlan_ds_wmm_addts addts;
/** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */ /** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */
mlan_ds_wmm_delts delts; mlan_ds_wmm_delts delts;
/** WMM add TS for host config */
mlan_ds_tx_addts_cfg host_addts;
/** WMM del TS for host config */
mlan_ds_tx_delts_cfg host_delts;
/** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */ /** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */
mlan_ds_wmm_queue_config q_cfg; mlan_ds_wmm_queue_config q_cfg;
/** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI,
@ -4138,7 +4166,7 @@ typedef struct _mlan_ds_11ax_rutxpwr_cmd {
* and 6 for other SOCs */ * and 6 for other SOCs */
t_u8 col; t_u8 col;
/**ru tx data */ /**ru tx data */
t_u8 rutxSubPwr[89]; t_s8 rutxSubPwr[89];
} mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd; } mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd;
/** Type definition of mlan_ds_11ax_cmd_cfg for MLAN_OID_11AX_CMD_CFG */ /** Type definition of mlan_ds_11ax_cmd_cfg for MLAN_OID_11AX_CMD_CFG */
@ -4787,7 +4815,10 @@ typedef struct _mlan_ds_misc_ipaddr_cfg {
typedef struct _mlan_ds_misc_ipv6_ra_offload { typedef struct _mlan_ds_misc_ipv6_ra_offload {
/** 0: disable; 1: enable*/ /** 0: disable; 1: enable*/
t_u8 enable; t_u8 enable;
t_u8 ipv6_addr[16]; /** Number of IPv6 address configured in FW */
t_u8 ipv6_addrs_count;
/** Ipv6 address array */
t_u8 ipv6_addrs[];
} mlan_ds_misc_ipv6_ra_offload; } mlan_ds_misc_ipv6_ra_offload;
/* MEF configuration disable */ /* MEF configuration disable */

View file

@ -2889,6 +2889,34 @@ done:
return ret; return ret;
} }
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
/*
* @brief validate if packet is NAN publish
*
* @param buf Frame buffer
*
* @return true -- success, otherwise false
*/
static BOOLEAN is_nan_publish(const t_u8 *buf)
{
t_u8 nan_sdf_oui[4] = {0x50, 0x6f, 0x9a, 0x13};
t_u8 nan_attr_id, nan_srv_ctrl_type;
if (!memcmp(nan_sdf_oui, buf + 1, NAN_SDF_VENDOR_SIZE)) {
nan_attr_id = *(buf + NAN_SDA_OFFSET);
nan_srv_ctrl_type =
*(buf + NAN_SDA_OFFSET + NAN_SRVC_CTRL_OFFSET);
if (nan_attr_id == NAN_ATTR_SDA &&
(nan_srv_ctrl_type & NAN_SRV_CTRL_TYPE_MASK) ==
NAN_PUBLISH) {
return MTRUE;
}
}
return MFALSE;
}
#endif
#if KERNEL_VERSION(3, 2, 0) <= CFG80211_VERSION_CODE #if KERNEL_VERSION(3, 2, 0) <= CFG80211_VERSION_CODE
#if KERNEL_VERSION(3, 3, 0) <= CFG80211_VERSION_CODE #if KERNEL_VERSION(3, 3, 0) <= CFG80211_VERSION_CODE
#if KERNEL_VERSION(3, 6, 0) <= CFG80211_VERSION_CODE #if KERNEL_VERSION(3, 6, 0) <= CFG80211_VERSION_CODE
@ -3041,6 +3069,9 @@ int woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
moal_private *remain_priv = NULL; moal_private *remain_priv = NULL;
#endif #endif
t_u16 fc, type, stype; t_u16 fc, type, stype;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
t_u8 category, action;
#endif
ENTER(); ENTER();
if (buf == NULL || len == 0) { if (buf == NULL || len == 0) {
@ -3226,6 +3257,26 @@ int woal_cfg80211_mgmt_tx(struct wiphy *wiphy,
*cookie = get_random_u32() | 1; *cookie = get_random_u32() | 1;
#endif #endif
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
if (ieee80211_is_action(
((struct ieee80211_mgmt *)buf)->frame_control)) {
category = *(buf + sizeof(moal_802_11_action_header) - 1);
action = *(buf + sizeof(moal_802_11_action_header));
if (category == IEEE_MGMT_ACTION_CATEGORY_PUBLIC &&
action == IEEE_PUBLIC_ACTION_CATEGORY_VENDOR_SPECIFIC &&
is_nan_publish(buf + sizeof(moal_802_11_action_header))) {
priv->phandle->nan_cookie = *cookie;
if (priv->phandle->is_nan_timer_set) {
woal_cancel_timer(&priv->phandle->nan_timer);
priv->phandle->is_nan_timer_set = MFALSE;
}
priv->phandle->is_nan_timer_set = MTRUE;
woal_mod_timer(&priv->phandle->nan_timer, wait);
}
}
#endif
ret = woal_mgmt_tx(priv, buf, len, chan, *cookie, wait); ret = woal_mgmt_tx(priv, buf, len, chan, *cookie, wait);
done: done:

View file

@ -3,7 +3,7 @@
* @brief This file contains the CFG80211 vendor specific defines. * @brief This file contains the CFG80211 vendor specific defines.
* *
* *
* Copyright 2015-2021 NXP * Copyright 2015-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -2080,7 +2080,7 @@ done:
static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf, static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
t_u32 respbuflen) t_u32 respbuflen)
{ {
t_u32 data[4]; t_u32 data[5];
mlan_ioctl_req *req = NULL; mlan_ioctl_req *req = NULL;
mlan_ds_rate *rate = NULL; mlan_ds_rate *rate = NULL;
woal_tx_rate_cfg *ratecfg = NULL; woal_tx_rate_cfg *ratecfg = NULL;
@ -2102,12 +2102,18 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
data, ARRAY_SIZE(data), &user_data_len); data, ARRAY_SIZE(data), &user_data_len);
} }
if (user_data_len > 4) { if (user_data_len > 5) {
PRINTM(MERROR, "Too many arguments\n"); PRINTM(MERROR, "Too many arguments\n");
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
} }
if ((user_data_len == 5) && (data[4] > 1)) {
PRINTM(MERROR, "Invalid auto_null_fixrate parameter");
ret = -EINVAL;
goto done;
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate)); req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
if (req == NULL) { if (req == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
@ -2119,6 +2125,8 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
rate->sub_command = MLAN_OID_RATE_CFG; rate->sub_command = MLAN_OID_RATE_CFG;
rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX; rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;
rate->auto_null_fixrate_enable = 0xFF;
if (user_data_len == 0) { if (user_data_len == 0) {
/* Get operation */ /* Get operation */
req->action = MLAN_ACT_GET; req->action = MLAN_ACT_GET;
@ -2180,7 +2188,7 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
} }
rate->param.rate_cfg.nss = data[2]; rate->param.rate_cfg.nss = data[2];
} }
if (user_data_len == 4) { if ((user_data_len == 4) || (data[4] == 1)) {
rate->param.rate_cfg.rate_setting = rate->param.rate_cfg.rate_setting =
data[3] & ~0x0C00; data[3] & ~0x0C00;
PRINTM(MIOCTL, PRINTM(MIOCTL,
@ -2246,6 +2254,13 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf,
} else { } else {
rate->param.rate_cfg.rate_setting = 0xffff; rate->param.rate_cfg.rate_setting = 0xffff;
} }
if (user_data_len == 5) {
rate->auto_null_fixrate_enable = data[4];
PRINTM(MINFO,
"SET: auto_null_fixrate_enable: 0x%x\n",
data[4]);
}
} }
} }

View file

@ -4,7 +4,7 @@
* driver. * driver.
* *
* *
* Copyright 2018-2022 NXP * Copyright 2018-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -421,6 +421,8 @@ static int dfs53cfg = DFS_W53_DEFAULT_FW;
static int keep_previous_scan = 1; static int keep_previous_scan = 1;
static int auto_11ax = 1; static int auto_11ax = 1;
static int reject_addba_req = 0;
/** /**
* @brief This function read a line in module parameter file * @brief This function read a line in module parameter file
* *
@ -1539,6 +1541,14 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size,
goto err; goto err;
params->dual_nb = out_data; params->dual_nb = out_data;
PRINTM(MMSG, "dual_nb=%d\n", params->dual_nb); PRINTM(MMSG, "dual_nb=%d\n", params->dual_nb);
} else if (strncmp(line, "reject_addba_req",
strlen("reject_addba_req")) == 0) {
if (parse_line_read_int(line, &out_data) !=
MLAN_STATUS_SUCCESS)
goto err;
params->reject_addba_req = out_data;
PRINTM(MMSG, "reject_addba_req=%x\n",
params->reject_addba_req);
} }
} }
if (end) if (end)
@ -1903,6 +1913,7 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params)
} }
handle->params.keep_previous_scan = keep_previous_scan; handle->params.keep_previous_scan = keep_previous_scan;
handle->params.auto_11ax = auto_11ax; handle->params.auto_11ax = auto_11ax;
handle->params.reject_addba_req = reject_addba_req;
handle->params.dual_nb = dual_nb; handle->params.dual_nb = dual_nb;
if (params) if (params)
handle->params.dual_nb = params->dual_nb; handle->params.dual_nb = params->dual_nb;
@ -2448,6 +2459,13 @@ void woal_init_from_dev_tree(void)
PRINTM(MERROR, "auto_11ax=0x%x\n", data); PRINTM(MERROR, "auto_11ax=0x%x\n", data);
auto_11ax = data; auto_11ax = data;
} }
} else if (!strncmp(prop->name, "reject_addba_req",
strlen("reject_addba_req"))) {
if (!of_property_read_u32(dt_node, prop->name, &data)) {
PRINTM(MERROR, "rej_addba_req_cfg=0x%x\n",
data);
reject_addba_req = data;
}
} }
#if defined(STA_CFG80211) || defined(UAP_CFG80211) #if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@ -3019,3 +3037,8 @@ MODULE_PARM_DESC(
module_param(dual_nb, int, 0); module_param(dual_nb, int, 0);
MODULE_PARM_DESC(dual_nb, "0: Single BT (Default); 1: Dual BT"); MODULE_PARM_DESC(dual_nb, "0: Single BT (Default); 1: Dual BT");
module_param(reject_addba_req, int, 0);
MODULE_PARM_DESC(
reject_addba_req,
"Bit1: Reject the addba request when FW auto re-connect enabled (STA BSS only); Bit0: Reject the addba request when HS activated");

View file

@ -36,7 +36,7 @@ Change log:
#ifdef UAP_SUPPORT #ifdef UAP_SUPPORT
#include "moal_uap.h" #include "moal_uap.h"
#endif #endif
#include <linux/list.h>
#if defined(STA_CFG80211) || defined(UAP_CFG80211) #if defined(STA_CFG80211) || defined(UAP_CFG80211)
#include "moal_cfg80211.h" #include "moal_cfg80211.h"
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
@ -1210,9 +1210,12 @@ void woal_check_mc_connection(moal_private *priv, t_u8 wait_option,
int i; int i;
#endif #endif
t_u16 enable = 0; t_u16 enable = 0;
if (priv->phandle->card_info->drcs &&
if (woal_mc_policy_cfg(priv, &enable, wait_option, MLAN_ACT_GET)) { moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS)) {
PRINTM(MERROR, "Get multi-channel policy failed\n"); if (woal_mc_policy_cfg(priv, &enable, wait_option,
MLAN_ACT_GET)) {
PRINTM(MERROR, "Get multi-channel policy failed\n");
}
} }
if (!enable) if (!enable)
@ -3090,8 +3093,10 @@ static mlan_status woal_set_ipv6_ra_offload(moal_handle *handle, t_u8 enable)
moal_private *priv = NULL; moal_private *priv = NULL;
mlan_ds_misc_cfg *misc = NULL; mlan_ds_misc_cfg *misc = NULL;
mlan_ioctl_req *req = NULL; mlan_ioctl_req *req = NULL;
mlan_ds_misc_ipv6_ra_offload *ipv6_ra; t_u8 *ipv6_ra;
int i = 0; int i = 0;
unsigned long flags;
struct ipv6addr_entry *ipv6_entry = NULL;
ENTER(); ENTER();
@ -3115,10 +3120,18 @@ static mlan_status woal_set_ipv6_ra_offload(moal_handle *handle, t_u8 enable)
misc->sub_command = MLAN_OID_MISC_IPV6_RA_OFFLOAD; misc->sub_command = MLAN_OID_MISC_IPV6_RA_OFFLOAD;
req->req_id = MLAN_IOCTL_MISC_CFG; req->req_id = MLAN_IOCTL_MISC_CFG;
req->action = MLAN_ACT_SET; req->action = MLAN_ACT_SET;
ipv6_ra = &misc->param.ipv6_ra_offload;
ipv6_ra->enable = enable; misc->param.ipv6_ra_offload.enable = enable;
moal_memcpy_ext(priv->phandle, ipv6_ra->ipv6_addr, priv->ipv6_addr, 16, misc->param.ipv6_ra_offload.ipv6_addrs_count = priv->ipv6count;
sizeof(ipv6_ra->ipv6_addr)); spin_lock_irqsave(&priv->ipv6addr_lock, flags);
ipv6_ra = misc->param.ipv6_ra_offload.ipv6_addrs;
list_for_each_entry (ipv6_entry, &priv->ipv6_addrses, link) {
moal_memcpy_ext(priv->phandle, ipv6_ra, ipv6_entry->ipv6_addr,
IPADDR_LEN, IPADDR_LEN);
ipv6_ra += IPADDR_LEN;
}
spin_unlock_irqrestore(&priv->ipv6addr_lock, flags);
ret = woal_request_ioctl(woal_get_priv(handle, MLAN_BSS_ROLE_STA), req, ret = woal_request_ioctl(woal_get_priv(handle, MLAN_BSS_ROLE_STA), req,
MOAL_NO_WAIT); MOAL_NO_WAIT);
if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING) if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING)
@ -3691,7 +3704,7 @@ mlan_status woal_cancel_hs(moal_private *priv, t_u8 wait_option)
hscfg.conditions = HOST_SLEEP_CFG_CANCEL; hscfg.conditions = HOST_SLEEP_CFG_CANCEL;
hscfg.is_invoke_hostcmd = MTRUE; hscfg.is_invoke_hostcmd = MTRUE;
ret = woal_set_get_hs_params(priv, MLAN_ACT_SET, wait_option, &hscfg); ret = woal_set_get_hs_params(priv, MLAN_ACT_SET, wait_option, &hscfg);
if (ret != MLAN_STATUS_SUCCESS) { if (ret != MLAN_STATUS_SUCCESS && ret != MLAN_STATUS_PENDING) {
PRINTM(MERROR, "%s: woal_set_get_hs_params failed \n", PRINTM(MERROR, "%s: woal_set_get_hs_params failed \n",
__func__); __func__);
LEAVE(); LEAVE();
@ -8306,7 +8319,7 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len,
if (pos) if (pos)
d->data3 = (t_u32)woal_string_to_number(pos); d->data3 = (t_u32)woal_string_to_number(pos);
if (((d->data1 > pow_limit) && (d->data1 != 0xffffffff)) || if (((d->data1 > pow_limit) && (d->data1 <= 0xfffffff0)) ||
(d->data2 > 2)) (d->data2 > 2))
ret = -EINVAL; ret = -EINVAL;

View file

@ -347,7 +347,7 @@ static struct _card_info card_info_SD8978 = {
#ifdef SD8997 #ifdef SD8997
static struct _card_info card_info_SD8997 = { static struct _card_info card_info_SD8997 = {
.embedded_supp = 1, .embedded_supp = 1,
.drcs = 1, .drcs = 0,
.go_noa = 1, .go_noa = 1,
.v16_fw_api = 1, .v16_fw_api = 1,
.pmic = 1, .pmic = 1,
@ -651,7 +651,7 @@ static struct _card_info card_info_SDIW615 = {
#ifdef PCIE8997 #ifdef PCIE8997
static struct _card_info card_info_PCIE8997 = { static struct _card_info card_info_PCIE8997 = {
.embedded_supp = 1, .embedded_supp = 1,
.drcs = 1, .drcs = 0,
.go_noa = 1, .go_noa = 1,
.v16_fw_api = 1, .v16_fw_api = 1,
.pmic = 1, .pmic = 1,
@ -1238,6 +1238,13 @@ void woal_clean_up(moal_handle *handle)
GFP_KERNEL); GFP_KERNEL);
} }
#endif #endif
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
if (handle->is_nan_timer_set) {
woal_cancel_timer(&handle->nan_timer);
handle->is_nan_timer_set = MFALSE;
}
#endif #endif
// stop bgscan // stop bgscan
#ifdef STA_CFG80211 #ifdef STA_CFG80211
@ -1693,6 +1700,65 @@ done:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
/**
* @brief This function deletes the IPv6 Address entry
*
* @param priv A pointer to moal_private structure
*
* @return N/A
*/
static void woal_remove_ipv6_address(moal_private *priv, t_u8 *addr)
{
struct ipv6addr_entry *ipv6_entry = NULL, *tmp_ipv6_entry;
unsigned long flags;
spin_lock_irqsave(&priv->ipv6addr_lock, flags);
list_for_each_entry_safe (ipv6_entry, tmp_ipv6_entry,
&priv->ipv6_addrses, link) {
if (memcmp(addr, ipv6_entry->ipv6_addr, IPADDR_LEN) == 0) {
priv->ipv6count -= 1;
list_del(&ipv6_entry->link);
kfree(ipv6_entry);
break;
}
}
spin_unlock_irqrestore(&priv->ipv6addr_lock, flags);
if (list_empty(&priv->ipv6_addrses))
priv->ipv6_addr_configured = MFALSE;
}
/**
* @brief This function adds the IPv6 Address entry
*
* @param priv A pointer to moal_private structure
*
* @return N/A
*/
static void woal_add_ipv6_address(moal_private *priv, t_u8 *addr)
{
struct ipv6addr_entry *pipv6_entry = NULL, *ipv6_entry = NULL;
unsigned long flags;
list_for_each_entry (ipv6_entry, &priv->ipv6_addrses, link) {
if (!memcmp(ipv6_entry->ipv6_addr, addr, IPADDR_LEN)) {
PRINTM(MIOCTL, "ipv6 addr already exists\n");
return;
}
}
pipv6_entry = kzalloc(sizeof(struct ipv6addr_entry), GFP_ATOMIC);
if (pipv6_entry) {
spin_lock_irqsave(&priv->ipv6addr_lock, flags);
INIT_LIST_HEAD(&pipv6_entry->link);
moal_memcpy_ext(priv->phandle, pipv6_entry->ipv6_addr,
(t_u8 *)addr, IPADDR_LEN, IPADDR_LEN);
list_add_tail(&pipv6_entry->link, &priv->ipv6_addrses);
spin_unlock_irqrestore(&priv->ipv6addr_lock, flags);
priv->ipv6count += 1;
}
priv->ipv6_addr_configured = MTRUE;
}
/** /**
* @brief This function handle the net interface ipv6 address change event * @brief This function handle the net interface ipv6 address change event
* *
@ -1709,7 +1775,7 @@ static int woal_inet6_netdeive_event(struct notifier_block *nb,
struct net_device *ndev = ifa->idev->dev; struct net_device *ndev = ifa->idev->dev;
moal_private *priv; moal_private *priv;
int ret = NOTIFY_OK; int ret = NOTIFY_OK;
t_u8 addr[16] = {0};
ENTER(); ENTER();
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
@ -1744,15 +1810,13 @@ static int woal_inet6_netdeive_event(struct notifier_block *nb,
switch (event) { switch (event) {
case NETDEV_UP: case NETDEV_UP:
PRINTM(MIOCTL, "[%s]: New ipv6 addr\n", ndev->name); PRINTM(MIOCTL, "[%s]: New ipv6 addr\n", ndev->name);
moal_memcpy_ext(priv->phandle, priv->ipv6_addr, moal_memcpy_ext(priv->phandle, addr, (t_u8 *)&ifa->addr,
(t_u8 *)&ifa->addr, sizeof(priv->ipv6_addr), sizeof(addr), sizeof(addr));
sizeof(priv->ipv6_addr)); woal_add_ipv6_address(priv, addr);
priv->ipv6_addr_configured = MTRUE;
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
PRINTM(MIOCTL, "[%s]: Ipv6 addr removed.\n", ndev->name); PRINTM(MIOCTL, "[%s]: Ipv6 addr removed.\n", ndev->name);
memset(priv->ipv6_addr, 0, sizeof(priv->ipv6_addr)); woal_remove_ipv6_address(priv, (t_u8 *)&ifa->addr);
priv->ipv6_addr_configured = MFALSE;
break; break;
default: default:
PRINTM(MIOCTL, "[%s]: Ignore event: %u\n", ndev->name, PRINTM(MIOCTL, "[%s]: Ignore event: %u\n", ndev->name,
@ -1793,6 +1857,37 @@ BOOLEAN woal_ssid_valid(mlan_802_11_ssid *pssid)
return MTRUE; return MTRUE;
} }
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
/**
* @brief Tx management timeout for NAN function
*
* @param context A pointer to context
* @return N/A
*/
void woal_nan_timer_func(void *context)
{
moal_handle *handle = (moal_handle *)context;
moal_private *priv = handle->priv[handle->remain_bss_index];
ENTER();
if (!priv->phandle->nan_cookie) {
PRINTM(MWARN, "NAN cookie not set\n");
LEAVE();
return;
}
PRINTM(MEVENT, "NAN timer started.\n");
cfg80211_tx_mgmt_expired(priv->wdev, priv->phandle->nan_cookie,
&priv->phandle->chan, GFP_ATOMIC);
priv->phandle->is_nan_timer_set = MFALSE;
priv->phandle->nan_cookie = 0;
LEAVE();
return;
}
#endif
#if defined(STA_CFG80211) || defined(UAP_CFG80211) #if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
/** /**
@ -2454,6 +2549,11 @@ mlan_status woal_init_sw(moal_handle *handle)
handle); handle);
handle->is_remain_timer_set = MFALSE; handle->is_remain_timer_set = MFALSE;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
woal_initialize_timer(&handle->nan_timer, woal_nan_timer_func, handle);
#endif
#endif #endif
#endif #endif
@ -2577,6 +2677,7 @@ mlan_status woal_init_sw(moal_handle *handle)
device.second_mac = handle->second_mac; device.second_mac = handle->second_mac;
device.antcfg = handle->params.antcfg; device.antcfg = handle->params.antcfg;
device.dmcs = moal_extflg_isset(handle, EXT_DMCS); device.dmcs = moal_extflg_isset(handle, EXT_DMCS);
device.reject_addba_req = handle->params.reject_addba_req;
for (i = 0; i < handle->drv_mode.intf_num; i++) { for (i = 0; i < handle->drv_mode.intf_num; i++) {
device.bss_attr[i].bss_type = device.bss_attr[i].bss_type =
@ -5515,6 +5616,13 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index,
#endif #endif
#endif #endif
#ifdef STA_CFG80211
#ifdef STA_SUPPORT
INIT_LIST_HEAD(&priv->ipv6_addrses);
spin_lock_init(&priv->ipv6addr_lock);
#endif
#endif
#ifdef STA_SUPPORT #ifdef STA_SUPPORT
INIT_LIST_HEAD(&priv->pmksa_cache_list); INIT_LIST_HEAD(&priv->pmksa_cache_list);
if (bss_type == MLAN_BSS_TYPE_STA) { if (bss_type == MLAN_BSS_TYPE_STA) {
@ -9831,6 +9939,7 @@ void woal_fw_dump_timer_func(void *context)
handle->is_fw_dump_timer_set = MFALSE; handle->is_fw_dump_timer_set = MFALSE;
if (handle->priv_num) if (handle->priv_num)
woal_process_hang(handle); woal_process_hang(handle);
handle->fw_dump = MFALSE;
LEAVE(); LEAVE();
return; return;
} }

View file

@ -436,6 +436,24 @@ typedef struct _moal_drv_timer {
t_u32 timer_is_canceled; t_u32 timer_is_canceled;
} moal_drv_timer, *pmoal_drv_timer; } moal_drv_timer, *pmoal_drv_timer;
/** moal_802_11_action header */
typedef struct {
/** Frame Cotrol */
t_u16 frame_control;
/** Duration */
t_u16 duration;
/** dest addr */
t_u8 da[ETH_ALEN];
/** source addr */
t_u8 sa[ETH_ALEN];
/** bssid */
t_u8 bssid[ETH_ALEN];
/** seq_ctrl */
t_u16 seq_ctrl;
/** category */
t_u8 category;
} __attribute__((packed)) moal_802_11_action_header;
/** /**
* @brief Timer handler * @brief Timer handler
* *
@ -1373,7 +1391,7 @@ struct rf_test_mode_data {
/* Rx fcs error count */ /* Rx fcs error count */
t_u32 rx_pkt_fcs_err_count; t_u32 rx_pkt_fcs_err_count;
/* Tx power config values */ /* Tx power config values */
t_u32 tx_power_data[3]; t_s32 tx_power_data[3];
/* Tx continuous config values */ /* Tx continuous config values */
t_u32 tx_cont_data[6]; t_u32 tx_cont_data[6];
/* Tx frame config values */ /* Tx frame config values */
@ -1550,6 +1568,13 @@ enum scan_set_band {
}; };
#endif #endif
/** IPv6 address node */
struct ipv6addr_entry {
/** list node link */
struct list_head link;
/** IPv6 address entry */
t_u8 ipv6_addr[16];
};
/** Private structure for MOAL */ /** Private structure for MOAL */
struct _moal_private { struct _moal_private {
/** Handle structure */ /** Handle structure */
@ -1637,7 +1662,12 @@ struct _moal_private {
/** IP addr */ /** IP addr */
t_u8 ip_addr[IPADDR_LEN]; t_u8 ip_addr[IPADDR_LEN];
t_u8 ipv6_addr_configured; t_u8 ipv6_addr_configured;
t_u8 ipv6_addr[16]; /** IPv6 addr count */
t_u8 ipv6count;
/** IPv6 addr Queue */
struct list_head ipv6_addrses;
/** Lock for IPv6 addrs */
spinlock_t ipv6addr_lock;
#ifdef STA_SUPPORT #ifdef STA_SUPPORT
/** scan type */ /** scan type */
t_u8 scan_type; t_u8 scan_type;
@ -2598,6 +2628,8 @@ typedef struct _moal_mod_para {
int hs_auto_arp; int hs_auto_arp;
/** Dual-BT **/ /** Dual-BT **/
int dual_nb; int dual_nb;
/* reject addba req config for HS or FW Auto-reconnect */
t_u32 reject_addba_req;
} moal_mod_para; } moal_mod_para;
void woal_tp_acnt_timer_func(void *context); void woal_tp_acnt_timer_func(void *context);
@ -2917,6 +2949,15 @@ struct _moal_handle {
t_u64 cookie; t_u64 cookie;
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
/** Tx frame wait cancel timer set flag */
BOOLEAN is_nan_timer_set;
/** Tx frame wait timer for nan publish */
moal_drv_timer nan_timer __ATTRIB_ALIGN__;
/** NAN cookie */
t_u64 nan_cookie;
#endif
#ifdef WIFI_DIRECT_SUPPORT #ifdef WIFI_DIRECT_SUPPORT
/** NoA duration */ /** NoA duration */
t_u32 noa_duration; t_u32 noa_duration;
@ -4116,6 +4157,9 @@ int woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req);
mlan_status woal_set_remain_channel_ioctl(moal_private *priv, t_u8 wait_option, mlan_status woal_set_remain_channel_ioctl(moal_private *priv, t_u8 wait_option,
pmlan_ds_remain_chan pchan); pmlan_ds_remain_chan pchan);
void woal_remain_timer_func(void *context); void woal_remain_timer_func(void *context);
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
void woal_nan_timer_func(void *context);
#endif
#ifdef WIFI_DIRECT_SUPPORT #ifdef WIFI_DIRECT_SUPPORT
mlan_status woal_wifi_direct_mode_cfg(moal_private *priv, t_u16 action, mlan_status woal_wifi_direct_mode_cfg(moal_private *priv, t_u16 action,
t_u16 *mode); t_u16 *mode);

View file

@ -4,7 +4,7 @@
* related functions. * related functions.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -459,6 +459,7 @@ static mlan_status woal_do_flr(moal_handle *handle, bool prepare, bool flr_flag)
if (IS_PCIE9098(handle->card_type)) if (IS_PCIE9098(handle->card_type))
handle->event_fw_dump = MTRUE; handle->event_fw_dump = MTRUE;
#endif #endif
handle->fw_dump = MFALSE;
goto exit; goto exit;

View file

@ -4,7 +4,7 @@
* driver. * driver.
* *
* *
* Copyright 2014-2021 NXP * Copyright 2014-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -4,7 +4,7 @@
* driver. * driver.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -4,7 +4,7 @@
* related functions. * related functions.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991
@ -3115,6 +3115,7 @@ static mlan_status woal_do_sdiommc_flr(moal_handle *handle, bool prepare,
if (IS_SD9177(handle->card_type)) if (IS_SD9177(handle->card_type))
handle->event_fw_dump = MTRUE; handle->event_fw_dump = MTRUE;
#endif #endif
handle->fw_dump = MFALSE;
goto exit; goto exit;

View file

@ -2781,7 +2781,7 @@ static mlan_status wlan_process_defer_event(moal_handle *handle,
* @return N/A * @return N/A
*/ */
static t_void woal_process_event_tx_status(moal_private *priv, static t_void woal_process_event_tx_status(moal_private *priv,
tx_mgmt_status_event *tx_status) tx_mgmt_status_event *tx_status)
{ {
unsigned long flag; unsigned long flag;
#if defined(STA_CFG80211) || defined(UAP_CFG80211) #if defined(STA_CFG80211) || defined(UAP_CFG80211)

View file

@ -4,7 +4,7 @@
* functions defined in moal module * functions defined in moal module
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -315,6 +315,14 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy,
struct cfg80211_disassoc_request *req); struct cfg80211_disassoc_request *req);
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static int woal_cfg80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev,
u8 tsid, const u8 *peer, u8 user_prio,
u16 admitted_time);
static int woal_cfg80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
u8 tsid, const u8 *peer);
#endif /* KERNEL_VERSION(3, 8, 0) */
/** cfg80211 operations */ /** cfg80211 operations */
static struct cfg80211_ops woal_cfg80211_ops = { static struct cfg80211_ops woal_cfg80211_ops = {
.change_virtual_intf = woal_cfg80211_change_virtual_intf, .change_virtual_intf = woal_cfg80211_change_virtual_intf,
@ -452,6 +460,11 @@ static struct cfg80211_ops woal_cfg80211_ops = {
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
.testmode_cmd = woal_testmode_cmd, .testmode_cmd = woal_testmode_cmd,
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
.add_tx_ts = woal_cfg80211_add_tx_ts,
.del_tx_ts = woal_cfg80211_del_tx_ts,
#endif /* KERNEL_VERSION(3, 8, 0) */
}; };
/** Region code mapping */ /** Region code mapping */
@ -2602,6 +2615,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
{ {
struct cfg80211_bss *bss = NULL; struct cfg80211_bss *bss = NULL;
unsigned long flags; unsigned long flags;
t_u8 qos_cfg = 0;
int uapsd_queues = -1;
u8 *assoc_req_buf = NULL; u8 *assoc_req_buf = NULL;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
struct cfg80211_rx_assoc_resp_data resp = { struct cfg80211_rx_assoc_resp_data resp = {
@ -2664,6 +2679,22 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
assoc_req_buf = assoc_req_buf =
assoc_info assoc_info
->assoc_req_buf; ->assoc_req_buf;
if (!woal_priv_qos_cfg(priv,
MLAN_ACT_GET,
&qos_cfg) &&
qos_cfg != 0) {
int ac;
uapsd_queues = 0;
for (ac = WMM_AC_BK;
ac <= WMM_AC_VO; ac++) {
if (qos_cfg &
MBIT(WMM_AC_VO -
ac))
uapsd_queues |=
MBIT(ac);
}
}
#if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_14) #if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_14)
resp.links[0].bss = bss; resp.links[0].bss = bss;
resp.buf = assoc_info->assoc_resp_buf; resp.buf = assoc_info->assoc_resp_buf;
@ -2671,6 +2702,7 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
resp.req_ies = assoc_req_buf; resp.req_ies = assoc_req_buf;
resp.req_ies_len = resp.req_ies_len =
assoc_info->assoc_req_len; assoc_info->assoc_req_len;
resp.uapsd_queues = uapsd_queues;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
wiphy_lock(priv->wdev->wiphy); wiphy_lock(priv->wdev->wiphy);
cfg80211_rx_assoc_resp(priv->netdev, cfg80211_rx_assoc_resp(priv->netdev,
@ -2688,8 +2720,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
cfg80211_rx_assoc_resp( cfg80211_rx_assoc_resp(
priv->netdev, bss, priv->netdev, bss,
assoc_info->assoc_resp_buf, assoc_info->assoc_resp_buf,
assoc_info->assoc_resp_len, -1, assoc_info->assoc_resp_len,
assoc_req_buf, uapsd_queues, assoc_req_buf,
assoc_info->assoc_req_len); assoc_info->assoc_req_len);
mutex_unlock(&priv->wdev->mtx); mutex_unlock(&priv->wdev->mtx);
#else #else
@ -2698,7 +2730,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv,
cfg80211_rx_assoc_resp( cfg80211_rx_assoc_resp(
priv->netdev, bss, priv->netdev, bss,
assoc_info->assoc_resp_buf, assoc_info->assoc_resp_buf,
assoc_info->assoc_resp_len, -1); assoc_info->assoc_resp_len,
uapsd_queues);
mutex_unlock(&priv->wdev->mtx); mutex_unlock(&priv->wdev->mtx);
#else #else
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
@ -2874,7 +2907,7 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
goto done; goto done;
} }
if (!ssid_bssid->ssid.ssid_len || ssid_bssid->ssid.ssid[0] < 0x20) { if (!ssid_bssid->ssid.ssid_len) {
PRINTM(MERROR, "Invalid SSID - aborting\n"); PRINTM(MERROR, "Invalid SSID - aborting\n");
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
@ -3597,6 +3630,7 @@ static mlan_status woal_cfg80211_dump_station_info(moal_private *priv,
MBIT(NL80211_STA_INFO_RX_PACKETS) | MBIT(NL80211_STA_INFO_RX_PACKETS) |
MBIT(NL80211_STA_INFO_TX_PACKETS) | MBIT(NL80211_STA_INFO_TX_PACKETS) |
MBIT(NL80211_STA_INFO_SIGNAL) | MBIT(NL80211_STA_INFO_SIGNAL) |
MBIT(NL80211_STA_INFO_SIGNAL_AVG) |
MBIT(NL80211_STA_INFO_TX_BITRATE) | MBIT(NL80211_STA_INFO_TX_BITRATE) |
MBIT(NL80211_STA_INFO_RX_BITRATE); MBIT(NL80211_STA_INFO_RX_BITRATE);
#else #else
@ -3635,7 +3669,10 @@ static mlan_status woal_cfg80211_dump_station_info(moal_private *priv,
sinfo->tx_bytes = priv->stats.tx_bytes; sinfo->tx_bytes = priv->stats.tx_bytes;
sinfo->rx_packets = priv->stats.rx_packets; sinfo->rx_packets = priv->stats.rx_packets;
sinfo->tx_packets = priv->stats.tx_packets; sinfo->tx_packets = priv->stats.tx_packets;
sinfo->signal = signal.bcn_rssi_avg; sinfo->signal = signal.bcn_rssi_last;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
sinfo->signal_avg = signal.bcn_rssi_avg;
#endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
sinfo->tx_failed = stats.failed; sinfo->tx_failed = stats.failed;
#endif #endif
@ -3792,6 +3829,7 @@ create_custom_regdomain(moal_private *priv,
int idx, freq, prev_freq = 0; int idx, freq, prev_freq = 0;
t_u8 chan; t_u8 chan;
t_u16 num_chan = 0; t_u16 num_chan = 0;
t_u16 pwr, prev_pwr = 0;
t_u32 bw, prev_bw = 0; t_u32 bw, prev_bw = 0;
t_u16 chflags, prev_chflags = 0, valid_rules = 0; t_u16 chflags, prev_chflags = 0, valid_rules = 0;
struct ieee80211_regdomain *regd = NULL; struct ieee80211_regdomain *regd = NULL;
@ -3843,11 +3881,25 @@ create_custom_regdomain(moal_private *priv,
bw = MHZ_TO_KHZ(20); bw = MHZ_TO_KHZ(20);
} }
pwr = custom_reg->cfp_tbl[idx].max_tx_power;
if (idx == 0 || prev_chflags != chflags || prev_bw != bw || if (idx == 0 || prev_chflags != chflags || prev_bw != bw ||
freq - prev_freq > 20) { freq - prev_freq > 20) {
valid_rules++; valid_rules++;
new_rule = true; new_rule = true;
} }
if (!new_rule && pwr != prev_pwr) {
if (band == IEEE80211_BAND_2GHZ &&
!(chflags & NXP_CHANNEL_NOHT40)) {
/* skip adding new pwr rule for 40 MHz 2G
* overlapping bonded channels, as max tx
* power value may differ
*/
} else {
valid_rules++;
new_rule = true;
}
}
rule = &regd->reg_rules[valid_rules - 1]; rule = &regd->reg_rules[valid_rules - 1];
@ -3861,7 +3913,9 @@ create_custom_regdomain(moal_private *priv,
continue; continue;
rule->freq_range.start_freq_khz = MHZ_TO_KHZ(freq - 10); rule->freq_range.start_freq_khz = MHZ_TO_KHZ(freq - 10);
rule->power_rule.max_eirp = DBM_TO_MBM(19); rule->power_rule.max_eirp = DBM_TO_MBM(pwr);
prev_pwr = pwr;
rule->flags = 0; rule->flags = 0;
if (chflags & NXP_CHANNEL_PASSIVE) if (chflags & NXP_CHANNEL_PASSIVE)
@ -6434,6 +6488,10 @@ int woal_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev,
int index = 0; int index = 0;
int j = 0; int j = 0;
struct cfg80211_ssid *match_ssid = NULL; struct cfg80211_ssid *match_ssid = NULL;
#ifdef WIFI_DIRECT_SUPPORT
mlan_scan_cfg scan_cfg;
#endif
ENTER(); ENTER();
#ifdef UAP_CFG80211 #ifdef UAP_CFG80211
@ -6591,10 +6649,21 @@ int woal_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev,
priv->scan_cfg.action = BG_SCAN_ACT_SET; priv->scan_cfg.action = BG_SCAN_ACT_SET;
priv->scan_cfg.enable = MTRUE; priv->scan_cfg.enable = MTRUE;
#ifdef WIFI_DIRECT_SUPPORT #ifdef WIFI_DIRECT_SUPPORT
if (priv->phandle->miracast_mode) memset(&scan_cfg, 0, sizeof(mlan_scan_cfg));
if (MLAN_STATUS_SUCCESS != woal_get_scan_config(priv, &scan_cfg)) {
PRINTM(MERROR, "Fail to get scan request IE\n");
}
if (priv->phandle->miracast_mode) {
priv->scan_cfg.scan_chan_gap = priv->phandle->scan_chan_gap; priv->scan_cfg.scan_chan_gap = priv->phandle->scan_chan_gap;
else } else {
priv->scan_cfg.scan_chan_gap = 0; if (scan_cfg.scan_chan_gap)
priv->scan_cfg.scan_chan_gap = scan_cfg.scan_chan_gap;
else if (woal_is_any_interface_active(priv->phandle))
priv->scan_cfg.scan_chan_gap =
priv->phandle->scan_chan_gap;
else
priv->scan_cfg.scan_chan_gap = 0;
}
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
@ -6683,7 +6752,7 @@ int woal_cfg80211_resume(struct wiphy *wiphy)
PRINTM(MERROR, "woal_cfg80211_resume: priv is NULL\n"); PRINTM(MERROR, "woal_cfg80211_resume: priv is NULL\n");
goto done; goto done;
} }
handle->cfg80211_suspend = MFALSE;
for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
if (handle->priv[i] && if (handle->priv[i] &&
(GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)) { (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)) {
@ -6791,7 +6860,6 @@ int woal_cfg80211_resume(struct wiphy *wiphy)
#endif #endif
done: done:
handle->cfg80211_suspend = MFALSE;
woal_queue_rx_task(handle); woal_queue_rx_task(handle);
PRINTM(MCMND, "<--- Leave woal_cfg80211_resume --->\n"); PRINTM(MCMND, "<--- Leave woal_cfg80211_resume --->\n");
return 0; return 0;
@ -10332,6 +10400,10 @@ mlan_status woal_register_cfg80211(moal_private *priv)
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
#endif #endif
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
wiphy->features |= NL80211_FEATURE_SUPPORTS_WMM_ADMISSION;
#endif /* KERNEL_VERSION(3, 19, 0) */
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA);
wiphy_ext_feature_set(wiphy, wiphy_ext_feature_set(wiphy,
@ -10503,3 +10575,140 @@ err_wiphy:
LEAVE(); LEAVE();
return ret; return ret;
} }
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
/**
* @brief Add WMM tspec TS
* @param wiphy A pointer to wiphy structure
* @param dev A pointer to net_device structure
* @param tsid A u8 tsid value for the TS
* @param peer A pointer to peer MAC address
* @param user_prio A u8 user priority value
* @param admitted_time A u16 admitted time for the TS
*
* @return 0 -- success, otherwise fail
*/
static int woal_cfg80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev,
u8 tsid, const u8 *peer, u8 user_prio,
u16 admitted_time)
{
mlan_ioctl_req *req = NULL;
mlan_ds_tx_addts_cfg *ts_cfg = NULL;
mlan_ds_wmm_cfg *pwmm = NULL;
int ret = 0;
mlan_status status = MLAN_STATUS_FAILURE;
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
ENTER();
if (peer == NULL || tsid >= MAX_NUM_TID || user_prio >= MAX_NUM_TID) {
PRINTM(MERROR, "ADDTS: Invalid parameters\n");
ret = -EINVAL;
goto done;
}
if (memcmp(peer, priv->cfg_bssid, MLAN_MAC_ADDR_LENGTH)) {
PRINTM(MERROR, "ADDTS: Invalid peer Address\n");
ret = -EINVAL;
goto done;
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
pwmm = (mlan_ds_wmm_cfg *)req->pbuf;
pwmm->sub_command = MLAN_OID_WMM_CFG_HOST_ADDTS;
ts_cfg = &pwmm->param.host_addts;
ts_cfg->tsid = tsid;
ts_cfg->user_prio = user_prio;
ts_cfg->admitted_time = admitted_time;
moal_memcpy_ext(priv->phandle, ts_cfg->peer, peer, sizeof(ts_cfg->peer),
MLAN_MAC_ADDR_LENGTH);
req->action = MLAN_ACT_SET;
req->req_id = MLAN_IOCTL_WMM_CFG;
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
PRINTM(MMSG,
"WMM AC - ADDTS tsid=%u peer=" MACSTR
" up=%u admitted_time=%u\n",
tsid, MAC2STR(peer), user_prio, admitted_time);
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
/**
* @brief Set del tx tspec parameters
* @param wiphy A pointer to wiphy structure
* @param dev A pointer to net_device structure
* @param params A pointer to ieee80211_txq_params structure
*
* @return 0 -- success, otherwise fail
*/
static int woal_cfg80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
u8 tsid, const u8 *peer)
{
mlan_ioctl_req *req = NULL;
mlan_ds_wmm_cfg *pwmm = NULL;
mlan_ds_tx_delts_cfg *ts_cfg = NULL;
int ret = 0;
mlan_status status = MLAN_STATUS_FAILURE;
moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
ENTER();
if (peer == NULL || tsid >= MAX_NUM_TID) {
PRINTM(MERROR, "DELTS: Invalid parameters \n");
ret = -EINVAL;
goto done;
}
if (memcmp(peer, priv->cfg_bssid, MLAN_MAC_ADDR_LENGTH)) {
PRINTM(MERROR, "DELTS: Invalid peer Address\n");
ret = -EINVAL;
goto done;
}
req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
if (req == NULL) {
ret = -ENOMEM;
goto done;
}
pwmm = (mlan_ds_wmm_cfg *)req->pbuf;
pwmm->sub_command = MLAN_OID_WMM_CFG_HOST_DELTS;
ts_cfg = &pwmm->param.host_delts;
ts_cfg->tsid = tsid;
moal_memcpy_ext(priv->phandle, ts_cfg->peer, peer, sizeof(ts_cfg->peer),
MLAN_MAC_ADDR_LENGTH);
req->action = MLAN_ACT_SET;
req->req_id = MLAN_IOCTL_WMM_CFG;
status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
if (status != MLAN_STATUS_SUCCESS) {
ret = -EFAULT;
goto done;
}
PRINTM(MMSG, "WMM AC - DELTS tsid=%u peer=" MACSTR "\n", tsid,
MAC2STR(peer));
done:
if (status != MLAN_STATUS_PENDING)
kfree(req);
LEAVE();
return ret;
}
#endif /* KERNEL_VERSION(3, 8, 0) */

View file

@ -3,7 +3,7 @@
* @brief This file contains uap driver specific defines etc. * @brief This file contains uap driver specific defines etc.
* *
* *
* Copyright 2008-2022 NXP * Copyright 2008-2022, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -1969,6 +1969,10 @@ moal_private *woal_alloc_virt_interface(moal_handle *handle, t_u8 bss_index,
spin_lock_init(&priv->dhcp_discover_lock); spin_lock_init(&priv->dhcp_discover_lock);
#endif #endif
#ifdef STA_CFG80211
INIT_LIST_HEAD(&priv->ipv6_addrses);
spin_lock_init(&priv->ipv6addr_lock);
#endif
spin_lock_init(&priv->connect_lock); spin_lock_init(&priv->connect_lock);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
@ -3993,21 +3997,25 @@ int woal_cfg80211_start_radar_detection(struct wiphy *wiphy,
snprintf(event_buf, sizeof(event_buf) - 1, "%s %d", CUS_EVT_CAC_START, snprintf(event_buf, sizeof(event_buf) - 1, "%s %d", CUS_EVT_CAC_START,
chandef->chan->hw_value); chandef->chan->hw_value);
woal_broadcast_event(priv, event_buf, strlen(event_buf)); woal_broadcast_event(priv, event_buf, strlen(event_buf));
if (MLAN_STATUS_SUCCESS == if (priv->phandle->card_info->drcs) {
woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, MLAN_ACT_GET)) { if (MLAN_STATUS_SUCCESS == woal_mc_policy_cfg(priv, &enable,
if (enable) { MOAL_IOCTL_WAIT,
if (MLAN_STATUS_SUCCESS == MLAN_ACT_GET)) {
woal_get_active_intf_channel(priv, &channel)) { if (enable) {
if (channel.channel != if (MLAN_STATUS_SUCCESS ==
chandef->chan->hw_value) { woal_get_active_intf_channel(priv,
PRINTM(MERROR, &channel)) {
"DFS channel is not allowed when another connection exists on different channel\n"); if (channel.channel !=
PRINTM(MERROR, chandef->chan->hw_value) {
"Another connection's channel=%d, dfs channel=%d\n", PRINTM(MERROR,
channel.channel, "DFS channel is not allowed when another connection exists on different channel\n");
chandef->chan->hw_value); PRINTM(MERROR,
ret = -EINVAL; "Another connection's channel=%d, dfs channel=%d\n",
goto done; channel.channel,
chandef->chan->hw_value);
ret = -EINVAL;
goto done;
}
} }
} }
} }

View file

@ -4,7 +4,7 @@
* driver. * driver.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991

View file

@ -4,7 +4,7 @@
* driver. * driver.
* *
* *
* Copyright 2008-2021 NXP * Copyright 2008-2021, 2024 NXP
* *
* This software file (the File) is distributed by NXP * This software file (the File) is distributed by NXP
* under the terms of the GNU General Public License Version 2, June 1991 * under the terms of the GNU General Public License Version 2, June 1991