diff --git a/Makefile b/Makefile index 145c547..f4e155b 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.p18"' + ccflags-y += -DMLAN_RELEASE_VERSION='"437.p21"' ccflags-y += -DFPNUM='"92"' diff --git a/README b/README index c9bbc07..0b3b755 100644 --- a/README +++ b/README @@ -59,7 +59,7 @@ auto_ds=0|1|2 ext_scan=0|1|2 net_rx=0|1 - amsdu_deaggr=0|1 + amsdu_deaggr=0|1 ps_mode=0|1|2 sched_scan=0|1 @@ -145,11 +145,18 @@ Bit7~Bit0:mode for channel index1; 0|1 roamoffload_in_hs=0|1 uap_max_sta: Maximum number of STA for UAP/GO (default 0, max 64) + + auto_fw_reload=0|1|3 + auto_fw_reload=0|1 + + dmcs=0|1 + host_mlme=0|1 for supplicant/authenticator running on host side, WPA3 support is available only in host_mlme mode for chipset 89xx FP-92, 90xx and later, host_mlme restricted to 1 country_ie_ignore=0|1 beacon_hints=0|1 + edmac_ctrl=0|1 chan_track=0|1 for 9098 only keep_previous_scan=0|1, @@ -476,13 +483,6 @@ echo "trigger_frame=1 0 1 2 5484 0 256 0 0 0 1 0 0 0 1 60 1 0 65535 0 511 5 0 61 0 0 0 0 90 0 0 0 0" > /proc/mwlan/adapter0/config echo "tx_frame=1 0x1102 0xabababab 200" >/proc/mwlan/adapter0/config - OTP Read/Write - Example: Read OTP MAC address. - echo "otp_mac_add_rd_wr=0" > /proc/mwlan/adapter0/config - - Example: Write OTP MAC addres. - echo "otp_mac_add_rd_wr=1 AA:BB:CC:DD:EE:FF" > /proc/mwlan/adapter0/config - 6) Set host sleep parameters hssetpara diff --git a/mlan/mlan_11ax.c b/mlan/mlan_11ax.c index 1d66ee4..fe60aef 100644 --- a/mlan/mlan_11ax.c +++ b/mlan/mlan_11ax.c @@ -933,6 +933,8 @@ mlan_status wlan_cmd_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, (mlan_ds_11ax_set_bsrp_cmd *)&ds_11ax_cmd->param; mlan_ds_11ax_llde_cmd *llde_cmd = (mlan_ds_11ax_llde_cmd *)&ds_11ax_cmd->param; + mlan_ds_11ax_rutxpwr_cmd *rutxpwr_cmd = + (mlan_ds_11ax_rutxpwr_cmd *)&ds_11ax_cmd->param; MrvlIEtypes_Data_t *tlv = MNULL; ENTER(); @@ -985,6 +987,12 @@ mlan_status wlan_cmd_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd, sizeof(mlan_ds_11ax_llde_cmd)); cmd->size += sizeof(mlan_ds_11ax_llde_cmd); break; + case MLAN_11AXCMD_RUTXSUBPWR_SUBID: + memcpy_ext(pmadapter, axcmd->val, &rutxpwr_cmd->subBand, + sizeof(t_u8), sizeof(t_u8)); + cmd->size += sizeof(t_u8); + break; + default: PRINTM(MERROR, "Unknown subcmd %x\n", ds_11ax_cmd->sub_id); break; @@ -1068,6 +1076,13 @@ mlan_status wlan_ret_11ax_cmd(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, memcpy_ext(pmadapter, &cfg->param.llde_cfg.llde, axcmd->val, sizeof(mlan_ds_11ax_llde_cmd), sizeof(mlan_ds_11ax_llde_cmd)); + pmadapter->llde_enabled = cfg->param.llde_cfg.llde; + pmadapter->llde_mode = cfg->param.llde_cfg.mode; + break; + case MLAN_11AXCMD_RUTXSUBPWR_SUBID: + memcpy_ext(pmadapter, &cfg->param.rutxpwr_cfg, axcmd->val, + sizeof(mlan_ds_11ax_rutxpwr_cmd), + sizeof(mlan_ds_11ax_rutxpwr_cmd)); break; default: PRINTM(MERROR, "Unknown subcmd %x\n", axcmd->sub_id); diff --git a/mlan/mlan_cmdevt.c b/mlan/mlan_cmdevt.c index 762ba4a..01b860f 100644 --- a/mlan/mlan_cmdevt.c +++ b/mlan/mlan_cmdevt.c @@ -9227,6 +9227,12 @@ static void wlan_fill_link_statistic(mlan_private *priv, iface_stat->peer_info[peerIdx].peer_mac_address, fw_ifaceStat->peer_info[peerIdx].peer_mac_address, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH); + iface_stat->peer_info[peerIdx].bssload.sta_count = + wlan_le16_to_cpu(fw_ifaceStat->peer_info[peerIdx] + .bssload.sta_count); + iface_stat->peer_info[peerIdx].bssload.chan_util = + wlan_le16_to_cpu(fw_ifaceStat->peer_info[peerIdx] + .bssload.chan_util); iface_stat->peer_info[peerIdx].capabilities = wlan_le32_to_cpu( fw_ifaceStat->peer_info[peerIdx].capabilities); iface_stat->peer_info[peerIdx].num_rate = wlan_le32_to_cpu( diff --git a/mlan/mlan_decl.h b/mlan/mlan_decl.h index 0760357..3a2fc83 100644 --- a/mlan/mlan_decl.h +++ b/mlan/mlan_decl.h @@ -2002,6 +2002,14 @@ typedef enum { WIFI_PEER_INVALID, } wifi_peer_type; +typedef struct bssload_info { + /** station count */ + t_u16 sta_count; + /** channel utilization */ + t_u16 chan_util; + t_u8 PAD[4]; +} bssload_info_t; + /** per peer statistics */ typedef struct { /** peer type (AP, TDLS, GO etc.) */ @@ -2010,6 +2018,8 @@ typedef struct { t_u8 peer_mac_address[6]; /** peer WIFI_CAPABILITY_XXX */ t_u32 capabilities; + /** STA count and channel utilization */ + bssload_info_t bssload; /** number of rates */ t_u32 num_rate; /** per rate statistics, number of entries = num_rate */ diff --git a/mlan/mlan_fw.h b/mlan/mlan_fw.h index 4bfbbeb..97b5b87 100644 --- a/mlan/mlan_fw.h +++ b/mlan/mlan_fw.h @@ -3611,6 +3611,14 @@ typedef MLAN_PACK_START struct { t_u32 retries_long; } MLAN_PACK_END mlan_wifi_rate_stat; +typedef MLAN_PACK_START struct { + /** station count */ + t_u16 sta_count; + /** channel utilization */ + t_u16 chan_util; + t_u8 PAD[4]; +} MLAN_PACK_END mlan_bssload_info; + /** per peer statistics */ typedef MLAN_PACK_START struct { /** peer type (AP, TDLS, GO etc.) */ @@ -3619,6 +3627,8 @@ typedef MLAN_PACK_START struct { t_u8 peer_mac_address[6]; /** peer WIFI_CAPABILITY_XXX */ t_u32 capabilities; + /** STA count and channel utilization */ + mlan_bssload_info bssload; /** number of rates */ t_u32 num_rate; /** per rate statistics, number of entries = num_rate */ diff --git a/mlan/mlan_init.c b/mlan/mlan_init.c index 5129d7a..c94ae9b 100644 --- a/mlan/mlan_init.c +++ b/mlan/mlan_init.c @@ -314,20 +314,6 @@ mlan_status wlan_allocate_adapter(pmlan_adapter pmadapter) LEAVE(); return MLAN_STATUS_FAILURE; } - if (pmadapter->callbacks.moal_vmalloc && - pmadapter->callbacks.moal_vfree) - ret = pmadapter->callbacks.moal_vmalloc( - pmadapter->pmoal_handle, buf_size, - (t_u8 **)&pmadapter->pold_chan_stats); - else - ret = pmadapter->callbacks.moal_malloc( - pmadapter->pmoal_handle, buf_size, MLAN_MEM_DEF, - (t_u8 **)&pmadapter->pold_chan_stats); - if (ret != MLAN_STATUS_SUCCESS || !pmadapter->pold_chan_stats) { - PRINTM(MERROR, "Failed to allocate old channel statistics\n"); - LEAVE(); - return MLAN_STATUS_FAILURE; - } #endif /* Allocate command buffer */ @@ -1809,15 +1795,6 @@ t_void wlan_free_adapter(pmlan_adapter pmadapter) (t_u8 *)pmadapter->pchan_stats); pmadapter->pchan_stats = MNULL; } - if (pmadapter->pold_chan_stats) { - if (pcb->moal_vmalloc && pcb->moal_vfree) - pcb->moal_vfree(pmadapter->pmoal_handle, - (t_u8 *)pmadapter->pold_chan_stats); - else - pcb->moal_mfree(pmadapter->pmoal_handle, - (t_u8 *)pmadapter->pold_chan_stats); - pmadapter->pold_chan_stats = MNULL; - } if (pmadapter->bcn_buf) { if (pcb->moal_vmalloc && pcb->moal_vfree) pcb->moal_vfree(pmadapter->pmoal_handle, diff --git a/mlan/mlan_ioctl.h b/mlan/mlan_ioctl.h index 252a7de..6e8c67b 100644 --- a/mlan/mlan_ioctl.h +++ b/mlan/mlan_ioctl.h @@ -4012,6 +4012,7 @@ typedef struct _mlan_ds_11ax_cfg { #define MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME 7 #define MLAN_11AXCMD_CFG_ID_SET_BSRP 8 #define MLAN_11AXCMD_CFG_ID_LLDE 9 +#define MLAN_11AXCMD_CFG_ID_RUTXPWR 10 #define MLAN_11AXCMD_SR_SUBID 0x102 #define MLAN_11AXCMD_BEAM_SUBID 0x103 @@ -4021,6 +4022,7 @@ typedef struct _mlan_ds_11ax_cfg { #define MLAN_11AXCMD_TXOPRTS_SUBID 0x108 #define MLAN_11AXCMD_SET_BSRP_SUBID 0x109 #define MLAN_11AXCMD_LLDE_SUBID 0x110 +#define MLAN_11AXCMD_RUTXSUBPWR_SUBID 0x118 #define MLAN_11AX_TWT_SETUP_SUBID 0x114 #define MLAN_11AX_TWT_TEARDOWN_SUBID 0x115 @@ -4031,6 +4033,8 @@ typedef struct _mlan_ds_11ax_cfg { #define MRVL_DOT11AX_OBSS_PD_OFFSET_TLV_ID (PROPRIETARY_TLV_BASE_ID + 323) #define NXP_6E_INBAND_FRAMES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 345) // 0x0159 +#define MLAN_11AXCMD_LLDE_MODE_EVENT_DRIVEN 5 + /** Type definition of mlan_11axcmdcfg_obss_pd_offset for MLAN_OID_11AX_CMD_CFG */ typedef struct MLAN_PACK_START _mlan_11axcmdcfg_obss_pd_offset { @@ -4122,6 +4126,21 @@ typedef struct _mlan_ds_11ax_llde_cmd { t_u16 tbppdu_datacnt; } mlan_ds_11ax_llde_cmd, *pmlan_ds_11ax_llde_cmd; +/** Type definition of mlan_ds_11ax_rutxpwr_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_rutxpwr_cmd { + /** type*/ + t_u16 type; + /** length of TLV */ + t_u16 len; + /** Sub-Band */ + t_u8 subBand; + /** column,row are 3 for every subband table,however column are 7 for FC + * and 6 for other SOCs */ + t_u8 col; + /**ru tx data */ + t_u8 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 */ typedef struct _mlan_ds_11ax_cmd_cfg { /** Sub-command */ @@ -4147,6 +4166,8 @@ typedef struct _mlan_ds_11ax_cmd_cfg { mlan_ds_11ax_set_bsrp_cmd setbsrp_cfg; /* MLAN_11AXCMD_LLDE_SUBID */ mlan_ds_11ax_llde_cmd llde_cfg; + /* MLAN_11AXCMD_RUTXPWR_SUBID */ + mlan_ds_11ax_rutxpwr_cmd rutxpwr_cfg; } param; } mlan_ds_11ax_cmd_cfg, *pmlan_ds_11ax_cmd_cfg; diff --git a/mlan/mlan_main.h b/mlan/mlan_main.h index edd7433..a3fa318 100644 --- a/mlan/mlan_main.h +++ b/mlan/mlan_main.h @@ -799,6 +799,7 @@ typedef struct _tidTbl { /** Highest priority setting for a packet (uses voice AC) */ #define WMM_HIGHEST_PRIORITY 7 +#define WMM_SECOND_HIGHEST_PRIORITY 6 /** Highest priority TID */ #define HIGH_PRIO_TID 7 /** Lowest priority TID */ @@ -2637,9 +2638,6 @@ struct _mlan_adapter { t_u32 num_in_chan_stats; /** index of chan stats */ t_u32 idx_chan_stats; - ChanStatistics_t *pold_chan_stats; - /** index of chan stats */ - t_u32 old_idx_chan_stats; t_u8 bgscan_reported; /** Number of records in the scan table */ @@ -2925,6 +2923,8 @@ struct _mlan_adapter { t_u16 flush_time_ac_vi_vo; /** remain_on_channel flag */ t_u8 remain_on_channel; + t_u8 llde_enabled; + t_u8 llde_mode; }; /** Check if stream 2X2 enabled */ @@ -2943,6 +2943,8 @@ struct _mlan_adapter { #define MLAN_ETHER_PKT_TYPE_WAPI (0x88B4) /** Ethernet packet type for IP */ #define MLAN_ETHER_PKT_TYPE_IP (0x0800) +/** Ethernet packet type for 1905.1a (EASYMESH) */ +#define MLAN_ETHER_PKT_TYPE_1905 (0x893a) /** Ethernet packet type offset */ #define MLAN_ETHER_PKT_TYPE_OFFSET (12) diff --git a/mlan/mlan_scan.c b/mlan/mlan_scan.c index 803f165..87dc754 100644 --- a/mlan/mlan_scan.c +++ b/mlan/mlan_scan.c @@ -164,6 +164,38 @@ t_u16 radio_type_to_band(t_u8 radio_type) return ret_band; } +/** + * @brief This function will update the channel statistics from scan result + * + * @param pmpriv A pointer to mlan_private structure + * @param pchan_stats A pointer to chan_statistics_t + * + * @return MTRUE/MFALSE + */ +static t_u8 wlan_set_chan_statistics(mlan_private *pmpriv, + chan_statistics_t *pchan_stats) +{ + t_u8 i; + t_u8 ret = MFALSE; + mlan_adapter *pmadapter = pmpriv->adapter; + chan_statistics_t *pstats = MNULL; + ENTER(); + for (i = 0; i < pmadapter->idx_chan_stats; i++) { + pstats = (chan_statistics_t *)&pmadapter->pchan_stats[i]; + if (pstats->chan_num == pchan_stats->chan_num && + (pstats->bandcfg.chanBand == + pchan_stats->bandcfg.chanBand)) { + memcpy_ext(pmadapter, (chan_statistics_t *)pstats, + pchan_stats, sizeof(chan_statistics_t), + sizeof(chan_statistics_t)); + ret = MTRUE; + break; + } + } + LEAVE(); + return ret; +} + /** * @brief This function will update the channel statistics from scan result * @@ -187,13 +219,6 @@ wlan_update_chan_statistics(mlan_private *pmpriv, ENTER(); for (i = 0; i < num_chan; i++) { - if (pmadapter->idx_chan_stats >= pmadapter->num_in_chan_stats) { - PRINTM(MERROR, - "Over flow: idx_chan_stats=%d, num_in_chan_stats=%d\n", - pmadapter->idx_chan_stats, - pmadapter->num_in_chan_stats); - break; - } pchan_stats->total_networks = wlan_le16_to_cpu(pchan_stats->total_networks); pchan_stats->cca_scan_duration = @@ -206,12 +231,24 @@ wlan_update_chan_statistics(mlan_private *pmpriv, pchan_stats->total_networks, pchan_stats->cca_scan_duration, pchan_stats->cca_busy_duration); - memcpy_ext(pmadapter, - (chan_statistics_t *)&pmadapter - ->pchan_stats[pmadapter->idx_chan_stats], - pchan_stats, sizeof(chan_statistics_t), - sizeof(chan_statistics_t)); - pmadapter->idx_chan_stats++; + if (!wlan_set_chan_statistics(pmpriv, pchan_stats)) { + if (pmadapter->idx_chan_stats >= + pmadapter->num_in_chan_stats) { + PRINTM(MERROR, + "Over flow: idx_chan_stats=%d, num_in_chan_stats=%d\n", + pmadapter->idx_chan_stats, + pmadapter->num_in_chan_stats); + LEAVE(); + return; + } + memcpy_ext( + pmadapter, + (chan_statistics_t *)&pmadapter + ->pchan_stats[pmadapter->idx_chan_stats], + pchan_stats, sizeof(chan_statistics_t), + sizeof(chan_statistics_t)); + pmadapter->idx_chan_stats++; + } pchan_stats++; } LEAVE(); @@ -4185,7 +4222,6 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf, t_u8 filtered_scan; t_u8 scan_current_chan_only; t_u8 max_chan_per_scan; - t_u8 i; ENTER(); @@ -4241,26 +4277,12 @@ mlan_status wlan_scan_networks(mlan_private *pmpriv, t_void *pioctl_buf, keep_previous_scan = puser_scan_in->keep_previous_scan; if (keep_previous_scan == MFALSE) { - memset(pmadapter, pmadapter->pscan_table, 0x00, - sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST); - pmadapter->num_in_scan_table = 0; + wlan_flush_scan_table(pmadapter); pmadapter->pbcn_buf_end = pmadapter->bcn_buf; } else { wlan_scan_delete_ageout_entry(pmpriv); } - // back up the pchan_stats before reset it - memset(pmadapter, pmadapter->pold_chan_stats, 0x00, - sizeof(ChanStatistics_t) * pmadapter->num_in_chan_stats); - memcpy_ext(pmpriv->adapter, pmadapter->pold_chan_stats, - pmadapter->pchan_stats, - sizeof(ChanStatistics_t) * pmadapter->num_in_chan_stats, - sizeof(ChanStatistics_t) * pmadapter->num_in_chan_stats); - pmadapter->old_idx_chan_stats = pmadapter->idx_chan_stats; - for (i = 0; i < pmadapter->num_in_chan_stats; i++) - pmadapter->pchan_stats[i].cca_scan_duration = 0; - pmadapter->idx_chan_stats = 0; - ret = wlan_scan_channel_list(pmpriv, pioctl_buf, max_chan_per_scan, filtered_scan, &pscan_cfg_out->config, pchan_list_out, pscan_chan_list); @@ -6453,7 +6475,7 @@ mlan_status wlan_cmd_bgscan_config(mlan_private *pmpriv, pwildcard_ssid_tlv->header.len; pwildcard_ssid_tlv->header.len = wlan_cpu_to_le16(pwildcard_ssid_tlv->header.len); - PRINTM(MINFO, "Scan: ssid_list[%d]: %s, %d\n", ssid_idx, + PRINTM(MCMD_D, "bgScan: ssid_list[%d]: %s, %d\n", ssid_idx, pwildcard_ssid_tlv->ssid, pwildcard_ssid_tlv->max_ssid_length); } diff --git a/mlan/mlan_shim.c b/mlan/mlan_shim.c index b10dcb2..9adea70 100644 --- a/mlan/mlan_shim.c +++ b/mlan/mlan_shim.c @@ -1458,6 +1458,8 @@ mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf) pmbuf->flags |= MLAN_BUF_FLAG_MOAL_TX_BUF; pmpriv = pmadapter->priv[pmbuf->bss_index]; + if (pmbuf->data_offset > UINT32_MAX - MLAN_ETHER_PKT_TYPE_OFFSET) + return MLAN_STATUS_FAILURE; eth_type = mlan_ntohs(*(t_u16 *)&pmbuf->pbuf[pmbuf->data_offset + MLAN_ETHER_PKT_TYPE_OFFSET]); @@ -1474,8 +1476,16 @@ mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf) *((t_u8 *)(pmbuf->pbuf + pmbuf->data_offset + MLAN_ETHER_PKT_TYPE_OFFSET + MLAN_IP_PROTOCOL_OFFSET)); - if (ip_protocol == MLAN_IP_PROTOCOL_ICMP) + if (ip_protocol == MLAN_IP_PROTOCOL_ICMP) { pmbuf->priority = WMM_HIGHEST_PRIORITY; + /** If LLDE Enabled, change the ICMP Prio to 6 + */ + if (pmadapter->llde_enabled && + (pmadapter->llde_mode == + MLAN_11AXCMD_LLDE_MODE_EVENT_DRIVEN)) + pmbuf->priority = + WMM_SECOND_HIGHEST_PRIORITY; + } } } #endif @@ -1487,6 +1497,7 @@ mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf) */ || (ip_protocol == MLAN_IP_PROTOCOL_ICMP) || (eth_type == MLAN_ETHER_PKT_TYPE_TDLS_ACTION) || + (eth_type == MLAN_ETHER_PKT_TYPE_1905) || (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) /* Adding the Ucast/Mcast pkt to bypass queue when flag is set*/ || (pmbuf->flags & MLAN_BUF_FLAG_MC_AGGR_PKT) @@ -1502,10 +1513,38 @@ mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf) pmbuf->flags |= MLAN_BUF_FLAG_TDLS; } if (eth_type == MLAN_ETHER_PKT_TYPE_EAPOL) { + pmbuf->priority = 7; PRINTM_NETINTF(MMSG, pmpriv); PRINTM(MMSG, "wlan: Send EAPOL pkt to " MACSTR "\n", MAC2STR(pmbuf->pbuf + pmbuf->data_offset)); } + + if (eth_type == MLAN_ETHER_PKT_TYPE_1905) { + t_u16 msg_type = 0; + + if (pmbuf->data_offset > + UINT32_MAX - MLAN_ETHER_PKT_TYPE_OFFSET - 4) + return MLAN_STATUS_FAILURE; + + msg_type = mlan_ntohs( + *(t_u16 *)&pmbuf + ->pbuf[pmbuf->data_offset + + MLAN_ETHER_PKT_TYPE_OFFSET + 4]); + + if (msg_type == 0x0007 || /* CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH + */ + msg_type == 0x0008 || /* CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE + */ + msg_type == 0x0009) { /* CMDU_TYPE_AP_AUTOCONFIGURATION_WSC + */ + pmbuf->priority = 7; + PRINTM_NETINTF(MMSG, pmpriv); + PRINTM(MMSG, + "wlan: Send 1905.1a pkt type: 0x%04x\n", + msg_type); + } + } + if (pmadapter->tp_state_on) pmadapter->callbacks.moal_tp_accounting( pmadapter->pmoal_handle, pmbuf->pdesc, 2); diff --git a/mlan/mlan_sta_event.c b/mlan/mlan_sta_event.c index 54f4195..755909e 100644 --- a/mlan/mlan_sta_event.c +++ b/mlan/mlan_sta_event.c @@ -611,9 +611,15 @@ static void wlan_process_sta_tx_pause_event(pmlan_private priv, } if (tlv_type == TLV_TYPE_TX_PAUSE) { tx_pause_tlv = (MrvlIEtypes_tx_pause_t *)tlv; - PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n", + PRINTM(MCMND, + "TxPause: " MACSTR + " pause=%d, pkts=%d, priv->tx_pause=%d\n", MAC2STR(tx_pause_tlv->peermac), - tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt); + tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt, + priv->tx_pause); + if (bssid) + PRINTM(MCMND, "TxPause: " MACSTR "\n", + MAC2STR(bssid)); status = wlan_get_tdls_link_status( priv, tx_pause_tlv->peermac); if (status != TDLS_NOT_SETUP) { diff --git a/mlan/mlan_sta_ioctl.c b/mlan/mlan_sta_ioctl.c index d681caa..e0183ce 100644 --- a/mlan/mlan_sta_ioctl.c +++ b/mlan/mlan_sta_ioctl.c @@ -5414,20 +5414,10 @@ start_config: pioctl_req->data_read_written = sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE; - if (pmadapter->scan_processing) { - pscan->param.scan_resp.pchan_stats = - (t_u8 *)pmadapter - ->pold_chan_stats; - pscan->param.scan_resp - .num_in_chan_stats = - pmadapter->old_idx_chan_stats; - } else { - pscan->param.scan_resp.pchan_stats = - (t_u8 *)pmadapter->pchan_stats; - pscan->param.scan_resp - .num_in_chan_stats = - pmadapter->idx_chan_stats; - } + pscan->param.scan_resp.pchan_stats = + (t_u8 *)pmadapter->pchan_stats; + pscan->param.scan_resp.num_in_chan_stats = + pmadapter->idx_chan_stats; } } } diff --git a/mlinux/mlan_decl.h b/mlinux/mlan_decl.h index 0760357..3a2fc83 100644 --- a/mlinux/mlan_decl.h +++ b/mlinux/mlan_decl.h @@ -2002,6 +2002,14 @@ typedef enum { WIFI_PEER_INVALID, } wifi_peer_type; +typedef struct bssload_info { + /** station count */ + t_u16 sta_count; + /** channel utilization */ + t_u16 chan_util; + t_u8 PAD[4]; +} bssload_info_t; + /** per peer statistics */ typedef struct { /** peer type (AP, TDLS, GO etc.) */ @@ -2010,6 +2018,8 @@ typedef struct { t_u8 peer_mac_address[6]; /** peer WIFI_CAPABILITY_XXX */ t_u32 capabilities; + /** STA count and channel utilization */ + bssload_info_t bssload; /** number of rates */ t_u32 num_rate; /** per rate statistics, number of entries = num_rate */ diff --git a/mlinux/mlan_ioctl.h b/mlinux/mlan_ioctl.h index 252a7de..6e8c67b 100644 --- a/mlinux/mlan_ioctl.h +++ b/mlinux/mlan_ioctl.h @@ -4012,6 +4012,7 @@ typedef struct _mlan_ds_11ax_cfg { #define MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME 7 #define MLAN_11AXCMD_CFG_ID_SET_BSRP 8 #define MLAN_11AXCMD_CFG_ID_LLDE 9 +#define MLAN_11AXCMD_CFG_ID_RUTXPWR 10 #define MLAN_11AXCMD_SR_SUBID 0x102 #define MLAN_11AXCMD_BEAM_SUBID 0x103 @@ -4021,6 +4022,7 @@ typedef struct _mlan_ds_11ax_cfg { #define MLAN_11AXCMD_TXOPRTS_SUBID 0x108 #define MLAN_11AXCMD_SET_BSRP_SUBID 0x109 #define MLAN_11AXCMD_LLDE_SUBID 0x110 +#define MLAN_11AXCMD_RUTXSUBPWR_SUBID 0x118 #define MLAN_11AX_TWT_SETUP_SUBID 0x114 #define MLAN_11AX_TWT_TEARDOWN_SUBID 0x115 @@ -4031,6 +4033,8 @@ typedef struct _mlan_ds_11ax_cfg { #define MRVL_DOT11AX_OBSS_PD_OFFSET_TLV_ID (PROPRIETARY_TLV_BASE_ID + 323) #define NXP_6E_INBAND_FRAMES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 345) // 0x0159 +#define MLAN_11AXCMD_LLDE_MODE_EVENT_DRIVEN 5 + /** Type definition of mlan_11axcmdcfg_obss_pd_offset for MLAN_OID_11AX_CMD_CFG */ typedef struct MLAN_PACK_START _mlan_11axcmdcfg_obss_pd_offset { @@ -4122,6 +4126,21 @@ typedef struct _mlan_ds_11ax_llde_cmd { t_u16 tbppdu_datacnt; } mlan_ds_11ax_llde_cmd, *pmlan_ds_11ax_llde_cmd; +/** Type definition of mlan_ds_11ax_rutxpwr_cmd for MLAN_OID_11AX_CMD_CFG */ +typedef struct _mlan_ds_11ax_rutxpwr_cmd { + /** type*/ + t_u16 type; + /** length of TLV */ + t_u16 len; + /** Sub-Band */ + t_u8 subBand; + /** column,row are 3 for every subband table,however column are 7 for FC + * and 6 for other SOCs */ + t_u8 col; + /**ru tx data */ + t_u8 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 */ typedef struct _mlan_ds_11ax_cmd_cfg { /** Sub-command */ @@ -4147,6 +4166,8 @@ typedef struct _mlan_ds_11ax_cmd_cfg { mlan_ds_11ax_set_bsrp_cmd setbsrp_cfg; /* MLAN_11AXCMD_LLDE_SUBID */ mlan_ds_11ax_llde_cmd llde_cfg; + /* MLAN_11AXCMD_RUTXPWR_SUBID */ + mlan_ds_11ax_rutxpwr_cmd rutxpwr_cfg; } param; } mlan_ds_11ax_cmd_cfg, *pmlan_ds_11ax_cmd_cfg; diff --git a/mlinux/moal_eth_ioctl.c b/mlinux/moal_eth_ioctl.c index dda746c..2f4f597 100644 --- a/mlinux/moal_eth_ioctl.c +++ b/mlinux/moal_eth_ioctl.c @@ -527,6 +527,10 @@ static int woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf, cfg->param.llde_cfg.txOpDuration = data[8]; cfg->param.llde_cfg.llde_ctrl = data[9]; break; + case MLAN_11AXCMD_CFG_ID_RUTXPWR: + cfg->sub_id = MLAN_11AXCMD_RUTXSUBPWR_SUBID; + break; + default: PRINTM(MERROR, "unknown 11axcmd\n"); ret = -EFAULT; diff --git a/mlinux/moal_main.c b/mlinux/moal_main.c index 8711392..e4ad6c8 100644 --- a/mlinux/moal_main.c +++ b/mlinux/moal_main.c @@ -8233,13 +8233,6 @@ static void woal_start_xmit(moal_private *priv, struct sk_buff *skb) case MLAN_STATUS_PENDING: atomic_inc(&priv->phandle->tx_pending); -#ifdef UAP_SUPPORT -#if defined(UAP_CFG80211) || defined(STA_CFG80211) - if (priv->wdev->iftype == NL80211_IFTYPE_AP_VLAN) - priv = priv->parent_priv; -#endif -#endif - #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29) atomic_inc(&priv->wmm_tx_pending[index]); if (atomic_read(&priv->wmm_tx_pending[index]) >= diff --git a/mlinux/moal_pcie.c b/mlinux/moal_pcie.c index 2d77296..c441334 100644 --- a/mlinux/moal_pcie.c +++ b/mlinux/moal_pcie.c @@ -33,7 +33,9 @@ Change log: #endif #include "moal_pcie.h" - +#ifdef UAP_SUPPORT +#include "moal_uap.h" +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) #ifdef IMX_SUPPORT #include @@ -760,39 +762,51 @@ static int woal_pcie_suspend(struct pci_dev *pdev, pm_message_t state) ret = -EBUSY; goto done; } - 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)) - woal_cancel_scan(handle->priv[i], MOAL_IOCTL_WAIT); - } - handle->suspend_fail = MFALSE; - memset(&pm_info, 0, sizeof(pm_info)); -#define MAX_RETRY_NUM 8 - for (i = 0; i < MAX_RETRY_NUM; i++) { - if (MLAN_STATUS_SUCCESS == - woal_get_pm_info(woal_get_priv(handle, MLAN_BSS_ROLE_ANY), - &pm_info)) { - if (pm_info.is_suspend_allowed == MTRUE) - break; - else - PRINTM(MMSG, - "Suspend not allowed and retry again\n"); - } - woal_sched_timeout(100); - } - if (pm_info.is_suspend_allowed == MFALSE) { - PRINTM(MMSG, "Suspend not allowed\n"); - ret = -EBUSY; - goto done; - } - - for (i = 0; i < handle->priv_num; i++) - netif_device_detach(handle->priv[i]->netdev); if (moal_extflg_isset(handle, EXT_PM_KEEP_POWER)) keep_power = MTRUE; else keep_power = MFALSE; + for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { + if (handle->priv[i]) + woal_cancel_scan(handle->priv[i], MOAL_IOCTL_WAIT); +#ifdef UAP_SUPPORT + if (handle->priv[i] && !keep_power && + handle->priv[i]->bss_started == MTRUE) { + if (woal_uap_bss_ctrl(handle->priv[i], MOAL_IOCTL_WAIT, + UAP_BSS_STOP)) { + PRINTM(MERROR, "%s: stop uap failed \n", + __func__); + } + } +#endif + } + handle->suspend_fail = MFALSE; + if (keep_power) { + memset(&pm_info, 0, sizeof(pm_info)); +#define MAX_RETRY_NUM 8 + for (i = 0; i < MAX_RETRY_NUM; i++) { + if (MLAN_STATUS_SUCCESS == + woal_get_pm_info(woal_get_priv(handle, + MLAN_BSS_ROLE_ANY), + &pm_info)) { + if (pm_info.is_suspend_allowed == MTRUE) + break; + else + PRINTM(MMSG, + "Suspend not allowed and retry again\n"); + } + woal_sched_timeout(100); + } + if (pm_info.is_suspend_allowed == MFALSE) { + PRINTM(MMSG, "Suspend not allowed\n"); + ret = -EBUSY; + goto done; + } + } + for (i = 0; i < handle->priv_num; i++) + netif_device_detach(handle->priv[i]->netdev); + if (keep_power) { /* Enable Host Sleep */ hs_actived = woal_enable_hs( @@ -1245,6 +1259,13 @@ static irqreturn_t woal_pcie_interrupt(int irq, void *dev_id) goto exit; } handle = card->handle; + /* No need to handle Interrupt during FW reload, we can safely return + * success to Kernel */ + if (handle->surprise_removed == MTRUE && handle->fw_reseting) { + PRINTM(MINFO, "*** SKIP INTR handling during FW reload ***\n"); + ret = MLAN_STATUS_SUCCESS; + return IRQ_HANDLED; + } PRINTM(MINFO, "*** IN PCIE IRQ ***\n"); handle->main_state = MOAL_RECV_INT; if (handle->second_mac) diff --git a/mlinux/moal_sdio_mmc.c b/mlinux/moal_sdio_mmc.c index d790cfd..9350484 100644 --- a/mlinux/moal_sdio_mmc.c +++ b/mlinux/moal_sdio_mmc.c @@ -793,8 +793,7 @@ int woal_sdio_suspend(struct device *dev) } #ifdef STA_SUPPORT 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)) + if (handle->priv[i]) woal_cancel_scan(handle->priv[i], MOAL_IOCTL_WAIT); } #endif diff --git a/mlinux/moal_shim.c b/mlinux/moal_shim.c index 16f61e6..3d3de9c 100644 --- a/mlinux/moal_shim.c +++ b/mlinux/moal_shim.c @@ -1148,6 +1148,12 @@ mlan_status moal_send_packet_complete(t_void *pmoal, pmlan_buffer pmbuf, t_u32 index = 0; #endif +#ifdef UAP_SUPPORT +#if defined(UAP_CFG80211) || defined(STA_CFG80211) + struct net_device *dev = NULL; +#endif +#endif + ENTER(); if (pmbuf && pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) { woal_free_mlan_buffer(handle, pmbuf); @@ -1157,6 +1163,15 @@ mlan_status moal_send_packet_complete(t_void *pmoal, pmlan_buffer pmbuf, if (pmbuf) { priv = woal_bss_index_to_priv(pmoal, pmbuf->bss_index); skb = (struct sk_buff *)pmbuf->pdesc; +#ifdef UAP_SUPPORT +#if defined(UAP_CFG80211) || defined(STA_CFG80211) + if (priv && priv->multi_ap_flag && skb) { + dev = skb->dev; + if (dev) + priv = (moal_private *)netdev_priv(dev); + } +#endif +#endif if (priv) { woal_set_trans_start(priv->netdev); if (skb) { @@ -3551,18 +3566,6 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) #ifdef REASSOCIATION wake_up_interruptible( &priv->phandle->reassoc_thread.wait_q); -#endif - } else { -#if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 35) - if (priv->mrvl_rssi_low) { - cfg80211_cqm_rssi_notify( - priv->netdev, - NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, -#if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - 0, -#endif - GFP_KERNEL); - } #endif } } @@ -3589,6 +3592,8 @@ mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent) PRINTM(MMSG, "wlan: Report sched_scan result\n"); woal_report_sched_scan_result(priv); + woal_sched_timeout(50); + woal_bgscan_stop_event(priv); priv->last_event = 0; PRINTM(MEVENT, "Reporting Sched_Scan results\n"); diff --git a/mlinux/moal_sta_cfg80211.c b/mlinux/moal_sta_cfg80211.c index ead7e93..49e91b4 100644 --- a/mlinux/moal_sta_cfg80211.c +++ b/mlinux/moal_sta_cfg80211.c @@ -4297,7 +4297,7 @@ static t_u8 wlan_check_scan_table_ageout(moal_private *priv) return MFALSE; } woal_get_monotonic_time(&t); -#define CFG80211_SCAN_RESULT_AGEOUT 10 +#define CFG80211_SCAN_RESULT_AGEOUT 20 if (t.time_sec > (scan_resp.age_in_secs + CFG80211_SCAN_RESULT_AGEOUT)) { LEAVE(); @@ -6431,6 +6431,9 @@ int woal_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev, #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) t_u8 buf[ETH_ALEN]; #endif + int index = 0; + int j = 0; + struct cfg80211_ssid *match_ssid = NULL; ENTER(); #ifdef UAP_CFG80211 @@ -6461,15 +6464,37 @@ int woal_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev, /** We have pending scan, start bgscan later */ if (priv->phandle->scan_pending_on_block) priv->scan_cfg.start_later = MTRUE; - for (i = 0; i < request->n_match_sets; i++) { - ssid = &request->match_sets[i].ssid; - strncpy(priv->scan_cfg.ssid_list[i].ssid, ssid->ssid, + for (i = 0; i < request->n_ssids; i++) { + ssid = &request->ssids[i]; + strncpy(priv->scan_cfg.ssid_list[index].ssid, ssid->ssid, ssid->ssid_len); - priv->scan_cfg.ssid_list[i].max_len = 0; - PRINTM(MIOCTL, "sched scan: ssid=%s\n", ssid->ssid); + if (ssid->ssid_len) { + priv->scan_cfg.ssid_list[index].max_len = 0; + index++; + } + PRINTM(MCMND, "sched scan: ssid=%s\n", ssid->ssid); } - /** Add broadcast scan, when n_match_sets = 0 */ - if (!request->n_match_sets) + + for (i = 0; i < request->n_match_sets; i++) { + match_ssid = &request->match_sets[i].ssid; + for (j = 0; j < request->n_ssids; j++) { + ssid = &request->ssids[j]; + if (ssid->ssid_len == match_ssid->ssid_len && + !strncmp(ssid->ssid, match_ssid->ssid, + ssid->ssid_len)) + break; + } + if (j == request->n_ssids) { + strncpy(priv->scan_cfg.ssid_list[index].ssid, + match_ssid->ssid, match_ssid->ssid_len); + priv->scan_cfg.ssid_list[index].max_len = + match_ssid->ssid_len; + index++; + } + PRINTM(MCMND, "sched scan: match_ssid=%s\n", match_ssid->ssid); + } + /** Add broadcast scan, when ssid_list is empty */ + if (!index) priv->scan_cfg.ssid_list[0].max_len = 0xff; for (i = 0; i < (int)MIN(WLAN_USER_SCAN_CHAN_MAX, request->n_channels); i++) { @@ -6671,6 +6696,8 @@ int woal_cfg80211_resume(struct wiphy *wiphy) #if KERNEL_VERSION(3, 2, 0) <= CFG80211_VERSION_CODE woal_report_sched_scan_result( handle->priv[i]); + woal_sched_timeout(50); + woal_bgscan_stop_event(handle->priv[i]); #endif handle->priv[i]->last_event = 0; PRINTM(MCMND, @@ -6843,8 +6870,7 @@ int woal_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) PRINTM(MCMND, "<--- Enter woal_cfg80211_suspend --->\n"); 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)) { + if (handle->priv[i]) { if (handle->scan_request) { PRINTM(MIOCTL, "Cancel pending scan in woal_cfg80211_suspend\n"); @@ -9648,10 +9674,11 @@ void woal_host_mlme_disconnect(moal_private *priv, u16 reason_code, u8 *sa) ENTER(); memset(frame_buf, 0, sizeof(frame_buf)); - mgmt->frame_control = (__force __le16)IEEE80211_STYPE_DEAUTH; + mgmt->frame_control = + (__force __le16)cpu_to_le16(IEEE80211_STYPE_DEAUTH); mgmt->duration = 0; mgmt->seq_ctrl = 0; - mgmt->u.deauth.reason_code = (__force __le16)reason_code; + mgmt->u.deauth.reason_code = (__force __le16)cpu_to_le16(reason_code); if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { moal_memcpy_ext(priv->phandle, mgmt->da, broadcast_addr, ETH_ALEN, sizeof(mgmt->da)); diff --git a/mlinux/moal_uap_cfg80211.c b/mlinux/moal_uap_cfg80211.c index efc34bb..607853f 100644 --- a/mlinux/moal_uap_cfg80211.c +++ b/mlinux/moal_uap_cfg80211.c @@ -2646,6 +2646,7 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, #endif moal_private *vlan_priv = NULL; + station_node *vlan_sta_list = NULL; t_u16 aid = 0; ENTER(); @@ -2684,8 +2685,11 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, vlan_priv = (moal_private *)netdev_priv(dev); aid = vlan_priv->vlan_sta_ptr->aid; PRINTM(MCMND, "wlan: Easymesh del Vlan aid=%d\n", aid); - vlan_priv->parent_priv->vlan_sta_list[(aid - 1) % MAX_STA_COUNT] - ->is_valid = MFALSE; + vlan_sta_list = + vlan_priv->parent_priv + ->vlan_sta_list[(aid - 1) % MAX_STA_COUNT]; + if (vlan_sta_list) + vlan_sta_list->is_valid = MFALSE; #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) cfg80211_unregister_netdevice(dev); #else