diff options
author | Sherry Sun <sherry.sun@nxp.com> | 2020-12-02 13:13:23 +0800 |
---|---|---|
committer | Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com> | 2021-04-27 10:41:55 +0000 |
commit | 1599bbb243194dd7bb39ec3fbd7b197cdeb540b2 (patch) | |
tree | a73adb9ebaa1c126b7ca00a772ffe3445d687d01 | |
parent | 086db5a3502bd2a8c99a0d02b828d069183aabbf (diff) |
MLK-25112: net: wireless: nxp: mxm_wifiex: upgrade to mxm5x16215 release
Upgrade to mxm5x16215 verison:
- Updated driver to request pm_qos only in connected state
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Approved-by: yang.tian <yang.tian@nxp.com>
(cherry picked from commit b8d23738835be6e88562f1afd92cca7afb7c6c22)
(cherry picked from commit 0cd055b21e3d06f7fae62984a0ffceda78957a48)
Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>
32 files changed, 1037 insertions, 85 deletions
diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c index 9f1869617a21..027ba589d752 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.c @@ -1896,6 +1896,8 @@ t_void wlan_11h_init(mlan_adapter *adapter) pdfs_test->user_nop_period_sec = 0; pdfs_test->no_channel_change_on_radar = MFALSE; pdfs_test->fixed_new_channel_on_radar = 0; + pdfs_test->cac_restart = 0; + pdfs_test->millisec_dwell_time = 0; adapter->dfs53cfg = adapter->init_para.dfs53cfg; LEAVE(); @@ -2144,6 +2146,17 @@ t_bool wlan_11h_radar_detect_required(mlan_private *priv, t_u8 channel) return required; } +t_s32 wlan_11h_cancel_radar_detect(mlan_private *priv) +{ + t_s32 ret; + HostCmd_DS_CHAN_RPT_REQ chan_rpt_req; + memset(priv->adapter, &chan_rpt_req, 0x00, sizeof(chan_rpt_req)); + ret = wlan_prepare_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST, + HostCmd_ACT_GEN_SET, 0, (t_void *)MNULL, + (t_void *)&chan_rpt_req); + return ret; +} + /** * @brief Perform a radar measurement if required on given channel * @@ -2232,7 +2245,21 @@ t_s32 wlan_11h_issue_radar_detect(mlan_private *priv, priv->adapter->dfs_test_params .user_cac_period_msec; } - + if (priv->adapter->dfs_test_params.cac_restart) { + priv->adapter->dfs_test_params.chan = + chan_rpt_req.chan_desc.chanNum; + if (chan_rpt_req.millisec_dwell_time) + priv->adapter->dfs_test_params + .millisec_dwell_time = + chan_rpt_req.millisec_dwell_time; + else + chan_rpt_req.millisec_dwell_time = + priv->adapter->dfs_test_params + .millisec_dwell_time; + memcpy_ext(priv->adapter, + &priv->adapter->dfs_test_params.bandcfg, + &bandcfg, sizeof(bandcfg), sizeof(bandcfg)); + } PRINTM(MMSG, "11h: issuing DFS Radar check for channel=%d." " Please wait for response...\n", @@ -2598,7 +2625,7 @@ mlan_status wlan_11h_cmdresp_process(mlan_private *priv, priv->adapter->state_dfs.dfs_check_pending = MTRUE; if (resp->params.chan_rpt_req.millisec_dwell_time == 0) { - /* from wlan_11h_ioctl_dfs_cancel_chan_report */ + /* from wlan_11h_ioctl_dfs_chan_report */ priv->adapter->state_dfs.dfs_check_pending = MFALSE; priv->adapter->state_dfs.dfs_check_priv = MNULL; priv->adapter->state_dfs.dfs_check_channel = 0; @@ -2885,6 +2912,7 @@ mlan_status wlan_11h_ioctl_dfs_testing(pmlan_adapter pmadapter, pdfs_test_params->no_channel_change_on_radar; dfs_test->usr_fixed_new_chan = pdfs_test_params->fixed_new_channel_on_radar; + dfs_test->usr_cac_restart = pdfs_test_params->cac_restart; } else { pdfs_test_params->user_cac_period_msec = dfs_test->usr_cac_period_msec; @@ -2894,6 +2922,7 @@ mlan_status wlan_11h_ioctl_dfs_testing(pmlan_adapter pmadapter, dfs_test->usr_no_chan_change; pdfs_test_params->fixed_new_channel_on_radar = dfs_test->usr_fixed_new_chan; + pdfs_test_params->cac_restart = dfs_test->usr_cac_restart; } LEAVE(); @@ -2985,15 +3014,15 @@ mlan_status wlan_11h_ioctl_chan_switch_count(pmlan_adapter pmadapter, } /** - * @brief 802.11h DFS cancel chan report + * @brief 802.11h DFS chan report * * @param priv Pointer to mlan_private * @param pioctl_req Pointer to mlan_ioctl_req * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ -mlan_status wlan_11h_ioctl_dfs_cancel_chan_report(mlan_private *priv, - pmlan_ioctl_req pioctl_req) +mlan_status wlan_11h_ioctl_dfs_chan_report(mlan_private *priv, + pmlan_ioctl_req pioctl_req) { mlan_ds_11h_cfg *ds_11hcfg = MNULL; HostCmd_DS_CHAN_RPT_REQ *chan_rpt_req = MNULL; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.h index 534ffd6a2f90..05766a99bb35 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11h.h @@ -142,6 +142,7 @@ mlan_status wlan_11h_print_event_radar_detected(mlan_private *priv, mlan_event *pevent, t_u8 *radar_chan); +t_s32 wlan_11h_cancel_radar_detect(mlan_private *priv); /** Handler for DFS_TESTING IOCTL */ extern mlan_status wlan_11h_ioctl_dfs_testing(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); @@ -149,9 +150,8 @@ extern mlan_status wlan_11h_ioctl_get_channel_nop_info(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); -extern mlan_status -wlan_11h_ioctl_dfs_cancel_chan_report(mlan_private *priv, - pmlan_ioctl_req pioctl_req); +extern mlan_status wlan_11h_ioctl_dfs_chan_report(mlan_private *priv, + pmlan_ioctl_req pioctl_req); extern mlan_status wlan_11h_ioctl_chan_switch_count(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c index 1997523afb5d..17cd78d02eb0 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_11n_aggr.c @@ -260,6 +260,13 @@ mlan_status wlan_11n_deaggregate_pkt(mlan_private *priv, pmlan_buffer pmbuf) pmbuf->use_count = wlan_11n_get_num_aggrpkts(data, total_pkt_len); + // rx_trace 7 + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf, 7 /*RX_DROP_P3*/); + if (pmadapter->tp_state_drop_point == 7 /*RX_DROP_P3*/) + goto done; + while (total_pkt_len >= hdr_len) { prx_pkt = (RxPacketHdr_t *)data; /* Length will be in network format, change it to host */ @@ -445,7 +452,10 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list, (pmlan_buffer)util_dequeue_list(pmadapter->pmoal_handle, &pra_list->buf_head, MNULL, MNULL); - + /* Collects TP statistics */ + if (pmadapter->tp_state_on && (pkt_size > sizeof(TxPD))) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf_src->pdesc, 3); pra_list->total_pkts--; /* decrement for every PDU taken from the list */ @@ -497,9 +507,18 @@ int wlan_11n_aggregate_pkt(mlan_private *priv, raListTbl *pra_list, pmbuf_aggr->pbuf = data - headroom; tx_param.next_pkt_len = ((pmbuf_src) ? pmbuf_src->data_len + sizeof(TxPD) : 0); + /* Collects TP statistics */ + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting(pmadapter->pmoal_handle, + pmbuf_aggr, 4); - ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, pmbuf_aggr, - &tx_param); + /* Drop Tx packets at drop point 4 */ + if (pmadapter->tp_state_drop_point == 4) { + wlan_write_data_complete(pmadapter, pmbuf_aggr, ret); + goto exit; + } else + ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, + pmbuf_aggr, &tx_param); switch (ret) { #ifdef USB case MLAN_STATUS_PRESOURCE: diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c index ec27a4c3be22..6393ae6045f7 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_cmdevt.c @@ -2344,7 +2344,7 @@ t_void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter, t_u8 flag) MLAN_STATUS_FAILURE); } #endif - if (pmadapter->curr_cmd) { + if (pmadapter->curr_cmd && flag) { pcmd_node = pmadapter->curr_cmd; if (pcmd_node->pioctl_buf) { pioctl_buf = (mlan_ioctl_req *)pcmd_node->pioctl_buf; @@ -2354,10 +2354,8 @@ t_void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter, t_u8 flag) MLAN_STATUS_FAILURE); pcmd_node->pioctl_buf = MNULL; } - if (flag) { - pmadapter->curr_cmd = MNULL; - wlan_insert_cmd_to_free_q(pmadapter, pcmd_node); - } + pmadapter->curr_cmd = MNULL; + wlan_insert_cmd_to_free_q(pmadapter, pcmd_node); } /* Cancel all pending command */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h index 9037910c11a9..e28c17ee3539 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_decl.h @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "210" +#define MLAN_RELEASE_VERSION "215" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -857,6 +857,23 @@ enum { SCAN_MODE_MANUAL = 0, SCAN_MODE_USER, }; +/** max cac time 10 minutes */ +#define MAX_CAC_DWELL_TIME 600000 +/** default cac time 60 seconds */ +#define DEF_CAC_DWELL_TIME 60000 +/** start freq for 5G */ +#define START_FREQ_11A_BAND 5000 +/** DFS state */ +typedef enum _dfs_state_t { + /** Channel can be used, CAC (Channel Availability Check) must be done + before using it */ + DFS_USABLE = 0, + /** Channel is not available, radar was detected */ + DFS_UNAVAILABLE = 1, + /** Channel is Available, CAC is done and is free of radar */ + DFS_AVAILABLE = 2, +} dfs_state_t; + typedef enum _dfs_w53_cfg_t { /** DFS W53 Default Fw Value */ DFS_W53_DEFAULT_FW = 0, @@ -1747,6 +1764,12 @@ typedef struct _mlan_callbacks { mlan_status (*moal_notify_hostcmd_complete)(t_void *pmoal_handle, t_u32 bss_index); #endif + void (*moal_tp_accounting)(t_void *pmoal_handle, t_void *buf, + t_u32 drop_point); + void (*moal_tp_accounting_rx_param)(t_void *pmoal_handle, + unsigned int type, + unsigned int rsvd1); + } mlan_callbacks, *pmlan_callbacks; /** Parameter unchanged, use MLAN default setting */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h index cddbce4154de..2011e2459f07 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_fw.h @@ -3533,6 +3533,29 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_GET_LOG { t_u64 rx_octets_in_ampdu_cnt; /** ampdu delimiter CRC error count */ t_u32 ampdu_delimiter_crc_error_cnt; + /** Rx Stuck Related Info*/ + /** Rx Stuck Issue count */ + t_u32 rx_stuck_issue_cnt[2]; + /** Rx Stuck Recovery count */ + t_u32 rx_stuck_recovery_cnt; + /** Rx Stuck TSF */ + t_u64 rx_stuck_tsf[2]; + /** Tx Watchdog Recovery Related Info */ + /** Tx Watchdog Recovery count */ + t_u32 tx_watchdog_recovery_cnt; + /** Tx Watchdog TSF */ + t_u64 tx_watchdog_tsf[2]; + /** Channel Switch Related Info */ + /** Channel Switch Announcement Sent */ + t_u32 channel_switch_ann_sent; + /** Channel Switch State */ + t_u32 channel_switch_state; + /** Register Class */ + t_u32 reg_class; + /** Channel Number */ + t_u32 channel_number; + /** Channel Switch Mode */ + t_u32 channel_switch_mode; } MLAN_PACK_END HostCmd_DS_802_11_GET_LOG; /* maln wifi rate */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h index caaadb03ca53..2315b2a2b79e 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_ioctl.h @@ -331,6 +331,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_CFP_TABLE = 0x0020007A, MLAN_OID_MISC_RANGE_EXT = 0x0020007B, MLAN_OID_MISC_DOT11MC_UNASSOC_FTM_CFG = 0x0020007C, + MLAN_OID_MISC_TP_STATE = 0x0020007D, }; /** Sub command size */ @@ -1594,6 +1595,29 @@ typedef struct _mlan_ds_get_stats { t_u64 rx_octets_in_ampdu_cnt; /** ampdu delimiter CRC error count */ t_u32 ampdu_delimiter_crc_error_cnt; + /** Rx Stuck Related Info*/ + /** Rx Stuck Issue count */ + t_u32 rx_stuck_issue_cnt[2]; + /** Rx Stuck Recovery count */ + t_u32 rx_stuck_recovery_cnt; + /** Rx Stuck TSF */ + t_u64 rx_stuck_tsf[2]; + /** Tx Watchdog Recovery Related Info */ + /** Tx Watchdog Recovery count */ + t_u32 tx_watchdog_recovery_cnt; + /** Tx Watchdog TSF */ + t_u64 tx_watchdog_tsf[2]; + /** Channel Switch Related Info */ + /** Channel Switch Announcement Sent */ + t_u32 channel_switch_ann_sent; + /** Channel Switch State */ + t_u32 channel_switch_state; + /** Register Class */ + t_u32 reg_class; + /** Channel Number */ + t_u32 channel_number; + /** Channel Switch Mode */ + t_u32 channel_switch_mode; } mlan_ds_get_stats, *pmlan_ds_get_stats; /** Type definition of mlan_ds_uap_stats for MLAN_OID_GET_STATS */ @@ -4077,6 +4101,8 @@ typedef struct _mlan_ds_11h_dfs_testing { /** User-configured fixed channel to change to, 0 to use random channel */ t_u8 usr_fixed_new_chan; + /** User-configured cac restart */ + t_u8 usr_cac_restart; } mlan_ds_11h_dfs_testing, *pmlan_ds_11h_dfs_testing; /** Type definition of mlan_ds_11h_dfs_testing for MLAN_OID_11H_CHAN_NOP_INFO */ @@ -4347,6 +4373,16 @@ typedef struct _mlan_ds_misc_arb_cfg { t_u32 arb_mode; } mlan_ds_misc_arb_cfg; +/** Type definition of mlan_ds_misc_tp_state + * for MLAN_OID_MISC_TP_STATE + */ +typedef struct _mlan_ds_misc_tp_state { + /** TP account mode 0-disable 1-enable */ + t_u32 on; + /** Packet drop point */ + t_u32 drop_point; +} mlan_ds_misc_tp_state; + /** Type definition of mlan_ds_misc_country_code * for MLAN_OID_MISC_COUNTRY_CODE */ @@ -5099,6 +5135,7 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_cfp_tbl cfp; t_u8 range_ext_mode; mlan_ds_misc_dot11mc_unassoc_ftm_cfg dot11mc_unassoc_ftm_cfg; + mlan_ds_misc_tp_state tp_state; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h index 5c4ff7136f11..2e3019f47460 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_main.h @@ -440,9 +440,9 @@ extern t_void (*assert_callback)(t_void *pmoal_handle, t_u32 cond); #define MRVDRV_MAX_CFP_CODE_A 5 /** high rx pending packets */ -#define HIGH_RX_PENDING 100 +#define HIGH_RX_PENDING 1000 /** low rx pending packets */ -#define LOW_RX_PENDING 80 +#define LOW_RX_PENDING 800 /** Default region code */ #define MRVDRV_DEFAULT_REGION_CODE 0x10 @@ -1602,6 +1602,14 @@ typedef struct { t_bool no_channel_change_on_radar; /** user-configured new channel to change to on radar */ t_u8 fixed_new_channel_on_radar; + /** user-configured cac restart */ + t_u8 cac_restart; + /** cac channel */ + t_u8 chan; + /** band cfg */ + Band_Config_t bandcfg; + /** cac time */ + t_u32 millisec_dwell_time; } wlan_dfs_testing_settings_t; /** @@ -2658,6 +2666,10 @@ typedef struct _mlan_adapter { /** authenticator_priv */ pmlan_private authenticator_priv; #endif + /** TP accounting mode 1-enable 0-disable */ + t_u32 tp_state_on; + /** Packet drop point */ + t_u32 tp_state_drop_point; } mlan_adapter, *pmlan_adapter; /** Check if stream 2X2 enabled */ @@ -3362,6 +3374,8 @@ mlan_status wlan_misc_ioctl_range_ext(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); mlan_status wlan_misc_ioctl_arb_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req); +mlan_status wlan_misc_ioctl_tp_state(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req); /* CFP related functions */ /** Region code index table */ extern t_u16 region_code_index[MRVDRV_MAX_REGION_CODE]; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_pcie.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_pcie.c index 7d4977e52c5b..51e55a90b73b 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_pcie.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_pcie.c @@ -1959,21 +1959,35 @@ static mlan_status wlan_pcie_process_recv_data(mlan_adapter *pmadapter) /* send buffer to host (which will free it) */ pmbuf->data_len = rx_len - PCIE_INTF_HEADER_LEN; pmbuf->data_offset += PCIE_INTF_HEADER_LEN; - PRINTM(MINFO, - "RECV DATA: Received packet from FW successfully\n"); - pmadapter->callbacks.moal_spin_lock( - pmadapter->pmoal_handle, - pmadapter->rx_data_queue.plock); - util_enqueue_list_tail(pmadapter->pmoal_handle, - &pmadapter->rx_data_queue, - (pmlan_linked_list)pmbuf, MNULL, - MNULL); - pmadapter->rx_pkts_queued++; - pmadapter->callbacks.moal_spin_unlock( - pmadapter->pmoal_handle, - pmadapter->rx_data_queue.plock); + // rx_trace 5 + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf, + 5 /*RX_DROP_P1*/); + if (pmadapter->tp_state_drop_point == + 5 /*RX_DROP_P1*/) { + pmadapter->ops.data_complete(pmadapter, pmbuf, + ret); + } else { + PRINTM(MINFO, + "RECV DATA: Received packet from FW successfully\n"); + pmadapter->callbacks.moal_spin_lock( + pmadapter->pmoal_handle, + pmadapter->rx_data_queue.plock); + util_enqueue_list_tail( + pmadapter->pmoal_handle, + &pmadapter->rx_data_queue, + (pmlan_linked_list)pmbuf, MNULL, MNULL); + pmadapter->rx_pkts_queued++; + pmadapter->callbacks.moal_tp_accounting_rx_param( + pmadapter->pmoal_handle, 1, + pmadapter->rx_pkts_queued); + pmadapter->callbacks.moal_spin_unlock( + pmadapter->pmoal_handle, + pmadapter->rx_data_queue.plock); - pmadapter->data_received = MTRUE; + pmadapter->data_received = MTRUE; + } /* Create new buffer and attach it to Rx Ring */ pmbuf = wlan_alloc_mlan_buffer(pmadapter, MLAN_RX_DATA_BUF_SIZE, @@ -3463,6 +3477,8 @@ mlan_status wlan_process_pcie_int_status(mlan_adapter *pmadapter) pcie_ireg &= ~pmadapter->pcard_pcie->reg->host_intr_upld_rdy; PRINTM(MINFO, "Rx DATA\n"); + pmadapter->callbacks.moal_tp_accounting_rx_param( + pmadapter->pmoal_handle, 0, 0); ret = wlan_pcie_process_recv_data(pmadapter); if (ret) goto done; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_shim.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_shim.c index 2859aa9e77e9..c5fc7f5085c7 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_shim.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_shim.c @@ -1002,6 +1002,17 @@ rx_process_start: pmadapter->callbacks.moal_spin_unlock( pmadapter->pmoal_handle, pmadapter->rx_data_queue.plock); + + // rx_trace 6 + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf, + 6 /*RX_DROP_P2*/); + if (pmadapter->tp_state_drop_point == 6 /*RX_DROP_P2*/) { + pmadapter->ops.data_complete(pmadapter, pmbuf, ret); + goto rx_process_start; + } + if (pmadapter->delay_task_flag && (pmadapter->rx_pkts_queued < LOW_RX_PENDING)) { PRINTM(MEVENT, "Run\n"); @@ -1082,6 +1093,8 @@ process_start: #if defined(SDIO) || defined(PCIE) if (!IS_USB(pmadapter->card_type)) { if (pmadapter->rx_pkts_queued > HIGH_RX_PENDING) { + pcb->moal_tp_accounting_rx_param( + pmadapter->pmoal_handle, 2, 0); PRINTM(MEVENT, "Pause\n"); pmadapter->delay_task_flag = MTRUE; mlan_queue_rx_work(pmadapter); @@ -1318,10 +1331,22 @@ mlan_status mlan_send_packet(t_void *pmlan_adapter, pmlan_buffer pmbuf) PRINTM(MMSG, "wlan: Send EAPOL pkt to " MACSTR "\n", MAC2STR(pmbuf->pbuf + pmbuf->data_offset)); } - wlan_add_buf_bypass_txqueue(pmadapter, pmbuf); + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf->pdesc, 2); + if (pmadapter->tp_state_drop_point == 2) + return 0; + else + wlan_add_buf_bypass_txqueue(pmadapter, pmbuf); } else { - /* Transmit the packet*/ - wlan_wmm_add_buf_txqueue(pmadapter, pmbuf); + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf->pdesc, 2); + if (pmadapter->tp_state_drop_point == 2) + return 0; + else + /* Transmit the packet*/ + wlan_wmm_add_buf_txqueue(pmadapter, pmbuf); } LEAVE(); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c index 4cd48b815767..a7fee3788925 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_cmdresp.c @@ -593,6 +593,32 @@ static mlan_status wlan_ret_get_log(pmlan_private pmpriv, pget_info->param.stats.amsdu_tx_cnt = pmpriv->amsdu_tx_cnt; pget_info->param.stats.msdu_in_tx_amsdu_cnt = pmpriv->msdu_in_tx_amsdu_cnt; + pget_info->param.stats.rx_stuck_issue_cnt[0] = + wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[0]); + pget_info->param.stats.rx_stuck_issue_cnt[1] = + wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[1]); + pget_info->param.stats.rx_stuck_recovery_cnt = + wlan_le32_to_cpu(pget_log->rx_stuck_recovery_cnt); + pget_info->param.stats.rx_stuck_tsf[0] = + wlan_le64_to_cpu(pget_log->rx_stuck_tsf[0]); + pget_info->param.stats.rx_stuck_tsf[1] = + wlan_le64_to_cpu(pget_log->rx_stuck_tsf[1]); + pget_info->param.stats.tx_watchdog_recovery_cnt = + wlan_le32_to_cpu(pget_log->tx_watchdog_recovery_cnt); + pget_info->param.stats.tx_watchdog_tsf[0] = + wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[0]); + pget_info->param.stats.tx_watchdog_tsf[1] = + wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[1]); + pget_info->param.stats.channel_switch_ann_sent = + wlan_le32_to_cpu(pget_log->channel_switch_ann_sent); + pget_info->param.stats.channel_switch_state = + wlan_le32_to_cpu(pget_log->channel_switch_state); + pget_info->param.stats.reg_class = + wlan_le32_to_cpu(pget_log->reg_class); + pget_info->param.stats.channel_number = + wlan_le32_to_cpu(pget_log->channel_number); + pget_info->param.stats.channel_switch_mode = + wlan_le32_to_cpu(pget_log->channel_switch_mode); if (pmpriv->adapter->getlog_enable) { pget_info->param.stats.tx_frag_cnt = wlan_le32_to_cpu(pget_log->tx_frag_cnt); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c index 6724a17f2742..c565144f04ac 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_sta_ioctl.c @@ -4806,6 +4806,29 @@ mlan_status wlan_misc_ioctl_arb_cfg(pmlan_adapter pmadapter, return ret; } +/** + * @brief Save tp accounting command configurations. + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status wlan_misc_ioctl_tp_state(pmlan_adapter pmadapter, + pmlan_ioctl_req pioctl_req) +{ + mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf; + mlan_status ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + pmadapter->tp_state_on = pmisc->param.tp_state.on; + pmadapter->tp_state_drop_point = pmisc->param.tp_state.drop_point; + + LEAVE(); + return ret; +} + mlan_status wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req) { @@ -5174,6 +5197,9 @@ static mlan_status wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, case MLAN_OID_MISC_RANGE_EXT: status = wlan_misc_ioctl_range_ext(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_TP_STATE: + status = wlan_misc_ioctl_tp_state(pmadapter, pioctl_req); + break; default: if (pioctl_req) pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_txrx.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_txrx.c index caf25708f98d..a8c93d5322db 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_txrx.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_txrx.c @@ -124,9 +124,15 @@ 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 - - ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, pmbuf, - tx_param); + if (pmadapter->tp_state_on) + pmadapter->callbacks.moal_tp_accounting(pmadapter->pmoal_handle, + pmbuf, 4); + if (pmadapter->tp_state_drop_point == 4) + goto done; + else { + ret = pmadapter->ops.host_to_card(priv, MLAN_TYPE_DATA, pmbuf, + tx_param); + } done: switch (ret) { #ifdef USB diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c index 86a6e72d1cff..1f905eb56b33 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_cmdevent.c @@ -3142,6 +3142,32 @@ static mlan_status wlan_uap_ret_get_log(pmlan_private pmpriv, pget_info->param.stats.amsdu_tx_cnt = pmpriv->amsdu_tx_cnt; pget_info->param.stats.msdu_in_tx_amsdu_cnt = pmpriv->msdu_in_tx_amsdu_cnt; + pget_info->param.stats.rx_stuck_issue_cnt[0] = + wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[0]); + pget_info->param.stats.rx_stuck_issue_cnt[1] = + wlan_le32_to_cpu(pget_log->rx_stuck_issue_cnt[1]); + pget_info->param.stats.rx_stuck_recovery_cnt = + wlan_le32_to_cpu(pget_log->rx_stuck_recovery_cnt); + pget_info->param.stats.rx_stuck_tsf[0] = + wlan_le64_to_cpu(pget_log->rx_stuck_tsf[0]); + pget_info->param.stats.rx_stuck_tsf[1] = + wlan_le64_to_cpu(pget_log->rx_stuck_tsf[1]); + pget_info->param.stats.tx_watchdog_recovery_cnt = + wlan_le32_to_cpu(pget_log->tx_watchdog_recovery_cnt); + pget_info->param.stats.tx_watchdog_tsf[0] = + wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[0]); + pget_info->param.stats.tx_watchdog_tsf[1] = + wlan_le64_to_cpu(pget_log->tx_watchdog_tsf[1]); + pget_info->param.stats.channel_switch_ann_sent = + wlan_le32_to_cpu(pget_log->channel_switch_ann_sent); + pget_info->param.stats.channel_switch_state = + wlan_le32_to_cpu(pget_log->channel_switch_state); + pget_info->param.stats.reg_class = + wlan_le32_to_cpu(pget_log->reg_class); + pget_info->param.stats.channel_number = + wlan_le32_to_cpu(pget_log->channel_number); + pget_info->param.stats.channel_switch_mode = + wlan_le32_to_cpu(pget_log->channel_switch_mode); if (pmpriv->adapter->getlog_enable) { pget_info->param.stats.tx_frag_cnt = wlan_le32_to_cpu(pget_log->tx_frag_cnt); @@ -5225,7 +5251,16 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) case EVENT_RADAR_DETECTED: PRINTM_NETINTF(MEVENT, pmpriv); PRINTM(MEVENT, "EVENT: Radar Detected\n"); - + if (pmpriv->adapter->dfs_test_params.cac_restart && + pmpriv->adapter->state_dfs.dfs_check_pending) { + wlan_11h_cancel_radar_detect(pmpriv); + wlan_11h_issue_radar_detect( + pmpriv, MNULL, + pmpriv->adapter->dfs_test_params.chan, + pmpriv->adapter->dfs_test_params.bandcfg); + pevent->event_id = 0; + break; + } /* Send as passthru first, this event can cause other events */ memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE); pevent->bss_index = pmpriv->bss_index; @@ -5291,6 +5326,7 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) case EVENT_CHANNEL_REPORT_RDY: PRINTM_NETINTF(MEVENT, pmpriv); PRINTM(MEVENT, "EVENT: Channel Report Ready\n"); + pmpriv->adapter->dfs_test_params.cac_restart = MFALSE; memset(pmadapter, event_buf, 0x00, MAX_EVENT_SIZE); /* Setup event buffer */ pevent->bss_index = pmpriv->bss_index; @@ -5304,7 +5340,6 @@ mlan_status wlan_ops_uap_process_event(t_void *priv) /* Handle / pass event data, and free buffer */ ret = wlan_11h_handle_event_chanrpt_ready(pmpriv, pevent, &channel); - if (pmpriv->intf_state_11h.is_11h_host) { *((t_u8 *)pevent->event_buf) = pmpriv->adapter->state_dfs.dfs_radar_found; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c index 8de4bd3d08ae..2610627c123b 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_uap_ioctl.c @@ -2175,8 +2175,8 @@ mlan_status wlan_ops_uap_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req) status = wlan_11h_ioctl_get_channel_nop_info( pmadapter, pioctl_req); if (cfg11h->sub_command == MLAN_OID_11H_CHAN_REPORT_REQUEST) - status = wlan_11h_ioctl_dfs_cancel_chan_report( - pmpriv, pioctl_req); + status = wlan_11h_ioctl_dfs_chan_report(pmpriv, + pioctl_req); if (cfg11h->sub_command == MLAN_OID_11H_CHAN_SWITCH_COUNT) status = wlan_11h_ioctl_chan_switch_count(pmadapter, pioctl_req); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_wmm.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_wmm.c index c9200b81672e..f32a16687090 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_wmm.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlan/mlan_wmm.c @@ -1028,6 +1028,7 @@ static int wlan_dequeue_tx_packet(pmlan_adapter pmadapter) t_u8 ra[MLAN_MAC_ADDR_LENGTH]; int tid_del = 0; int tid = 0; + mlan_buffer *pmbuf = MNULL; ENTER(); @@ -1064,6 +1065,33 @@ static int wlan_dequeue_tx_packet(pmlan_adapter pmadapter) } if (ptr->del_ba_count >= DEL_BA_THRESHOLD) wlan_update_del_ba_count(priv, ptr); + if (pmadapter->tp_state_on) { + pmbuf = (pmlan_buffer)util_peek_list( + pmadapter->pmoal_handle, &ptr->buf_head, MNULL, MNULL); + if (pmbuf) { + pmadapter->callbacks.moal_tp_accounting( + pmadapter->pmoal_handle, pmbuf->pdesc, 3); + if (pmadapter->tp_state_drop_point == 3) { + pmbuf = (pmlan_buffer)util_dequeue_list( + pmadapter->pmoal_handle, &ptr->buf_head, + MNULL, MNULL); + PRINTM(MERROR, "Dequeuing the packet %p %p\n", + ptr, pmbuf); + priv->wmm.pkts_queued[ptrindex]--; + util_scalar_decrement(pmadapter->pmoal_handle, + &priv->wmm.tx_pkts_queued, + MNULL, MNULL); + ptr->total_pkts--; + pmadapter->callbacks.moal_spin_unlock( + pmadapter->pmoal_handle, + priv->wmm.ra_list_spinlock); + wlan_write_data_complete(pmadapter, pmbuf, + MLAN_STATUS_SUCCESS); + LEAVE(); + return MLAN_STATUS_SUCCESS; + } + } + } if (!ptr->is_11n_enabled || (ptr->ba_status || ptr->del_ba_count >= DEL_BA_THRESHOLD) #ifdef STA_SUPPORT diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h index 9037910c11a9..e28c17ee3539 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_decl.h @@ -24,7 +24,7 @@ #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "210" +#define MLAN_RELEASE_VERSION "215" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -857,6 +857,23 @@ enum { SCAN_MODE_MANUAL = 0, SCAN_MODE_USER, }; +/** max cac time 10 minutes */ +#define MAX_CAC_DWELL_TIME 600000 +/** default cac time 60 seconds */ +#define DEF_CAC_DWELL_TIME 60000 +/** start freq for 5G */ +#define START_FREQ_11A_BAND 5000 +/** DFS state */ +typedef enum _dfs_state_t { + /** Channel can be used, CAC (Channel Availability Check) must be done + before using it */ + DFS_USABLE = 0, + /** Channel is not available, radar was detected */ + DFS_UNAVAILABLE = 1, + /** Channel is Available, CAC is done and is free of radar */ + DFS_AVAILABLE = 2, +} dfs_state_t; + typedef enum _dfs_w53_cfg_t { /** DFS W53 Default Fw Value */ DFS_W53_DEFAULT_FW = 0, @@ -1747,6 +1764,12 @@ typedef struct _mlan_callbacks { mlan_status (*moal_notify_hostcmd_complete)(t_void *pmoal_handle, t_u32 bss_index); #endif + void (*moal_tp_accounting)(t_void *pmoal_handle, t_void *buf, + t_u32 drop_point); + void (*moal_tp_accounting_rx_param)(t_void *pmoal_handle, + unsigned int type, + unsigned int rsvd1); + } mlan_callbacks, *pmlan_callbacks; /** Parameter unchanged, use MLAN default setting */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h index caaadb03ca53..2315b2a2b79e 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/mlan_ioctl.h @@ -331,6 +331,7 @@ enum _mlan_ioctl_req_id { MLAN_OID_MISC_CFP_TABLE = 0x0020007A, MLAN_OID_MISC_RANGE_EXT = 0x0020007B, MLAN_OID_MISC_DOT11MC_UNASSOC_FTM_CFG = 0x0020007C, + MLAN_OID_MISC_TP_STATE = 0x0020007D, }; /** Sub command size */ @@ -1594,6 +1595,29 @@ typedef struct _mlan_ds_get_stats { t_u64 rx_octets_in_ampdu_cnt; /** ampdu delimiter CRC error count */ t_u32 ampdu_delimiter_crc_error_cnt; + /** Rx Stuck Related Info*/ + /** Rx Stuck Issue count */ + t_u32 rx_stuck_issue_cnt[2]; + /** Rx Stuck Recovery count */ + t_u32 rx_stuck_recovery_cnt; + /** Rx Stuck TSF */ + t_u64 rx_stuck_tsf[2]; + /** Tx Watchdog Recovery Related Info */ + /** Tx Watchdog Recovery count */ + t_u32 tx_watchdog_recovery_cnt; + /** Tx Watchdog TSF */ + t_u64 tx_watchdog_tsf[2]; + /** Channel Switch Related Info */ + /** Channel Switch Announcement Sent */ + t_u32 channel_switch_ann_sent; + /** Channel Switch State */ + t_u32 channel_switch_state; + /** Register Class */ + t_u32 reg_class; + /** Channel Number */ + t_u32 channel_number; + /** Channel Switch Mode */ + t_u32 channel_switch_mode; } mlan_ds_get_stats, *pmlan_ds_get_stats; /** Type definition of mlan_ds_uap_stats for MLAN_OID_GET_STATS */ @@ -4077,6 +4101,8 @@ typedef struct _mlan_ds_11h_dfs_testing { /** User-configured fixed channel to change to, 0 to use random channel */ t_u8 usr_fixed_new_chan; + /** User-configured cac restart */ + t_u8 usr_cac_restart; } mlan_ds_11h_dfs_testing, *pmlan_ds_11h_dfs_testing; /** Type definition of mlan_ds_11h_dfs_testing for MLAN_OID_11H_CHAN_NOP_INFO */ @@ -4347,6 +4373,16 @@ typedef struct _mlan_ds_misc_arb_cfg { t_u32 arb_mode; } mlan_ds_misc_arb_cfg; +/** Type definition of mlan_ds_misc_tp_state + * for MLAN_OID_MISC_TP_STATE + */ +typedef struct _mlan_ds_misc_tp_state { + /** TP account mode 0-disable 1-enable */ + t_u32 on; + /** Packet drop point */ + t_u32 drop_point; +} mlan_ds_misc_tp_state; + /** Type definition of mlan_ds_misc_country_code * for MLAN_OID_MISC_COUNTRY_CODE */ @@ -5099,6 +5135,7 @@ typedef struct _mlan_ds_misc_cfg { mlan_ds_misc_cfp_tbl cfp; t_u8 range_ext_mode; mlan_ds_misc_dot11mc_unassoc_ftm_cfg dot11mc_unassoc_ftm_cfg; + mlan_ds_misc_tp_state tp_state; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c index d262fcd0a4b0..60d229b2abbe 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.c @@ -1,3 +1,4 @@ + /** @file moal_eth_ioctl.c * * @brief This file contains private ioctl functions @@ -10320,7 +10321,7 @@ static int woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, mlan_ioctl_req *req = NULL; mlan_ds_11h_cfg *ds_11hcfg = NULL; int ret = 0; - int data[4] = {0}; + int data[5] = {0}; int user_data_len = 0, header_len = 0; mlan_status status = MLAN_STATUS_SUCCESS; @@ -10347,14 +10348,14 @@ static int woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, /* SET operation */ parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), &user_data_len); - if (user_data_len != 4) { + if (user_data_len != 5) { PRINTM(MERROR, "Invalid number of args!\n"); ret = -EINVAL; goto done; } - if ((unsigned)data[0] > 0xFFFFF) { + if ((unsigned)data[0] > 1800) { PRINTM(MERROR, - "The maximum user CAC is 1048575 msec (17 mins approx).\n"); + "The maximum user CAC is 1800 seconds (30 mins).\n"); ret = -EINVAL; goto done; } @@ -10369,6 +10370,12 @@ static int woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, ret = -EINVAL; goto done; } + if ((unsigned)data[4] != 0 && ((unsigned)data[4] != 1)) { + PRINTM(MERROR, "CAC restart should be 0/1\n"); + ret = -EINVAL; + goto done; + } + ds_11hcfg->param.dfs_testing.usr_cac_period_msec = (t_u32)data[0] * 1000; ds_11hcfg->param.dfs_testing.usr_nop_period_sec = @@ -10376,6 +10383,8 @@ static int woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, ds_11hcfg->param.dfs_testing.usr_no_chan_change = data[2] ? 1 : 0; ds_11hcfg->param.dfs_testing.usr_fixed_new_chan = (t_u8)data[3]; + ds_11hcfg->param.dfs_testing.usr_cac_restart = (t_u8)data[4]; + priv->phandle->cac_restart = (t_u8)data[4]; priv->phandle->cac_period_jiffies = (t_u32)data[0] * HZ / 1000; priv->phandle->usr_nop_period_sec = (t_u16)data[1]; req->action = MLAN_ACT_SET; @@ -10398,6 +10407,7 @@ static int woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, data[1] = ds_11hcfg->param.dfs_testing.usr_nop_period_sec; data[2] = ds_11hcfg->param.dfs_testing.usr_no_chan_change; data[3] = ds_11hcfg->param.dfs_testing.usr_fixed_new_chan; + data[4] = ds_11hcfg->param.dfs_testing.usr_cac_restart; moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data), respbuflen); ret = sizeof(data); @@ -14823,6 +14833,150 @@ done: LEAVE(); return ret; } + +/** + * @brief Timer function for TP state command. + * + * @param data pointer to a buffer + * + * @return N/A + */ +void woal_tp_acnt_timer_func(void *context) +{ + moal_handle *phandle = (moal_handle *)context; + int i = 0; + + if (phandle == NULL) + return; + PRINTM(MDATA, "####### CPU%d: tp acnt timer\n", smp_processor_id()); + /* Tx TP accounting */ + for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) { + phandle->tp_acnt.tx_bytes_rate[i] = + phandle->tp_acnt.tx_bytes[i] - + phandle->tp_acnt.tx_bytes_last[i]; + phandle->tp_acnt.tx_bytes_last[i] = + phandle->tp_acnt.tx_bytes[i]; + } + phandle->tp_acnt.tx_pending = atomic_read(&phandle->tx_pending); + /* Tx Interrupt accounting */ + phandle->tp_acnt.tx_intr_rate = + phandle->tp_acnt.tx_intr_cnt - phandle->tp_acnt.tx_intr_last; + phandle->tp_acnt.tx_intr_last = phandle->tp_acnt.tx_intr_cnt; + + /* Rx TP accounting */ + for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) { + phandle->tp_acnt.rx_bytes_rate[i] = + phandle->tp_acnt.rx_bytes[i] - + phandle->tp_acnt.rx_bytes_last[i]; + phandle->tp_acnt.rx_bytes_last[i] = + phandle->tp_acnt.rx_bytes[i]; + } + phandle->tp_acnt.rx_pending = atomic_read(&phandle->rx_pending); + // Interrupt accounting, RX + phandle->tp_acnt.rx_intr_rate = + phandle->tp_acnt.rx_intr_cnt - phandle->tp_acnt.rx_intr_last; + phandle->tp_acnt.rx_intr_last = phandle->tp_acnt.rx_intr_cnt; + + /* re-arm timer */ + woal_mod_timer(&phandle->tp_acnt.timer, 1000); +} + +/** + * @brief set tp state to mlan + * + * @param priv pointer to moal_private + * + * @return N/A + */ +void woal_set_tp_state(moal_private *priv) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + moal_handle *handle = priv->phandle; + mlan_status status = MLAN_STATUS_SUCCESS; + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) + return; + /* Fill request buffer */ + misc = (mlan_ds_misc_cfg *)req->pbuf; + misc->sub_command = MLAN_OID_MISC_TP_STATE; + req->req_id = MLAN_IOCTL_MISC_CFG; + misc->param.tp_state.on = handle->tp_acnt.on; + misc->param.tp_state.drop_point = handle->tp_acnt.drop_point; + req->action = MLAN_ACT_SET; + /* Send IOCTL request to MLAN */ + status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); + if (status != MLAN_STATUS_PENDING) + kfree(req); + return; +} + +/** + * @brief Set/Get TP statistics. + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int woal_priv_set_tp_state(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen) +{ + moal_handle *handle = priv->phandle; + int ret = 0; + int data[2]; + int header_len = 0, user_data_len = 0; + + ENTER(); + + if (!respbuf) { + PRINTM(MERROR, "response buffer is not available!\n"); + ret = -EINVAL; + goto done; + } + header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TP_STATE); + user_data_len = strlen(respbuf) - header_len; + parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data), + &user_data_len); + if (user_data_len > 2) { + PRINTM(MERROR, "Invalid number of args!\n"); + ret = -EINVAL; + goto done; + } + if (user_data_len) { + handle->tp_acnt.on = data[0]; + /* Enable TP statistics collection */ + if (data[0] == 1) { + handle->tp_acnt.drop_point = data[1]; + if (handle->is_tp_acnt_timer_set == MFALSE) { + woal_initialize_timer(&handle->tp_acnt.timer, + woal_tp_acnt_timer_func, + handle); + handle->is_tp_acnt_timer_set = MTRUE; + woal_mod_timer(&handle->tp_acnt.timer, 1000); + } + } else { + if (handle->is_tp_acnt_timer_set) { + woal_cancel_timer(&handle->tp_acnt.timer); + handle->is_tp_acnt_timer_set = MFALSE; + } + memset((void *)&handle->tp_acnt, 0, + sizeof(moal_tp_acnt_t)); + } + woal_set_tp_state(priv); + } + /* Get command results */ + if (user_data_len == 0) { + moal_memcpy_ext(handle, respbuf, (t_u8 *)(&handle->tp_acnt), + sizeof(handle->tp_acnt), respbuflen); + ret = sizeof(handle->tp_acnt); + } + +done: + LEAVE(); + return ret; +} + /** * @brief Set priv command for Android * @param dev A pointer to net_device structure @@ -15956,6 +16110,12 @@ int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) len = woal_priv_set_get_lpm(priv, buf, priv_cmd.total_len); goto handled; + } else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TP_STATE, + strlen(PRIV_CMD_TP_STATE)) == 0) { + /* Set/Get TP accounting state */ + len = woal_priv_set_tp_state(priv, buf, + priv_cmd.total_len); + goto handled; } else { PRINTM(MERROR, "Unknown NXP PRIVATE command %s, ignored\n", diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h index f27d269d1f17..57b203e833dd 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_eth_ioctl.h @@ -670,4 +670,6 @@ typedef struct { /** chan_list */ wlan_ieee80211_chan chan_list[]; } __ATTRIB_PACK__ wlan_ieee80211_chan_list; + +#define PRIV_CMD_TP_STATE "tp_state" #endif /* _WOAL_ETH_PRIV_H_ */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_init.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_init.c index 077a6614dbc9..bfdc41ba4362 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_init.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_init.c @@ -113,6 +113,7 @@ int shutdown_hs; /** SDIO slew rate */ int slew_rate = 3; #endif +int tx_work = 0; #if defined(STA_SUPPORT) /** 802.11d configuration */ @@ -1077,6 +1078,17 @@ static mlan_status parse_cfg_read_block(t_u8 *data, t_u32 size, PRINTM(MMSG, "napi %s\n", moal_extflg_isset(handle, EXT_NAPI) ? "on" : "off"); + } else if (strncmp(line, "tx_work", strlen("tx_work")) == 0) { + if (parse_line_read_int(line, &out_data) != + MLAN_STATUS_SUCCESS) + goto err; + if (out_data) + moal_extflg_set(handle, EXT_TX_WORK); + else + moal_extflg_clear(handle, EXT_TX_WORK); + PRINTM(MMSG, "tx_work %s\n", + moal_extflg_isset(handle, EXT_TX_WORK) ? "on" : + "off"); } #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) else if (strncmp(line, "dfs_offload", strlen("dfs_offload")) == @@ -1415,6 +1427,9 @@ static void woal_setup_module_param(moal_handle *handle, moal_mod_para *params) } if (napi) moal_extflg_set(handle, EXT_NAPI); + if (tx_work) + moal_extflg_set(handle, EXT_TX_WORK); + #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (dfs_offload) moal_extflg_set(handle, EXT_DFS_OFFLOAD); @@ -1622,6 +1637,12 @@ void woal_init_from_dev_tree(void) } } #endif + else if (!strncmp(prop->name, "tx_work", strlen("tx_work"))) { + if (!of_property_read_u32(dt_node, prop->name, &data)) { + PRINTM(MIOCTL, "tx_work=0x%x\n", data); + tx_work = data; + } + } #ifdef MFG_CMD_SUPPORT else if (!strncmp(prop->name, "mfg_mode", strlen("mfg_mode"))) { if (!of_property_read_u32(dt_node, prop->name, &data)) { @@ -2158,6 +2179,8 @@ MODULE_PARM_DESC( slew_rate, "0:has the slowest slew rate, then 01, then 02, and 03 has the highest slew rate"); #endif +module_param(tx_work, uint, 0660); +MODULE_PARM_DESC(tx_work, "1: Enable tx_work; 0: Disable tx_work"); module_param(dpd_data_cfg, charp, 0); MODULE_PARM_DESC(dpd_data_cfg, "DPD data file name"); module_param(init_cfg, charp, 0); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c index a6df8c052d6d..8cb4af25d096 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_ioctl.c @@ -670,6 +670,8 @@ mlan_status woal_request_ioctl(moal_private *priv, mlan_ioctl_req *req, priv->phandle->cac_period_jiffies - (jiffies - priv->phandle->meas_start_jiffies); } + if (priv->phandle->cac_restart) + cac_left_jiffies = DEF_CAC_DWELL_TIME * HZ / 1000; if (cac_left_jiffies < 0) { /* Avoid driver hang in FW died during CAC measure * period */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.c index a4d5f0b8b919..f7d66598accc 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.c @@ -635,6 +635,8 @@ static mlan_callbacks woal_callbacks = { .moal_wait_hostcmd_complete = moal_wait_hostcmd_complete, .moal_notify_hostcmd_complete = moal_notify_hostcmd_complete, #endif + .moal_tp_accounting = moal_tp_accounting, + .moal_tp_accounting_rx_param = moal_tp_accounting_rx_param, }; int woal_open(struct net_device *dev); @@ -3731,6 +3733,7 @@ moal_private *woal_add_interface(moal_handle *handle, t_u8 bss_index, INIT_LIST_HEAD(&priv->tx_stat_queue); spin_lock_init(&priv->tx_stat_lock); + #ifdef STA_CFG80211 #ifdef STA_SUPPORT spin_lock_init(&priv->connect_lock); @@ -4329,7 +4332,11 @@ void woal_terminate_workqueue(moal_handle *handle) destroy_workqueue(handle->evt_workqueue); handle->evt_workqueue = NULL; } - + if (handle->tx_workqueue) { + flush_workqueue(handle->tx_workqueue); + destroy_workqueue(handle->tx_workqueue); + handle->tx_workqueue = NULL; + } LEAVE(); } @@ -5052,6 +5059,9 @@ void woal_flush_tx_stat_queue(moal_private *priv) } INIT_LIST_HEAD(&priv->tx_stat_queue); spin_unlock_irqrestore(&priv->tx_stat_lock, flags); + spin_lock_bh(&(priv->tx_q.lock)); + __skb_queue_purge(&priv->tx_q); + spin_unlock_bh(&(priv->tx_q.lock)); } /** @@ -5421,9 +5431,8 @@ done: * * @return 0 --success */ -netdev_tx_t woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +int woal_start_xmit(moal_private *priv, struct sk_buff *skb) { - moal_private *priv = (moal_private *)netdev_priv(dev); mlan_buffer *pmbuf = NULL; mlan_status status; struct sk_buff *new_skb = NULL; @@ -5433,14 +5442,7 @@ netdev_tx_t woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) int ret = 0; ENTER(); - PRINTM(MDATA, "%lu : %s (bss=%d): Data <= kernel\n", jiffies, dev->name, - priv->bss_index); - if (priv->phandle->surprise_removed == MTRUE) { - dev_kfree_skb_any(skb); - priv->stats.tx_dropped++; - goto done; - } priv->num_tx_timeout = 0; if (!skb->len || (skb->len > ETH_FRAME_LEN)) { PRINTM(MERROR, "Tx Error: Bad skb length %d : %d\n", skb->len, @@ -5530,6 +5532,50 @@ done: } /** + * @brief This function handles packet transmission + * + * @param skb A pointer to sk_buff structure + * @param dev A pointer to net_device structure + * + * @return 0 --success + */ +netdev_tx_t woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + moal_private *priv = (moal_private *)netdev_priv(dev); + ENTER(); + PRINTM(MDATA, "%lu : %s (bss=%d): Data <= kernel\n", jiffies, dev->name, + priv->bss_index); + + /* Collect TP statistics */ + if (priv->phandle->tp_acnt.on) + moal_tp_accounting(priv->phandle, skb, 1); + /* Drop Tx packets at drop point 1 */ + if (priv->phandle->tp_acnt.drop_point == 1) { + dev_kfree_skb_any(skb); + LEAVE(); + return 0; + } + if (priv->phandle->surprise_removed == MTRUE) { + dev_kfree_skb_any(skb); + priv->stats.tx_dropped++; + goto done; + } + if (moal_extflg_isset(priv->phandle, EXT_TX_WORK)) { + spin_lock_bh(&(priv->tx_q.lock)); + __skb_queue_tail(&(priv->tx_q), skb); + spin_unlock_bh(&(priv->tx_q.lock)); + + queue_work(priv->phandle->tx_workqueue, + &priv->phandle->tx_work); + goto done; + } + woal_start_xmit(priv, skb); +done: + LEAVE(); + return 0; +} + +/** * @brief Convert ascii string to Hex integer * * @param d A pointer to integer buf @@ -5793,6 +5839,7 @@ void woal_init_priv(moal_private *priv, t_u8 wait_option) } #endif + skb_queue_head_init(&priv->tx_q); memset(&priv->tx_protocols, 0, sizeof(dot11_protocol)); memset(&priv->rx_protocols, 0, sizeof(dot11_protocol)); priv->media_connected = MFALSE; @@ -8248,6 +8295,54 @@ t_void woal_rx_work_queue(struct work_struct *work) } /** + * @brief This function dequeue pkt from list + * + * @param list A pointer to struct sk_buff_head + * + * @return skb buffer + */ + +struct sk_buff *woal_skb_dequeue_spinlock(struct sk_buff_head *list) +{ + struct sk_buff *result; + + spin_lock_bh(&list->lock); + result = __skb_dequeue(list); + spin_unlock_bh(&list->lock); + return result; +} + +/** + * @brief This workqueue function handles rx_work_process + * + * @param work A pointer to work_struct + * + * @return N/A + */ +t_void woal_tx_work_handler(struct work_struct *work) +{ + moal_handle *handle = container_of(work, moal_handle, tx_work); + moal_private *priv = NULL; + int i = 0; + struct sk_buff *skb = NULL; + + ENTER(); + if (handle->surprise_removed == MTRUE) { + LEAVE(); + return; + } + + for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { + priv = handle->priv[i]; + while ((skb = woal_skb_dequeue_spinlock(&priv->tx_q)) != NULL) { + woal_start_xmit(priv, skb); + } + } + + LEAVE(); +} + +/** * @brief This workqueue function handles main_process * * @param work A pointer to work_struct @@ -8535,6 +8630,26 @@ moal_handle *woal_add_card(void *card, struct device *dev, moal_if_ops *if_ops, napi_enable(&handle->napi_rx); } + if (moal_extflg_isset(handle, EXT_TX_WORK)) { + /* Create workqueue for tx process */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) + handle->tx_workqueue = create_workqueue("MOAL_TX_WORKQ"); +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + handle->tx_workqueue = alloc_workqueue( + "MOAL_TX_WORK_QUEUE", + WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); +#else + handle->tx_workqueue = create_workqueue("MOAL_TX_WORK_QUEUE"); +#endif +#endif + if (!handle->tx_workqueue) { + woal_terminate_workqueue(handle); + goto err_kmalloc; + } + MLAN_INIT_WORK(&handle->tx_work, woal_tx_work_handler); + } + #ifdef REASSOCIATION PRINTM(MINFO, "Starting re-association thread...\n"); handle->reassoc_thread.handle = handle; @@ -8676,6 +8791,8 @@ mlan_status woal_remove_card(void *card) flush_workqueue(handle->evt_workqueue); if (handle->rx_workqueue) flush_workqueue(handle->rx_workqueue); + if (handle->tx_workqueue) + flush_workqueue(handle->tx_workqueue); if (moal_extflg_isset(handle, EXT_NAPI)) { napi_disable(&handle->napi_rx); @@ -8741,6 +8858,15 @@ mlan_status woal_remove_card(void *card) #endif #endif #endif + if (handle->tp_acnt.on) { + handle->tp_acnt.on = 0; + handle->tp_acnt.drop_point = 0; + if (handle->is_tp_acnt_timer_set) { + woal_cancel_timer(&handle->tp_acnt.timer); + handle->is_tp_acnt_timer_set = MFALSE; + } + } + /* Remove interface */ for (i = 0; i < MIN(MLAN_MAX_BSS_NUM, handle->priv_num); i++) woal_remove_interface(handle, i); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h index 8421ae6ec39f..5f9a2956b274 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_main.h @@ -1392,6 +1392,7 @@ struct _moal_private { #if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 29) atomic_t wmm_tx_pending[4]; #endif + struct sk_buff_head tx_q; /** per interface extra headroom */ t_u16 extra_tx_head_len; /** TX status spin lock */ @@ -1552,6 +1553,7 @@ enum ext_mod_params { EXT_HOST_MLME, #endif #endif + EXT_TX_WORK, EXT_MAX_PARAM, }; @@ -1640,6 +1642,46 @@ typedef struct _moal_mod_para { int dfs53cfg; } moal_mod_para; +void woal_tp_acnt_timer_func(void *context); +void woal_set_tp_state(moal_private *priv); +#define MAX_TP_ACCOUNT_DROP_POINT_NUM 5 +#define RX_DROP_P1 (MAX_TP_ACCOUNT_DROP_POINT_NUM) +#define RX_DROP_P2 (MAX_TP_ACCOUNT_DROP_POINT_NUM + 1) +#define RX_DROP_P3 (MAX_TP_ACCOUNT_DROP_POINT_NUM + 2) +#define RX_DROP_P4 (MAX_TP_ACCOUNT_DROP_POINT_NUM + 3) +#define RX_DROP_P5 (MAX_TP_ACCOUNT_DROP_POINT_NUM + 4) +typedef struct _moal_tp_acnt_t { + /* TX accounting */ + unsigned long tx_packets[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_packets_last[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_packets_rate[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_bytes[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_bytes_last[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_bytes_rate[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long tx_intr_cnt; + unsigned long tx_intr_last; + unsigned long tx_intr_rate; + unsigned long tx_pending; + /** RX accounting */ + unsigned long rx_packets[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_packets_last[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_packets_rate[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_bytes[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_bytes_last[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_bytes_rate[MAX_TP_ACCOUNT_DROP_POINT_NUM]; + unsigned long rx_intr_cnt; + unsigned long rx_intr_last; + unsigned long rx_intr_rate; + unsigned long rx_pending; + unsigned long rx_paused_cnt; + /* TP account mode 0-disable 1-enable */ + unsigned int on; + /* drop point */ + unsigned int drop_point; + /* periodic timer */ + moal_drv_timer timer; +} moal_tp_acnt_t; + /** Handle data structure for MOAL */ struct _moal_handle { /** MLAN adapter structure */ @@ -1778,6 +1820,10 @@ struct _moal_handle { spinlock_t evt_lock; /** event queue */ struct list_head evt_queue; + /** tx workqueue */ + struct workqueue_struct *tx_workqueue; + /** tx work */ + struct work_struct tx_work; /** remain on channel flag */ t_u8 remain_on_channel; /** bss index for remain on channel */ @@ -1870,6 +1916,8 @@ struct _moal_handle { #endif /** cac period length, valid only when dfs testing is enabled */ long cac_period_jiffies; + /** cac restart*/ + t_u8 cac_restart; /** handle index - for multiple card supports */ t_u8 handle_idx; #if defined(USB) @@ -1987,6 +2035,11 @@ struct _moal_handle { t_u8 rf_test_mode; /** pointer to rf test mode data struct */ struct rf_test_mode_data *rf_data; + /** TP accounting parameters */ + moal_tp_acnt_t tp_acnt; + BOOLEAN is_tp_acnt_timer_set; + + t_u8 request_pm; }; /** diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c index 95364ff20ffb..d2818d4e60e6 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.c @@ -37,11 +37,11 @@ Change log: #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) #include <linux/busfreq-imx.h> #endif + /******************************************************** Local Variables ********************************************************/ #define DRV_NAME "NXP mdriver PCIe" - #if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) static struct pm_qos_request woal_pcie_pm_qos_req; @@ -121,6 +121,8 @@ static const struct pci_device_id wlan_ids[] = { /* moal interface ops */ static moal_if_ops pcie_ops; +MODULE_DEVICE_TABLE(pci, wlan_ids); + /******************************************************** Global Variables ********************************************************/ @@ -128,6 +130,33 @@ static moal_if_ops pcie_ops; /******************************************************** Local Functions ********************************************************/ + +void woal_request_pmqos_busfreq_high() +{ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + pm_qos_add_request(&woal_pcie_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) + request_bus_freq(BUS_FREQ_HIGH); +#endif +} + +void woal_release_pmqos_busfreq_high() +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) + release_bus_freq(BUS_FREQ_HIGH); +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + pm_qos_remove_request(&woal_pcie_pm_qos_req); +#endif +#endif +} + static mlan_status woal_pcie_preinit(struct pci_dev *pdev); /** @brief This function updates the card types @@ -572,6 +601,8 @@ static int woal_pcie_suspend(struct pci_dev *pdev, pm_message_t state) flush_workqueue(handle->evt_workqueue); if (handle->rx_workqueue) flush_workqueue(handle->rx_workqueue); + if (handle->tx_workqueue) + flush_workqueue(handle->tx_workqueue); pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); pci_save_state(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); @@ -1348,23 +1379,9 @@ mlan_status woal_pcie_bus_register(void) mlan_status ret = MLAN_STATUS_SUCCESS; ENTER(); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - pm_qos_add_request(&woal_pcie_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) - request_bus_freq(BUS_FREQ_HIGH); -#endif /* API registers the NXP PCIE driver */ if (pci_register_driver(&wlan_pcie)) { PRINTM(MFATAL, "PCIE Driver Registration Failed \n"); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - pm_qos_remove_request(&woal_pcie_pm_qos_req); -#endif -#endif ret = MLAN_STATUS_FAILURE; } @@ -1381,16 +1398,8 @@ void woal_pcie_bus_unregister(void) { ENTER(); -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70) - release_bus_freq(BUS_FREQ_HIGH); -#endif /* PCIE Driver Unregistration */ pci_unregister_driver(&wlan_pcie); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - pm_qos_remove_request(&woal_pcie_pm_qos_req); -#endif -#endif LEAVE(); } diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.h index ae22f4d01341..1f3fd7196b83 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_pcie.h @@ -139,4 +139,10 @@ typedef struct _pcie_service_card { mlan_status woal_pcie_bus_register(void); /** Unregister from bus driver function */ void woal_pcie_bus_unregister(void); + +/* pmqos busfreq request handler*/ +void woal_request_pmqos_busfreq_high(void); +/* pmqos busfreq release handler*/ +void woal_release_pmqos_busfreq_high(void); + #endif /* _MOAL_PCIE_H_ */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_proc.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_proc.c index 1d1898c32b05..d60ae7f64b4d 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_proc.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_proc.c @@ -270,6 +270,56 @@ static int woal_info_proc_read(struct seq_file *sfp, void *data) ustats.rsna_4way_hshk_failures); } #endif /* UAP_SUPPORT */ + seq_printf(sfp, "=== tp_acnt.on:%d drop_point:%d ===\n", + handle->tp_acnt.on, handle->tp_acnt.drop_point); + seq_printf(sfp, "====Tx accounting====\n"); + for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) { + seq_printf(sfp, "[%d] Tx packets : %lu\n", i, + handle->tp_acnt.tx_packets[i]); + seq_printf(sfp, "[%d] Tx packets last: %lu\n", i, + handle->tp_acnt.tx_packets_last[i]); + seq_printf(sfp, "[%d] Tx packets rate: %lu\n", i, + handle->tp_acnt.tx_packets_rate[i]); + seq_printf(sfp, "[%d] Tx bytes : %lu\n", i, + handle->tp_acnt.tx_bytes[i]); + seq_printf(sfp, "[%d] Tx bytes last : %lu\n", i, + handle->tp_acnt.tx_bytes_last[i]); + seq_printf(sfp, "[%d] Tx bytes rate : %luMbps\n", i, + handle->tp_acnt.tx_bytes_rate[i] * 8 / 1024 / 1024); + } + seq_printf(sfp, "Tx intr cnt : %lu\n", + handle->tp_acnt.tx_intr_cnt); + seq_printf(sfp, "Tx intr last : %lu\n", + handle->tp_acnt.tx_intr_last); + seq_printf(sfp, "Tx intr rate : %lu\n", + handle->tp_acnt.tx_intr_rate); + seq_printf(sfp, "Tx pending : %lu\n", + handle->tp_acnt.tx_pending); + seq_printf(sfp, "====Rx accounting====\n"); + for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) { + seq_printf(sfp, "[%d] Rx packets : %lu\n", i, + handle->tp_acnt.rx_packets[i]); + seq_printf(sfp, "[%d] Rx packets last: %lu\n", i, + handle->tp_acnt.rx_packets_last[i]); + seq_printf(sfp, "[%d] Rx packets rate: %lu\n", i, + handle->tp_acnt.rx_packets_rate[i]); + seq_printf(sfp, "[%d] Rx bytes : %lu\n", i, + handle->tp_acnt.rx_bytes[i]); + seq_printf(sfp, "[%d] Rx bytes last : %lu\n", i, + handle->tp_acnt.rx_bytes_last[i]); + seq_printf(sfp, "[%d] Rx bytes rate : %luMbps\n", i, + handle->tp_acnt.rx_bytes_rate[i] * 8 / 1024 / 1024); + } + seq_printf(sfp, "Rx intr cnt : %lu\n", + handle->tp_acnt.rx_intr_cnt); + seq_printf(sfp, "Rx intr last : %lu\n", + handle->tp_acnt.rx_intr_last); + seq_printf(sfp, "Rx intr rate : %lu\n", + handle->tp_acnt.rx_intr_rate); + seq_printf(sfp, "Rx pending : %lu\n", + handle->tp_acnt.rx_pending); + seq_printf(sfp, "Rx pause : %lu\n", + handle->tp_acnt.rx_paused_cnt); exit: LEAVE(); MODULE_PUT; @@ -482,6 +532,33 @@ static ssize_t woal_config_write(struct file *f, const char __user *buf, PRINTM(MMSG, "Request fw_reload=%d\n", config_data); woal_request_fw_reload(handle, config_data); } + if (!strncmp(databuf, "drop_point=", strlen("drop_point="))) { + line += strlen("drop_point") + 1; + config_data = (t_u32)woal_string_to_number(line); + if (config_data) { + handle->tp_acnt.on = 1; + handle->tp_acnt.drop_point = config_data; + if (handle->is_tp_acnt_timer_set == MFALSE) { + woal_initialize_timer(&handle->tp_acnt.timer, + woal_tp_acnt_timer_func, + handle); + handle->is_tp_acnt_timer_set = MTRUE; + woal_mod_timer(&handle->tp_acnt.timer, 1000); + } + } else { + if (handle->is_tp_acnt_timer_set) { + woal_cancel_timer(&handle->tp_acnt.timer); + handle->is_tp_acnt_timer_set = MFALSE; + } + memset((void *)&handle->tp_acnt, 0, + sizeof(moal_tp_acnt_t)); + } + priv = woal_get_priv(handle, MLAN_BSS_ROLE_ANY); + if (priv) + woal_set_tp_state(priv); + PRINTM(MMSG, "on=%d drop_point=%d\n", handle->tp_acnt.on, + handle->tp_acnt.drop_point); + } if (!strncmp(databuf, "rf_test_mode", strlen("rf_test_mode"))) { line += strlen("rf_test_mode") + 1; config_data = (t_u32)woal_string_to_number(line); diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c index 4312b452f689..84fea5611671 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c @@ -111,6 +111,8 @@ static const struct sdio_device_id wlan_ids[] = { {}, }; +MODULE_DEVICE_TABLE(sdio, wlan_ids); + int woal_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id); void woal_sdio_remove(struct sdio_func *func); #ifdef SDIO diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c index 2effd85a4238..ff3b593e9c1c 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.c @@ -615,6 +615,68 @@ mlan_status moal_spin_lock(t_void *pmoal_handle, t_void *plock) } /** + * @brief This function collects TP statistics. + * + * @param pmoal_handle Pointer to the MOAL context + * @param buf pointer to the buffer of a packet + * @param drop_point Drop pointer user set + * + * @return N/A + */ +void moal_tp_accounting(t_void *pmoal_handle, void *buf, t_u32 drop_point) +{ + struct sk_buff *skb = NULL; + moal_handle *handle = (moal_handle *)pmoal_handle; + pmlan_buffer pmbuf = (pmlan_buffer)buf; + + if (drop_point < MAX_TP_ACCOUNT_DROP_POINT_NUM) { + if (drop_point == 4) { + handle->tp_acnt.tx_bytes[drop_point] += pmbuf->data_len; + } else { + skb = (struct sk_buff *)buf; + handle->tp_acnt.tx_bytes[drop_point] += skb->len; + } + handle->tp_acnt.tx_packets[drop_point]++; + } else if (drop_point <= RX_DROP_P5) { + t_u16 rx_len = 0; + if (drop_point == RX_DROP_P1 || drop_point == RX_DROP_P2) + rx_len = pmbuf->data_len - + *((t_u16 *)(pmbuf->pbuf + pmbuf->data_offset) + + 2); // remove rx_pkt_offset + else if (drop_point == RX_DROP_P3) // aggr pkt + rx_len = pmbuf->data_len; + else if (drop_point == RX_DROP_P4) { // before to kernel + skb = (struct sk_buff *)buf; + rx_len = skb->len; + } + handle->tp_acnt + .rx_bytes[drop_point - MAX_TP_ACCOUNT_DROP_POINT_NUM] += + rx_len; + handle->tp_acnt.rx_packets[drop_point - + MAX_TP_ACCOUNT_DROP_POINT_NUM]++; + } +} + +void moal_tp_accounting_rx_param(t_void *pmoal_handle, unsigned int type, + unsigned int rsvd1) +{ + moal_handle *phandle = (moal_handle *)pmoal_handle; + switch (type) { + case 0: // Rx interrupt + phandle->tp_acnt.rx_intr_cnt++; + break; + case 1: // rx_pkts_queued + phandle->tp_acnt.rx_pending = rsvd1; + break; + case 2: // paused + phandle->tp_acnt.rx_paused_cnt++; + break; + default: + break; + } +} + +/** * @brief Request a spin_unlock * * @param pmoal_handle Pointer to the MOAL context @@ -1357,8 +1419,13 @@ mlan_status moal_recv_packet(t_void *pmoal_handle, pmlan_buffer pmbuf) sizeof(dot11_rxcontrol), sizeof(dot11_rxcontrol)); } - - if (in_interrupt()) + // rx_trace 8 + if (priv->phandle->tp_acnt.on) + moal_tp_accounting(handle, skb, RX_DROP_P4); + if (priv->phandle->tp_acnt.drop_point == RX_DROP_P4) { + status = MLAN_STATUS_PENDING; + dev_kfree_skb(skb); + } else if (in_interrupt()) netif_rx(skb); else { if (atomic_read(&handle->rx_pending) > @@ -1375,6 +1442,56 @@ done: } /** + * @brief This function checks media_connected state for + * BSS types UAP/STA/P2P_GO/GC + * + * @param pmoal_handle Pointer to the MOAL context + * + */ +int woal_check_media_connected(t_void *pmoal_handle) +{ + int i; + moal_handle *pmhandle = (moal_handle *)pmoal_handle; + moal_private *pmpriv = NULL; + for (i = 0; i < pmhandle->priv_num && (pmpriv = pmhandle->priv[i]); + i++) { + if ((pmpriv->media_connected == MTRUE)) { + return MTRUE; + } + } + return MFALSE; +} + +/** + * @brief This function checks connect and disconnect + * events for BSS types UAP/STA/P2P_GO/GC + * + * @param pmoal_handle Pointer to the MOAL context + * + */ +void moal_connection_status_check_pmqos(t_void *pmoal_handle) +{ + moal_handle *pmhandle = (moal_handle *)pmoal_handle; + if ((woal_check_media_connected(pmoal_handle) == MTRUE)) { + if ((pmhandle->request_pm == MFALSE)) { + pmhandle->request_pm = MTRUE; +#ifdef PCIE + if (IS_PCIE(pmhandle->card_type)) + woal_request_pmqos_busfreq_high(); +#endif + } + } else { + if (pmhandle->request_pm == MTRUE) { + pmhandle->request_pm = MFALSE; +#ifdef PCIE + if (IS_PCIE(pmhandle->card_type)) + woal_release_pmqos_busfreq_high(); +#endif + } + } +} + +/** * @brief This function handles event receive * * @param pmoal_handle Pointer to the MOAL context @@ -1511,7 +1628,7 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); woal_wake_queue(priv->netdev); - + moal_connection_status_check_pmqos(pmoal_handle); break; case MLAN_EVENT_ID_DRV_ASSOC_SUCC_LOGGER: @@ -1680,6 +1797,7 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) priv->rate_index = AUTO_RATE; } #endif /* REASSOCIATION */ + moal_connection_status_check_pmqos(pmoal_handle); break; case MLAN_EVENT_ID_FW_MIC_ERR_UNI: @@ -2384,11 +2502,13 @@ mlan_status moal_recv_event(t_void *pmoal_handle, pmlan_event pmevent) woal_wake_queue(priv->netdev); woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len); + moal_connection_status_check_pmqos(pmoal_handle); break; case MLAN_EVENT_ID_UAP_FW_BSS_IDLE: priv->media_connected = MFALSE; woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len); + moal_connection_status_check_pmqos(pmoal_handle); break; case MLAN_EVENT_ID_UAP_FW_MIC_COUNTERMEASURES: { t_u16 status = 0; diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.h index e692a083095a..ddcf9c075c8e 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_shim.h @@ -116,5 +116,7 @@ mlan_status moal_free_timer(t_void *pmoal_handle, t_void *ptimer); mlan_status moal_start_timer(t_void *pmoal_handle, t_void *ptimer, t_u8 periodic, t_u32 msec); mlan_status moal_stop_timer(t_void *pmoal_handle, t_void *ptimer); - +void moal_tp_accounting(t_void *pmoal_handle, void *buf, t_u32 drop_point); +void moal_tp_accounting_rx_param(t_void *pmoal_handle, unsigned int type, + unsigned int rsvd1); #endif /*_MOAL_H */ diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.c b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.c index a1d30c32adcd..34e66cf8321a 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.c +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.c @@ -1009,6 +1009,8 @@ static int woal_uap_dfs_testing(struct net_device *dev, struct ifreq *req) param.no_chan_change; cfg11h->param.dfs_testing.usr_fixed_new_chan = param.fixed_new_chan; + cfg11h->param.dfs_testing.usr_cac_restart = param.cac_restart; + priv->phandle->cac_restart = param.cac_restart; priv->phandle->cac_period_jiffies = param.usr_cac_period * HZ / 1000; priv->user_cac_period_msec = @@ -1029,6 +1031,7 @@ static int woal_uap_dfs_testing(struct net_device *dev, struct ifreq *req) cfg11h->param.dfs_testing.usr_no_chan_change; param.fixed_new_chan = cfg11h->param.dfs_testing.usr_fixed_new_chan; + param.cac_restart = cfg11h->param.dfs_testing.usr_cac_restart; } /* Copy to user */ if (copy_to_user(req->ifr_data, ¶m, sizeof(param))) { diff --git a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.h b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.h index d8182c1561b3..b60dfefeed02 100644 --- a/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.h +++ b/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_uap.h @@ -495,6 +495,8 @@ typedef struct _dfs_testing_param { t_u8 no_chan_change; /** fixed channel to change to on radar */ t_u8 fixed_new_chan; + /** CAC restart */ + t_u8 cac_restart; } dfs_testing_para; /** Channel switch count config */ |