diff --git a/Makefile b/Makefile index f4e155b..d8d791d 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ APPDIR= $(shell if test -d "mapp"; then echo mapp; fi) ############################################################################# ccflags-y += -I$(KERNELDIR)/include - ccflags-y += -DMLAN_RELEASE_VERSION='"437.p21"' + ccflags-y += -DMLAN_RELEASE_VERSION='"437.p24"' ccflags-y += -DFPNUM='"92"' diff --git a/README b/README index 0b3b755..bafe754 100644 --- a/README +++ b/README @@ -11,7 +11,7 @@ Goto source code directory. make [clean] build 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 diff --git a/mlan/mlan_11ax.c b/mlan/mlan_11ax.c index fe60aef..c6fd387 100644 --- a/mlan/mlan_11ax.c +++ b/mlan/mlan_11ax.c @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_11d.c b/mlan/mlan_11d.c index 9290e87..b1bed8d 100644 --- a/mlan/mlan_11d.c +++ b/mlan/mlan_11d.c @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_11n.c b/mlan/mlan_11n.c index 4977e2f..8ea305f 100644 --- a/mlan/mlan_11n.c +++ b/mlan/mlan_11n.c @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_11n_aggr.c b/mlan/mlan_11n_aggr.c index 5b383dc..e1925d4 100644 --- a/mlan/mlan_11n_aggr.c +++ b/mlan/mlan_11n_aggr.c @@ -3,7 +3,7 @@ * @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 * 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(); 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 @@ -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_type = priv->bss_type; /* 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; if (mbuf->flags & MLAN_BUF_FLAG_TDLS) 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; 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; 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 */ 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, 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(); return (pmbuf->data_len - data_len); @@ -302,8 +304,8 @@ static INLINE void wlan_11n_update_pktlen_amsdu_txpd(mlan_private *priv, ENTER(); ptx_pd = (TxPD *)mbuf->pbuf; - ptx_pd->tx_pkt_length = - (t_u16)wlan_cpu_to_le16(mbuf->data_len - sizeof(TxPD)); + ptx_pd->tx_pkt_length = (t_u16)wlan_cpu_to_le16( + mbuf->data_len - Tx_PD_SIZEOF(priv->adapter)); ptx_pd->pkt_delay_2ms = wlan_wmm_compute_driver_packet_delay(priv, mbuf); @@ -643,8 +645,9 @@ done: * * @return Final packet size or MLAN_STATUS_FAILURE */ -int wlan_send_amsdu_subframe_list(mlan_private *priv, raListTbl *pra_list, - int headroom, int ptrindex) +static int wlan_send_amsdu_subframe_list(mlan_private *priv, + raListTbl *pra_list, int headroom, + int ptrindex) { int pkt_size = 0; 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, MNULL, MNULL); /* 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->pmoal_handle, pmbuf_src, 3); pra_list->total_pkts--; @@ -849,7 +853,7 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list, } /* Form AMSDU */ wlan_11n_form_amsdu_txpd(priv, pmbuf_aggr); - pkt_size = sizeof(TxPD); + pkt_size = Tx_PD_SIZEOF(pmadapter); #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) 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, MNULL, MNULL); /* 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->pmoal_handle, pmbuf_src, 3); 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->pbuf = data - headroom; 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 */ if (pmadapter->tp_state_on) { pmadapter->callbacks.moal_tp_accounting(pmadapter->pmoal_handle, diff --git a/mlan/mlan_cfp.c b/mlan/mlan_cfp.c index 239cd6c..0fdb12b 100644 --- a/mlan/mlan_cfp.c +++ b/mlan/mlan_cfp.c @@ -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 * @@ -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) goto out; + + wlan_set_otp_cfp_max_tx_pwr(pmadapter, MFALSE); + /* Set remaining flags for BG */ rows = pmadapter->tx_power_table_bg_rows; cols = pmadapter->tx_power_table_bg_cols; diff --git a/mlan/mlan_cmdevt.c b/mlan/mlan_cmdevt.c index 01b860f..cd6c7bd 100644 --- a/mlan/mlan_cmdevt.c +++ b/mlan/mlan_cmdevt.c @@ -5122,6 +5122,15 @@ mlan_status wlan_adapter_init_cmd(pmlan_adapter pmadapter) &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 if (pmpriv_sta) { 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); 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); - 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_type = pmpriv->bss_type; plocal_tx_pd->tx_pkt_length = (t_u16)data_len; 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; 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); - cmd_size += sizeof(TxPD) + data_len; + cmd_size += Tx_PD_SIZEOF(pmpriv->adapter) + data_len; cmd->size = wlan_cpu_to_le16(cmd_size); LEAVE(); diff --git a/mlan/mlan_decl.h b/mlan/mlan_decl.h index 3a2fc83..ff75c17 100644 --- a/mlan/mlan_decl.h +++ b/mlan/mlan_decl.h @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 @@ -2762,6 +2762,8 @@ typedef struct _mlan_device { t_u32 antcfg; /** dmcs */ t_u8 dmcs; + t_u32 reject_addba_req; + } mlan_device, *pmlan_device; /** MLAN API function prototype */ diff --git a/mlan/mlan_event_ids.h b/mlan/mlan_event_ids.h index 14d5184..074e787 100644 --- a/mlan/mlan_event_ids.h +++ b/mlan/mlan_event_ids.h @@ -3,7 +3,7 @@ * @brief This file contains FW event ID definitions. * * - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_fw.h b/mlan/mlan_fw.h index 97b5b87..db1cbc2 100644 --- a/mlan/mlan_fw.h +++ b/mlan/mlan_fw.h @@ -5,7 +5,7 @@ * in MLAN module. * * - * Copyright 2008-2023 NXP + * Copyright 2008-2024 NXP * * This software file (the File) is distributed by NXP * 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 /** Buffer size for ethernet Tx packets */ -#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \ - (MV_ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN) +#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE(_adapter) \ + (MV_ETH_FRAME_LEN + Tx_PD_SIZEOF(_adapter) + EXTRA_LEN) /** Buffer size for ethernet Rx packets */ #define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \ @@ -1215,6 +1215,8 @@ enum host_cmd_id { #define FW_CAPINFO_EXT_SEC_RG_POWER MBIT(19) /** FW cap info bit 20: RX_SW_INT */ #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 */ #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) #define IS_FW_SUPPORT_RX_SW_INT(_adapter) \ (_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 */ 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 */ #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 */ #define HostCmd_ACT_GEN_GET 0x0000 /** General purpose action : Set */ @@ -4879,6 +4892,32 @@ typedef MLAN_PACK_START struct { t_u8 wmm_param_tlv[sizeof(IEEEtypes_WmmParameter_t) + 2]; } 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 */ @@ -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*/ typedef MLAN_PACK_START struct { MrvlIEtypesHeader_t Header; - t_u8 ipv6_addr[16]; + /** ipv6 address buffer */ + t_u8 ipv6_addrs[]; } MLAN_PACK_END MrvlIETypes_IPv6AddrParamSet_t; 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; /** 0x00: disable IPv6 RA Offload; 0x01: enable IPv6 RA offload */ t_u8 enable; + /** Number of IPv6 address configured in FW */ + t_u8 ipv6_addr_count; MrvlIETypes_IPv6AddrParamSet_t ipv6_addr_param; } 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_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; } MLAN_PACK_END HostCmd_DS_COMMAND, *pHostCmd_DS_COMMAND; diff --git a/mlan/mlan_hostcmd_ids.h b/mlan/mlan_hostcmd_ids.h index 79d137c..e7c7f39 100644 --- a/mlan/mlan_hostcmd_ids.h +++ b/mlan/mlan_hostcmd_ids.h @@ -3,7 +3,7 @@ * @brief This file contains host command ID definitions. * * - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * This software file (the File) is distributed by NXP * 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 */ 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 */ ENUM_ELEMENT_LAST(__HostCmd_CMD_Last) diff --git a/mlan/mlan_ieee.h b/mlan/mlan_ieee.h index 280f6bc..9fad37b 100644 --- a/mlan/mlan_ieee.h +++ b/mlan/mlan_ieee.h @@ -4,7 +4,7 @@ * definitions used in MLAN and MOAL module. * * - * Copyright 2008-2023 NXP + * Copyright 2008-2024 NXP * * This software file (the File) is distributed by NXP * 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; +/** 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 */ typedef MLAN_PACK_START struct { IEEEtypes_ActionCategory_e category; diff --git a/mlan/mlan_init.c b/mlan/mlan_init.c index c94ae9b..3787b1c 100644 --- a/mlan/mlan_init.c +++ b/mlan/mlan_init.c @@ -4,7 +4,7 @@ * and HW. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_ioctl.h b/mlan/mlan_ioctl.h index 6e8c67b..5a02207 100644 --- a/mlan/mlan_ioctl.h +++ b/mlan/mlan_ioctl.h @@ -3,7 +3,7 @@ * @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 * 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_STATUS = 0x000A0007, MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008, + MLAN_OID_WMM_CFG_HOST_ADDTS = 0x000A000A, + MLAN_OID_WMM_CFG_HOST_DELTS = 0x000A000B, /* WPS Configuration Group */ MLAN_IOCTL_WPS_CFG = 0x000B0000, @@ -2986,6 +2988,8 @@ typedef struct _mlan_data_rate { typedef struct _mlan_ds_rate { /** Sub-command */ t_u32 sub_command; + /** Only set auto tx fix rate */ + t_u16 auto_null_fixrate_enable; /** Rate configuration parameter */ union { /** Rate configuration for MLAN_OID_RATE_CFG */ @@ -3609,6 +3613,26 @@ typedef struct _mlan_ds_wmm_queue_config { t_u8 reserved[10]; } 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 */ typedef struct _mlan_ds_wmm_cfg { /** Sub-command */ @@ -3623,6 +3647,10 @@ typedef struct _mlan_ds_wmm_cfg { mlan_ds_wmm_addts addts; /** WMM delete TS for MLAN_OID_WMM_CFG_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 */ mlan_ds_wmm_queue_config q_cfg; /** 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 */ t_u8 col; /**ru tx data */ - t_u8 rutxSubPwr[89]; + t_s8 rutxSubPwr[89]; } mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd; /** 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 { /** 0: disable; 1: 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; /* MEF configuration disable */ diff --git a/mlan/mlan_join.h b/mlan/mlan_join.h index f7bafb9..3a11e0a 100644 --- a/mlan/mlan_join.h +++ b/mlan/mlan_join.h @@ -8,7 +8,7 @@ * both adhoc and infrastructure networks * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_main.h b/mlan/mlan_main.h index a3fa318..8144958 100644 --- a/mlan/mlan_main.h +++ b/mlan/mlan_main.h @@ -5,7 +5,7 @@ * in MLAN module. * * - * Copyright 2008-2023 NXP + * Copyright 2008-2024 NXP * * This software file (the File) is distributed by NXP * 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; /** dmcs*/ t_u8 dmcs; + t_u32 reject_addba_req; } mlan_init_para, *pmlan_init_para; #ifdef SDIO diff --git a/mlan/mlan_misc.c b/mlan/mlan_misc.c index 0325d85..f3723af 100644 --- a/mlan/mlan_misc.c +++ b/mlan/mlan_misc.c @@ -4809,9 +4809,24 @@ static mlan_status wlan_rate_ioctl_set_rate_index(pmlan_adapter pmadapter, pmpriv->is_data_rate_auto, pmpriv->data_rate); /* Send request to firmware */ - ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, - HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req, - (t_void *)bitmap_rates); + if (ds_rate->auto_null_fixrate_enable == 1) { + ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, + 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) ret = MLAN_STATUS_PENDING; diff --git a/mlan/mlan_pcie.c b/mlan/mlan_pcie.c index 983808b..6fcac14 100644 --- a/mlan/mlan_pcie.c +++ b/mlan/mlan_pcie.c @@ -3,7 +3,7 @@ * @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 * 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; mlan_buffer *pmbuf = MNULL; 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; t_u32 reg_rxbd_rdptr = pmadapter->pcard_pcie->reg->reg_rxbd_rdptr; #if defined(PCIE8997) || defined(PCIE8897) @@ -2902,6 +2902,14 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) goto done; } 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 == pcb->moal_unmap_memory(pmadapter->pmoal_handle, pmbuf->pbuf + pmbuf->data_offset, @@ -2972,6 +2980,13 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) 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 */ pmbuf = wlan_alloc_mlan_buffer(pmadapter, MLAN_RX_DATA_BUF_SIZE, @@ -2983,10 +2998,6 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) ret = MLAN_STATUS_FAILURE; goto done; } - } else { - /* Queue the mlan_buffer again */ - PRINTM(MERROR, "PCIE: Drop invalid packet, length=%d", - rx_len); } if (MLAN_STATUS_FAILURE == @@ -5191,6 +5202,9 @@ static mlan_status wlan_pcie_interrupt_ext(t_u16 msg_id, ENTER(); ret = wlan_pcie_interrupt(msg_id, pmadapter); 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); } LEAVE(); diff --git a/mlan/mlan_scan.c b/mlan/mlan_scan.c index 87dc754..34ca4a4 100644 --- a/mlan/mlan_scan.c +++ b/mlan/mlan_scan.c @@ -6,7 +6,7 @@ * for sending scan commands to the firmware. * * - * Copyright 2008-2023 NXP + * Copyright 2008-2024 NXP * * This software file (the File) is distributed by NXP * 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 = wlan_cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP); pscan_gap_tlv->header.len = sizeof(pscan_gap_tlv->gap); - pscan_gap_tlv->gap = - wlan_cpu_to_le16((t_u16)pmadapter->scan_chan_gap); + pscan_gap_tlv->gap = wlan_cpu_to_le16((t_u16)scan_chan_gap); /** indicate FW, gap is optional */ pscan_gap_tlv->gap |= GAP_FLAG_OPTIONAL; tlv += sizeof(pscan_gap_tlv->header) + diff --git a/mlan/mlan_shim.c b/mlan/mlan_shim.c index 9adea70..5a657a2 100644 --- a/mlan/mlan_shim.c +++ b/mlan/mlan_shim.c @@ -3,7 +3,7 @@ * @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 * 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.mcs32 = pmdevice->mcs32; pmadapter->init_para.antcfg = pmdevice->antcfg; + pmadapter->init_para.reject_addba_req = pmdevice->reject_addba_req; pmadapter->init_para.dmcs = pmdevice->dmcs; #ifdef SDIO diff --git a/mlan/mlan_sta_cmd.c b/mlan/mlan_sta_cmd.c index 8d65019..99a938a 100644 --- a/mlan/mlan_sta_cmd.c +++ b/mlan/mlan_sta_cmd.c @@ -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 *)pdata_buf; 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(); @@ -2980,13 +2982,16 @@ static mlan_status wlan_cmd_ipv6_ra_offload(mlan_private *pmpriv, if (cmd_action == HostCmd_ACT_GEN_SET) { ipv6_ra_cfg->enable = ipv6_ra_offload->enable; ie->type = wlan_cpu_to_le16(TLV_TYPE_IPV6_RA_OFFLOAD); - ie->len = wlan_cpu_to_le16(16); - memcpy_ext(pmpriv->adapter, - ipv6_ra_cfg->ipv6_addr_param.ipv6_addr, - ipv6_ra_offload->ipv6_addr, 16, - sizeof(ipv6_ra_cfg->ipv6_addr_param.ipv6_addr)); + ipv6_ra_cfg->ipv6_addr_count = + ipv6_ra_offload->ipv6_addrs_count; + memcpy_ext(pmpriv->adapter, pipv6addrs, psrcipv6addr, + (ipv6_ra_offload->ipv6_addrs_count * IPADDR_LEN), + (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( - 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) pcmd->size = wlan_cpu_to_le16(S_DS_GEN + 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: ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf); 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: ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf); break; diff --git a/mlan/mlan_sta_cmdresp.c b/mlan/mlan_sta_cmdresp.c index ec91dc1..38047e8 100644 --- a/mlan/mlan_sta_cmdresp.c +++ b/mlan/mlan_sta_cmdresp.c @@ -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_offload; ipv6_ra->enable = ipv6_ra_resp->enable; - memcpy_ext(pmpriv->adapter, ipv6_ra->ipv6_addr, - ipv6_ra_resp->ipv6_addr_param.ipv6_addr, 16, - sizeof(ipv6_ra->ipv6_addr)); + ipv6_ra->ipv6_addrs_count = ipv6_ra_resp->ipv6_addr_count; + memcpy_ext(pmpriv->adapter, ipv6_ra->ipv6_addrs, + ipv6_ra_resp->ipv6_addr_param.ipv6_addrs, + (ipv6_ra->ipv6_addrs_count * IPADDR_LEN), + (ipv6_ra->ipv6_addrs_count * IPADDR_LEN)); } 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: ret = wlan_ret_wmm_delts_req(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_WMM_HOST_ADDTS_REQ: + case HostCmd_CMD_WMM_HOST_DELTS_REQ: + break; case HostCmd_CMD_WMM_QUEUE_CONFIG: ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf); break; diff --git a/mlan/mlan_sta_event.c b/mlan/mlan_sta_event.c index 755909e..e5fa3ea 100644 --- a/mlan/mlan_sta_event.c +++ b/mlan/mlan_sta_event.c @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_sta_ioctl.c b/mlan/mlan_sta_ioctl.c index e0183ce..b75055e 100644 --- a/mlan/mlan_sta_ioctl.c +++ b/mlan/mlan_sta_ioctl.c @@ -5312,7 +5312,7 @@ mlan_status wlan_scan_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req) LEAVE(); return MLAN_STATUS_FAILURE; } - if (pmadapter->remain_on_channel + if (pmadapter->remain_on_channel && pioctl_req->action == MLAN_ACT_SET #ifdef WIFI_DIRECT_SUPPORT && (pmpriv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT) #endif diff --git a/mlan/mlan_sta_rx.c b/mlan/mlan_sta_rx.c index e12a4fc..3f4c147 100644 --- a/mlan/mlan_sta_rx.c +++ b/mlan/mlan_sta_rx.c @@ -4,7 +4,7 @@ * module. * * - * Copyright 2008-2022 NXP + * Copyright 2008-2022, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_sta_tx.c b/mlan/mlan_sta_tx.c index 1ad0c21..40b5f9b 100644 --- a/mlan/mlan_sta_tx.c +++ b/mlan/mlan_sta_tx.c @@ -4,7 +4,7 @@ * transmission in MLAN module. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * 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 < - (sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { + (Tx_PD_SIZEOF(pmadapter) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { PRINTM(MERROR, "not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n", 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; goto done; } /* 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; head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1))); 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 */ plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv); 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; TxPD *ptx_pd; -/* sizeof(TxPD) + Interface specific header */ +/* Tx_PD_SIZEOF(pmadapter) + Interface specific header */ #define NULL_PACKET_HDR 256 t_u32 data_len = NULL_PACKET_HDR; 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->flags |= MLAN_BUF_FLAG_NULL_PKT; 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->tx_control = priv->pkt_tx_ctrl; ptx_pd->flags = flags; 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 */ ptx_pd->bss_num = GET_BSS_NUM(priv); 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_NETINTF(MDATA, priv); 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: LEAVE(); return ret; diff --git a/mlan/mlan_txrx.c b/mlan/mlan_txrx.c index fbb966f..f6f66ae 100644 --- a/mlan/mlan_txrx.c +++ b/mlan/mlan_txrx.c @@ -203,8 +203,8 @@ mlan_status wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf, if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) plocal_tx_pd = (TxPD *)(head_ptr + priv->intf_hr_len); #endif - dest_mac_first_octet = *(head_ptr + priv->intf_hr_len + sizeof(TxPD) + - DEST_MAC_OFFSET); + dest_mac_first_octet = *(head_ptr + priv->intf_hr_len + + Tx_PD_SIZEOF(pmadapter) + DEST_MAC_OFFSET); if (dest_mac_first_octet & 0x01) wlan_drv_mcast_cycle_delay_calulation(pmadapter, pmbuf); @@ -223,7 +223,7 @@ done: case MLAN_STATUS_PRESOURCE: PRINTM(MINFO, "MLAN_STATUS_PRESOURCE is returned\n"); 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)); break; #endif @@ -246,12 +246,12 @@ done: break; case MLAN_STATUS_PENDING: 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)); break; case MLAN_STATUS_SUCCESS: 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)); wlan_write_data_complete(pmadapter, pmbuf, ret); break; diff --git a/mlan/mlan_uap_cmdevent.c b/mlan/mlan_uap_cmdevent.c index 242de00..0d7a89c 100644 --- a/mlan/mlan_uap_cmdevent.c +++ b/mlan/mlan_uap_cmdevent.c @@ -5690,6 +5690,8 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) wlan_delete_station_list(pmpriv); pmpriv->port_open = MFALSE; pmpriv->amsdu_disable = MFALSE; + pmpriv->rxpd_rate_info = 0; + pmpriv->rxpd_rate = 0; pmpriv->tx_pause = MFALSE; break; case EVENT_MICRO_AP_MIC_COUNTERMEASURES: diff --git a/mlan/mlan_uap_txrx.c b/mlan/mlan_uap_txrx.c index 8449630..e64488c 100644 --- a/mlan/mlan_uap_txrx.c +++ b/mlan/mlan_uap_txrx.c @@ -3,7 +3,7 @@ * @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 * 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_len -= sizeof(pkt_type) + sizeof(tx_control); } - if (pmbuf->data_offset < - (sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { + if (pmbuf->data_offset < (Tx_PD_SIZEOF(pmpriv->adapter) + + pmpriv->intf_hr_len + DMA_ALIGNMENT)) { PRINTM(MERROR, "not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n", 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", pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len); 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 = pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - - pmpriv->intf_hr_len; + head_ptr = pmbuf->pbuf + pmbuf->data_offset - + Tx_PD_SIZEOF(pmpriv->adapter) - pmpriv->intf_hr_len; head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1))); 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 */ 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_usec = pmbuf->in_ts_usec; newbuf->data_offset = - (sizeof(TxPD) + priv->intf_hr_len + - DMA_ALIGNMENT); + (Tx_PD_SIZEOF(pmadapter) + + priv->intf_hr_len + DMA_ALIGNMENT); util_scalar_increment( pmadapter->pmoal_handle, &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_usec = pmbuf->in_ts_usec; newbuf->data_offset = - (sizeof(TxPD) + priv->intf_hr_len + - DMA_ALIGNMENT); + (Tx_PD_SIZEOF(pmadapter) + + priv->intf_hr_len + DMA_ALIGNMENT); util_scalar_increment( pmadapter->pmoal_handle, &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_usec = pmbuf->in_ts_usec; newbuf->data_offset = - (sizeof(TxPD) + priv->intf_hr_len + - DMA_ALIGNMENT); + (Tx_PD_SIZEOF(pmadapter) + + priv->intf_hr_len + DMA_ALIGNMENT); util_scalar_increment( pmadapter->pmoal_handle, &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 = pmbuf->in_ts_usec; newbuf->data_offset = - (sizeof(TxPD) + + (Tx_PD_SIZEOF( + pmadapter) + priv->intf_hr_len + DMA_ALIGNMENT); util_scalar_increment( diff --git a/mlan/mlan_usb.c b/mlan/mlan_usb.c index ca8226c..0a25d94 100644 --- a/mlan/mlan_usb.c +++ b/mlan/mlan_usb.c @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlan/mlan_wmm.c b/mlan/mlan_wmm.c index 94ea090..06fc26b 100644 --- a/mlan/mlan_wmm.c +++ b/mlan/mlan_wmm.c @@ -3,7 +3,7 @@ * @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 * 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); tx_param.next_pkt_len = - ((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : + ((pmbuf_next) ? pmbuf_next->data_len + + Tx_PD_SIZEOF(pmadapter) : 0); 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->pmoal_handle, priv->wmm.ra_list_spinlock); tx_param.next_pkt_len = - ((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : + ((pmbuf_next) ? pmbuf_next->data_len + + Tx_PD_SIZEOF(pmadapter) : 0); 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: break; case MLAN_STATUS_SUCCESS: - DBG_HEXDUMP(MDAT_D, "Tx", - pmbuf->pbuf + pmbuf->data_offset, - MIN(pmbuf->data_len + sizeof(TxPD), - MAX_DATA_DUMP_LEN)); + DBG_HEXDUMP( + MDAT_D, "Tx", pmbuf->pbuf + pmbuf->data_offset, + MIN(pmbuf->data_len + Tx_PD_SIZEOF(pmadapter), + MAX_DATA_DUMP_LEN)); wlan_write_data_complete(pmadapter, pmbuf, ret); break; default: @@ -2877,6 +2879,69 @@ t_void wlan_restore_tdls_packets(pmlan_private priv, t_u8 *mac, 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 * @@ -3309,6 +3374,67 @@ static mlan_status wlan_wmm_ioctl_delts_req(pmlan_adapter pmadapter, 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 * @@ -3619,6 +3745,12 @@ mlan_status wlan_wmm_cfg_ioctl(pmlan_adapter pmadapter, case MLAN_OID_WMM_CFG_DELTS: status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req); 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: status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req); break; diff --git a/mlan/mlan_wmm.h b/mlan/mlan_wmm.h index a458948..6e9dd12 100644 --- a/mlan/mlan_wmm.h +++ b/mlan/mlan_wmm.h @@ -4,7 +4,7 @@ * of wmm functionalities * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * 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, HostCmd_DS_COMMAND *cmd, 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 diff --git a/mlinux/mlan_decl.h b/mlinux/mlan_decl.h index 3a2fc83..ff75c17 100644 --- a/mlinux/mlan_decl.h +++ b/mlinux/mlan_decl.h @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 @@ -2762,6 +2762,8 @@ typedef struct _mlan_device { t_u32 antcfg; /** dmcs */ t_u8 dmcs; + t_u32 reject_addba_req; + } mlan_device, *pmlan_device; /** MLAN API function prototype */ diff --git a/mlinux/mlan_ieee.h b/mlinux/mlan_ieee.h index 280f6bc..9fad37b 100644 --- a/mlinux/mlan_ieee.h +++ b/mlinux/mlan_ieee.h @@ -4,7 +4,7 @@ * definitions used in MLAN and MOAL module. * * - * Copyright 2008-2023 NXP + * Copyright 2008-2024 NXP * * This software file (the File) is distributed by NXP * 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; +/** 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 */ typedef MLAN_PACK_START struct { IEEEtypes_ActionCategory_e category; diff --git a/mlinux/mlan_ioctl.h b/mlinux/mlan_ioctl.h index 6e8c67b..5a02207 100644 --- a/mlinux/mlan_ioctl.h +++ b/mlinux/mlan_ioctl.h @@ -3,7 +3,7 @@ * @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 * 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_STATUS = 0x000A0007, MLAN_OID_WMM_CFG_TS_STATUS = 0x000A0008, + MLAN_OID_WMM_CFG_HOST_ADDTS = 0x000A000A, + MLAN_OID_WMM_CFG_HOST_DELTS = 0x000A000B, /* WPS Configuration Group */ MLAN_IOCTL_WPS_CFG = 0x000B0000, @@ -2986,6 +2988,8 @@ typedef struct _mlan_data_rate { typedef struct _mlan_ds_rate { /** Sub-command */ t_u32 sub_command; + /** Only set auto tx fix rate */ + t_u16 auto_null_fixrate_enable; /** Rate configuration parameter */ union { /** Rate configuration for MLAN_OID_RATE_CFG */ @@ -3609,6 +3613,26 @@ typedef struct _mlan_ds_wmm_queue_config { t_u8 reserved[10]; } 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 */ typedef struct _mlan_ds_wmm_cfg { /** Sub-command */ @@ -3623,6 +3647,10 @@ typedef struct _mlan_ds_wmm_cfg { mlan_ds_wmm_addts addts; /** WMM delete TS for MLAN_OID_WMM_CFG_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 */ mlan_ds_wmm_queue_config q_cfg; /** 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 */ t_u8 col; /**ru tx data */ - t_u8 rutxSubPwr[89]; + t_s8 rutxSubPwr[89]; } mlan_ds_11ax_rutxpwr_cmd, *pmlan_ds_11ax_rutxpwr_cmd; /** 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 { /** 0: disable; 1: 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; /* MEF configuration disable */ diff --git a/mlinux/moal_cfg80211.c b/mlinux/moal_cfg80211.c index 787d764..25e61ae 100644 --- a/mlinux/moal_cfg80211.c +++ b/mlinux/moal_cfg80211.c @@ -2889,6 +2889,34 @@ done: 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, 3, 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; #endif t_u16 fc, type, stype; +#if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) + t_u8 category, action; +#endif ENTER(); if (buf == NULL || len == 0) { @@ -3226,6 +3257,26 @@ int woal_cfg80211_mgmt_tx(struct wiphy *wiphy, *cookie = get_random_u32() | 1; #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); done: diff --git a/mlinux/moal_cfg80211_util.h b/mlinux/moal_cfg80211_util.h index 801e5fd..25b512e 100644 --- a/mlinux/moal_cfg80211_util.h +++ b/mlinux/moal_cfg80211_util.h @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_eth_ioctl.c b/mlinux/moal_eth_ioctl.c index da5d66c..f5e3880 100644 --- a/mlinux/moal_eth_ioctl.c +++ b/mlinux/moal_eth_ioctl.c @@ -2080,7 +2080,7 @@ done: static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) { - t_u32 data[4]; + t_u32 data[5]; mlan_ioctl_req *req = NULL; mlan_ds_rate *rate = 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); } - if (user_data_len > 4) { + if (user_data_len > 5) { PRINTM(MERROR, "Too many arguments\n"); ret = -EINVAL; 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)); if (req == NULL) { 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->param.rate_cfg.rate_type = MLAN_RATE_INDEX; + rate->auto_null_fixrate_enable = 0xFF; + if (user_data_len == 0) { /* Get operation */ 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]; } - if (user_data_len == 4) { + if ((user_data_len == 4) || (data[4] == 1)) { rate->param.rate_cfg.rate_setting = data[3] & ~0x0C00; PRINTM(MIOCTL, @@ -2246,6 +2254,13 @@ static int woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf, } else { 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]); + } } } diff --git a/mlinux/moal_init.c b/mlinux/moal_init.c index 56a8768..560661f 100644 --- a/mlinux/moal_init.c +++ b/mlinux/moal_init.c @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2018-2022 NXP + * Copyright 2018-2022, 2024 NXP * * This software file (the File) is distributed by NXP * 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 auto_11ax = 1; +static int reject_addba_req = 0; + /** * @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; params->dual_nb = out_data; 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) @@ -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.auto_11ax = auto_11ax; + handle->params.reject_addba_req = reject_addba_req; handle->params.dual_nb = dual_nb; if (params) 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); 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 CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) @@ -3019,3 +3037,8 @@ MODULE_PARM_DESC( module_param(dual_nb, int, 0); 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"); diff --git a/mlinux/moal_ioctl.c b/mlinux/moal_ioctl.c index d005124..5f46dbf 100644 --- a/mlinux/moal_ioctl.c +++ b/mlinux/moal_ioctl.c @@ -36,7 +36,7 @@ Change log: #ifdef UAP_SUPPORT #include "moal_uap.h" #endif - +#include #if defined(STA_CFG80211) || defined(UAP_CFG80211) #include "moal_cfg80211.h" #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; #endif t_u16 enable = 0; - - if (woal_mc_policy_cfg(priv, &enable, wait_option, MLAN_ACT_GET)) { - PRINTM(MERROR, "Get multi-channel policy failed\n"); + if (priv->phandle->card_info->drcs && + moal_extflg_isset(priv->phandle, EXT_CFG80211_DRCS)) { + if (woal_mc_policy_cfg(priv, &enable, wait_option, + MLAN_ACT_GET)) { + PRINTM(MERROR, "Get multi-channel policy failed\n"); + } } if (!enable) @@ -3090,8 +3093,10 @@ static mlan_status woal_set_ipv6_ra_offload(moal_handle *handle, t_u8 enable) moal_private *priv = NULL; mlan_ds_misc_cfg *misc = NULL; mlan_ioctl_req *req = NULL; - mlan_ds_misc_ipv6_ra_offload *ipv6_ra; + t_u8 *ipv6_ra; int i = 0; + unsigned long flags; + struct ipv6addr_entry *ipv6_entry = NULL; 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; req->req_id = MLAN_IOCTL_MISC_CFG; req->action = MLAN_ACT_SET; - ipv6_ra = &misc->param.ipv6_ra_offload; - ipv6_ra->enable = enable; - moal_memcpy_ext(priv->phandle, ipv6_ra->ipv6_addr, priv->ipv6_addr, 16, - sizeof(ipv6_ra->ipv6_addr)); + + misc->param.ipv6_ra_offload.enable = enable; + misc->param.ipv6_ra_offload.ipv6_addrs_count = priv->ipv6count; + 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, MOAL_NO_WAIT); 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.is_invoke_hostcmd = MTRUE; 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", __func__); LEAVE(); @@ -8306,7 +8319,7 @@ static int parse_tx_pwr_string(moal_handle *handle, const char *s, size_t len, if (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)) ret = -EINVAL; diff --git a/mlinux/moal_main.c b/mlinux/moal_main.c index e4ad6c8..cc65c1c 100644 --- a/mlinux/moal_main.c +++ b/mlinux/moal_main.c @@ -347,7 +347,7 @@ static struct _card_info card_info_SD8978 = { #ifdef SD8997 static struct _card_info card_info_SD8997 = { .embedded_supp = 1, - .drcs = 1, + .drcs = 0, .go_noa = 1, .v16_fw_api = 1, .pmic = 1, @@ -651,7 +651,7 @@ static struct _card_info card_info_SDIW615 = { #ifdef PCIE8997 static struct _card_info card_info_PCIE8997 = { .embedded_supp = 1, - .drcs = 1, + .drcs = 0, .go_noa = 1, .v16_fw_api = 1, .pmic = 1, @@ -1238,6 +1238,13 @@ void woal_clean_up(moal_handle *handle) GFP_KERNEL); } #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 // stop bgscan #ifdef STA_CFG80211 @@ -1693,6 +1700,65 @@ done: #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) #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 * @@ -1709,7 +1775,7 @@ static int woal_inet6_netdeive_event(struct notifier_block *nb, struct net_device *ndev = ifa->idev->dev; moal_private *priv; int ret = NOTIFY_OK; - + t_u8 addr[16] = {0}; ENTER(); #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) { case NETDEV_UP: PRINTM(MIOCTL, "[%s]: New ipv6 addr\n", ndev->name); - moal_memcpy_ext(priv->phandle, priv->ipv6_addr, - (t_u8 *)&ifa->addr, sizeof(priv->ipv6_addr), - sizeof(priv->ipv6_addr)); - priv->ipv6_addr_configured = MTRUE; + moal_memcpy_ext(priv->phandle, addr, (t_u8 *)&ifa->addr, + sizeof(addr), sizeof(addr)); + woal_add_ipv6_address(priv, addr); break; case NETDEV_DOWN: PRINTM(MIOCTL, "[%s]: Ipv6 addr removed.\n", ndev->name); - memset(priv->ipv6_addr, 0, sizeof(priv->ipv6_addr)); - priv->ipv6_addr_configured = MFALSE; + woal_remove_ipv6_address(priv, (t_u8 *)&ifa->addr); break; default: PRINTM(MIOCTL, "[%s]: Ignore event: %u\n", ndev->name, @@ -1793,6 +1857,37 @@ BOOLEAN woal_ssid_valid(mlan_802_11_ssid *pssid) 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 CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) /** @@ -2454,6 +2549,11 @@ mlan_status woal_init_sw(moal_handle *handle) handle); 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 @@ -2577,6 +2677,7 @@ mlan_status woal_init_sw(moal_handle *handle) device.second_mac = handle->second_mac; device.antcfg = handle->params.antcfg; 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++) { device.bss_attr[i].bss_type = @@ -5515,6 +5616,13 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, #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 INIT_LIST_HEAD(&priv->pmksa_cache_list); 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; if (handle->priv_num) woal_process_hang(handle); + handle->fw_dump = MFALSE; LEAVE(); return; } diff --git a/mlinux/moal_main.h b/mlinux/moal_main.h index d36e1aa..541cc46 100644 --- a/mlinux/moal_main.h +++ b/mlinux/moal_main.h @@ -436,6 +436,24 @@ typedef struct _moal_drv_timer { t_u32 timer_is_canceled; } 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 * @@ -1373,7 +1391,7 @@ struct rf_test_mode_data { /* Rx fcs error count */ t_u32 rx_pkt_fcs_err_count; /* Tx power config values */ - t_u32 tx_power_data[3]; + t_s32 tx_power_data[3]; /* Tx continuous config values */ t_u32 tx_cont_data[6]; /* Tx frame config values */ @@ -1550,6 +1568,13 @@ enum scan_set_band { }; #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 */ struct _moal_private { /** Handle structure */ @@ -1637,7 +1662,12 @@ struct _moal_private { /** IP addr */ t_u8 ip_addr[IPADDR_LEN]; 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 /** scan type */ t_u8 scan_type; @@ -2598,6 +2628,8 @@ typedef struct _moal_mod_para { int hs_auto_arp; /** Dual-BT **/ int dual_nb; + /* reject addba req config for HS or FW Auto-reconnect */ + t_u32 reject_addba_req; } moal_mod_para; void woal_tp_acnt_timer_func(void *context); @@ -2917,6 +2949,15 @@ struct _moal_handle { t_u64 cookie; #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 /** 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, pmlan_ds_remain_chan pchan); 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 mlan_status woal_wifi_direct_mode_cfg(moal_private *priv, t_u16 action, t_u16 *mode); diff --git a/mlinux/moal_pcie.c b/mlinux/moal_pcie.c index c441334..6defcbf 100644 --- a/mlinux/moal_pcie.c +++ b/mlinux/moal_pcie.c @@ -4,7 +4,7 @@ * related functions. * * - * Copyright 2008-2022 NXP + * Copyright 2008-2022, 2024 NXP * * This software file (the File) is distributed by NXP * 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)) handle->event_fw_dump = MTRUE; #endif + handle->fw_dump = MFALSE; goto exit; diff --git a/mlinux/moal_pcie.h b/mlinux/moal_pcie.h index a60be64..e2a3e69 100644 --- a/mlinux/moal_pcie.h +++ b/mlinux/moal_pcie.h @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2014-2021 NXP + * Copyright 2014-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_sdio.h b/mlinux/moal_sdio.h index 4c3ebb1..77a8516 100644 --- a/mlinux/moal_sdio.h +++ b/mlinux/moal_sdio.h @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2022 NXP + * Copyright 2008-2022, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_sdio_mmc.c b/mlinux/moal_sdio_mmc.c index 9350484..94b3741 100644 --- a/mlinux/moal_sdio_mmc.c +++ b/mlinux/moal_sdio_mmc.c @@ -4,7 +4,7 @@ * related functions. * * - * Copyright 2008-2022 NXP + * Copyright 2008-2022, 2024 NXP * * This software file (the File) is distributed by NXP * 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)) handle->event_fw_dump = MTRUE; #endif + handle->fw_dump = MFALSE; goto exit; diff --git a/mlinux/moal_shim.c b/mlinux/moal_shim.c index 3d3de9c..3bce6b1 100644 --- a/mlinux/moal_shim.c +++ b/mlinux/moal_shim.c @@ -2781,7 +2781,7 @@ static mlan_status wlan_process_defer_event(moal_handle *handle, * @return N/A */ 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; #if defined(STA_CFG80211) || defined(UAP_CFG80211) diff --git a/mlinux/moal_shim.h b/mlinux/moal_shim.h index 70d5dff..ca6ed5c 100644 --- a/mlinux/moal_shim.h +++ b/mlinux/moal_shim.h @@ -4,7 +4,7 @@ * functions defined in moal module * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_sta_cfg80211.c b/mlinux/moal_sta_cfg80211.c index 49e91b4..84a7e03 100644 --- a/mlinux/moal_sta_cfg80211.c +++ b/mlinux/moal_sta_cfg80211.c @@ -315,6 +315,14 @@ static int woal_cfg80211_disassociate(struct wiphy *wiphy, struct cfg80211_disassoc_request *req); #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 */ static struct cfg80211_ops woal_cfg80211_ops = { .change_virtual_intf = woal_cfg80211_change_virtual_intf, @@ -452,6 +460,11 @@ static struct cfg80211_ops woal_cfg80211_ops = { #ifdef CONFIG_NL80211_TESTMODE .testmode_cmd = woal_testmode_cmd, #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 */ @@ -2602,6 +2615,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv, { struct cfg80211_bss *bss = NULL; unsigned long flags; + t_u8 qos_cfg = 0; + int uapsd_queues = -1; u8 *assoc_req_buf = NULL; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) 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_info ->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) resp.links[0].bss = bss; 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_len = assoc_info->assoc_req_len; + resp.uapsd_queues = uapsd_queues; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) wiphy_lock(priv->wdev->wiphy); cfg80211_rx_assoc_resp(priv->netdev, @@ -2688,8 +2720,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv, cfg80211_rx_assoc_resp( priv->netdev, bss, assoc_info->assoc_resp_buf, - assoc_info->assoc_resp_len, -1, - assoc_req_buf, + assoc_info->assoc_resp_len, + uapsd_queues, assoc_req_buf, assoc_info->assoc_req_len); mutex_unlock(&priv->wdev->mtx); #else @@ -2698,7 +2730,8 @@ void woal_host_mlme_process_assoc_resp(moal_private *priv, cfg80211_rx_assoc_resp( priv->netdev, bss, assoc_info->assoc_resp_buf, - assoc_info->assoc_resp_len, -1); + assoc_info->assoc_resp_len, + uapsd_queues); mutex_unlock(&priv->wdev->mtx); #else #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; } - if (!ssid_bssid->ssid.ssid_len || ssid_bssid->ssid.ssid[0] < 0x20) { + if (!ssid_bssid->ssid.ssid_len) { PRINTM(MERROR, "Invalid SSID - aborting\n"); ret = -EINVAL; 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_TX_PACKETS) | MBIT(NL80211_STA_INFO_SIGNAL) | + MBIT(NL80211_STA_INFO_SIGNAL_AVG) | MBIT(NL80211_STA_INFO_TX_BITRATE) | MBIT(NL80211_STA_INFO_RX_BITRATE); #else @@ -3635,7 +3669,10 @@ static mlan_status woal_cfg80211_dump_station_info(moal_private *priv, sinfo->tx_bytes = priv->stats.tx_bytes; sinfo->rx_packets = priv->stats.rx_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) sinfo->tx_failed = stats.failed; #endif @@ -3792,6 +3829,7 @@ create_custom_regdomain(moal_private *priv, int idx, freq, prev_freq = 0; t_u8 chan; t_u16 num_chan = 0; + t_u16 pwr, prev_pwr = 0; t_u32 bw, prev_bw = 0; t_u16 chflags, prev_chflags = 0, valid_rules = 0; struct ieee80211_regdomain *regd = NULL; @@ -3843,11 +3881,25 @@ create_custom_regdomain(moal_private *priv, bw = MHZ_TO_KHZ(20); } + pwr = custom_reg->cfp_tbl[idx].max_tx_power; + if (idx == 0 || prev_chflags != chflags || prev_bw != bw || freq - prev_freq > 20) { valid_rules++; 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 = ®d->reg_rules[valid_rules - 1]; @@ -3861,7 +3913,9 @@ create_custom_regdomain(moal_private *priv, continue; 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; 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 j = 0; struct cfg80211_ssid *match_ssid = NULL; +#ifdef WIFI_DIRECT_SUPPORT + mlan_scan_cfg scan_cfg; +#endif + ENTER(); #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.enable = MTRUE; #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; - else - priv->scan_cfg.scan_chan_gap = 0; + } else { + 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 #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"); goto done; } - + handle->cfg80211_suspend = MFALSE; for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { if (handle->priv[i] && (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA)) { @@ -6791,7 +6860,6 @@ int woal_cfg80211_resume(struct wiphy *wiphy) #endif done: - handle->cfg80211_suspend = MFALSE; woal_queue_rx_task(handle); PRINTM(MCMND, "<--- Leave woal_cfg80211_resume --->\n"); return 0; @@ -10332,6 +10400,10 @@ mlan_status woal_register_cfg80211(moal_private *priv) wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; #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) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA); wiphy_ext_feature_set(wiphy, @@ -10503,3 +10575,140 @@ err_wiphy: LEAVE(); 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) */ diff --git a/mlinux/moal_uap.h b/mlinux/moal_uap.h index 686ed37..f5a1402 100644 --- a/mlinux/moal_uap.h +++ b/mlinux/moal_uap.h @@ -3,7 +3,7 @@ * @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 * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_uap_cfg80211.c b/mlinux/moal_uap_cfg80211.c index 607853f..9a69831 100644 --- a/mlinux/moal_uap_cfg80211.c +++ b/mlinux/moal_uap_cfg80211.c @@ -1969,6 +1969,10 @@ moal_private *woal_alloc_virt_interface(moal_handle *handle, t_u8 bss_index, spin_lock_init(&priv->dhcp_discover_lock); #endif +#ifdef STA_CFG80211 + INIT_LIST_HEAD(&priv->ipv6_addrses); + spin_lock_init(&priv->ipv6addr_lock); +#endif spin_lock_init(&priv->connect_lock); #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, chandef->chan->hw_value); woal_broadcast_event(priv, event_buf, strlen(event_buf)); - if (MLAN_STATUS_SUCCESS == - woal_mc_policy_cfg(priv, &enable, MOAL_IOCTL_WAIT, MLAN_ACT_GET)) { - if (enable) { - if (MLAN_STATUS_SUCCESS == - woal_get_active_intf_channel(priv, &channel)) { - if (channel.channel != - chandef->chan->hw_value) { - PRINTM(MERROR, - "DFS channel is not allowed when another connection exists on different channel\n"); - PRINTM(MERROR, - "Another connection's channel=%d, dfs channel=%d\n", - channel.channel, - chandef->chan->hw_value); - ret = -EINVAL; - goto done; + if (priv->phandle->card_info->drcs) { + if (MLAN_STATUS_SUCCESS == woal_mc_policy_cfg(priv, &enable, + MOAL_IOCTL_WAIT, + MLAN_ACT_GET)) { + if (enable) { + if (MLAN_STATUS_SUCCESS == + woal_get_active_intf_channel(priv, + &channel)) { + if (channel.channel != + chandef->chan->hw_value) { + PRINTM(MERROR, + "DFS channel is not allowed when another connection exists on different channel\n"); + PRINTM(MERROR, + "Another connection's channel=%d, dfs channel=%d\n", + channel.channel, + chandef->chan->hw_value); + ret = -EINVAL; + goto done; + } } } } diff --git a/mlinux/moal_usb.c b/mlinux/moal_usb.c index 8584dca..00089da 100644 --- a/mlinux/moal_usb.c +++ b/mlinux/moal_usb.c @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991 diff --git a/mlinux/moal_usb.h b/mlinux/moal_usb.h index 4ea8b1f..dd4fa95 100644 --- a/mlinux/moal_usb.h +++ b/mlinux/moal_usb.h @@ -4,7 +4,7 @@ * driver. * * - * Copyright 2008-2021 NXP + * Copyright 2008-2021, 2024 NXP * * This software file (the File) is distributed by NXP * under the terms of the GNU General Public License Version 2, June 1991