From 26cfe7eb284af14715df40f36f87778cc8fb8284 Mon Sep 17 00:00:00 2001 From: Himanshu Agarwal Date: Mon, 8 May 2017 15:01:07 +0530 Subject: [PATCH 01/26] qcacmn: Reduce log level of DPTRACE prints to DEBUG Presently log level of DPTRACE prints is INFO due to which they are coming in kmsg and causing watchdog bite. Reduce log level of DPTRACE prints from INFO to DEBUG. Change-Id: I0124dcc461d3e05541267c8310a43ea3ce0de9af CRs-Fixed: 2043719 --- qdf/linux/src/qdf_trace.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index 5981d04147..9e910463aa 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -927,7 +927,7 @@ void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir) EXPORT_SYMBOL(qdf_dp_trace_set_track); #if CONFIG_MCL #define DPTRACE_PRINT(args...) \ - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, ## args) + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, ## args) #else #define DPTRACE_PRINT(args...) \ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_NONE, ## args) @@ -1702,15 +1702,13 @@ void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id) int32_t i, tail; if (!g_qdf_dp_trace_data.enable) { - QDF_TRACE(QDF_MODULE_ID_SYS, - QDF_TRACE_LEVEL_ERROR, "Tracing Disabled"); + DPTRACE_PRINT("Tracing Disabled"); return; } - QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR, - "Total Records: %d, Head: %d, Tail: %d", - g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head, - g_qdf_dp_trace_data.tail); + DPTRACE_PRINT("Total Records: %d, Head: %d, Tail: %d", + g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head, + g_qdf_dp_trace_data.tail); /* aquire the lock so that only one thread at a time can read * the ring buffer From 1312d700b5827e61132ee2461294a14f64f356e5 Mon Sep 17 00:00:00 2001 From: Vivek Date: Mon, 12 Jun 2017 18:57:51 +0530 Subject: [PATCH 02/26] qcacmn: Add debug prints when logically deleting an object Add prints for all the references held by the components, for an object, when the object is logically deleted. The prints will be enabled only when the log level is set to Debug. Change-Id: If0a5b97a5e250fe1e5058611026c3c7ae8500359 CRs-Fixed: 2059750 --- .../obj_mgr/src/wlan_objmgr_pdev_obj.c | 11 +++++++++++ .../obj_mgr/src/wlan_objmgr_peer_obj.c | 18 ++++++++++++++++++ .../obj_mgr/src/wlan_objmgr_psoc_obj.c | 11 +++++++++++ .../obj_mgr/src/wlan_objmgr_vdev_obj.c | 11 +++++++++++ 4 files changed, 51 insertions(+) diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c index 67a0a1c1cf..b00cf1c533 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c @@ -221,10 +221,21 @@ static QDF_STATUS wlan_objmgr_pdev_obj_destroy(struct wlan_objmgr_pdev *pdev) QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev) { + uint8_t print_idx; + if (pdev == NULL) { obj_mgr_err("pdev is NULL"); return QDF_STATUS_E_FAILURE; } + + print_idx = qdf_get_pidx(); + if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, + QDF_TRACE_LEVEL_DEBUG)) { + obj_mgr_debug("Logically deleting the pdev(id:%d)", + pdev->pdev_objmgr.wlan_pdev_id); + wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg); + } + /* * Update PDEV object state to LOGICALLY DELETED * It prevents further access of this object diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c index c59760accd..28dfdc0078 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c @@ -289,11 +289,29 @@ static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer) QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer) { + uint8_t print_idx; + uint8_t *macaddr; + if (peer == NULL) { obj_mgr_err("PEER is NULL"); return QDF_STATUS_E_FAILURE; } + wlan_peer_obj_lock(peer); + macaddr = wlan_peer_get_macaddr(peer); + wlan_peer_obj_unlock(peer); + + + print_idx = qdf_get_pidx(); + if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, + QDF_TRACE_LEVEL_DEBUG)) { + obj_mgr_debug("Logically deleting the peer" + "(%02x:%02x:%02x:%02x:%02x:%02x)", + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg); + } + /** * Update VDEV object state to LOGICALLY DELETED * It prevents further access of this object diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c index 8f99154e62..05d8b78341 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c @@ -235,10 +235,21 @@ static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc) QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc) { + uint8_t print_idx; + if (psoc == NULL) { obj_mgr_err("psoc is NULL"); return QDF_STATUS_E_FAILURE; } + + print_idx = qdf_get_pidx(); + + if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, + QDF_TRACE_LEVEL_DEBUG)) { + obj_mgr_debug("Logically deleting the psoc"); + wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg); + } + /* * Update PSOC object state to LOGICALLY DELETED * It prevents further access of this object diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index 0e07247c0d..63a341c5f9 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -276,10 +276,21 @@ static QDF_STATUS wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev *vdev) QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev) { + uint8_t print_idx; + if (vdev == NULL) { obj_mgr_err("vdev is NULL"); return QDF_STATUS_E_FAILURE; } + + print_idx = qdf_get_pidx(); + if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, + QDF_TRACE_LEVEL_DEBUG)) { + obj_mgr_debug("Logically deleting the vdev(id:%d)", + vdev->vdev_objmgr.vdev_id); + wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg); + } + /* * Update VDEV object state to LOGICALLY DELETED * It prevents further access of this object From 656ec600ac03dcd48c9c78d8b95129d09fe4eac7 Mon Sep 17 00:00:00 2001 From: Anurag Chouhan Date: Tue, 16 May 2017 15:06:44 +0530 Subject: [PATCH 03/26] qcacmn: Fix Operands size in a bitwise operation Bitwise operation on different operands size may lead to unexpected results, Typecast the constant to the size of the variable while performing the bitwise operation. Change-Id: Ifd9939905cc9df22bb249fa9b1a6a9670cf5f113 CRs-fixed: 2047880 --- qdf/linux/src/i_qdf_lock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qdf/linux/src/i_qdf_lock.h b/qdf/linux/src/i_qdf_lock.h index 53e7a59d9c..96acd6b9bc 100644 --- a/qdf/linux/src/i_qdf_lock.h +++ b/qdf/linux/src/i_qdf_lock.h @@ -295,7 +295,7 @@ static inline void __qdf_spin_lock_bh(__qdf_spinlock_t *lock) static inline void __qdf_spin_unlock_bh(__qdf_spinlock_t *lock) { if (unlikely(lock->flags & QDF_LINUX_UNLOCK_BH)) { - lock->flags &= ~QDF_LINUX_UNLOCK_BH; + lock->flags &= (unsigned long)~QDF_LINUX_UNLOCK_BH; spin_unlock_bh(&lock->spinlock); } else spin_unlock(&lock->spinlock); From 4b70998fcb494bab976dad011c8b7d41fa62bc7a Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 8 Jun 2017 13:59:02 -0700 Subject: [PATCH 04/26] qcacmn: Restart SAP with CSA/ECSA when gWlanMccToSccSwitchMod=3 Restart SAP with CSA/ECSA when ini variable gWlanMccToSccSwitchMod=3. Currently ini variable setting gWlanMccToSccSwitchMod=2 was causing SAP to restart with CSA. Change-Id: I9a4b68cd154fa63325d146510832c2410f2dc244 CRs-Fixed: 2058567 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 2 +- .../policy_mgr/src/wlan_policy_mgr_action.c | 28 +------------------ 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 40cce054c0..728d32eb7f 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -782,7 +782,7 @@ struct policy_mgr_hdd_cbacks { QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch, bool is_restart_sap); + uint8_t *sec_ch); enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 1695fc4bff..8990550e66 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -599,27 +599,6 @@ static bool policy_mgr_is_restart_sap_allowed( return true; } -/** - * policy_mgr_is_sap_channel_change_without_restart() - Check if - * SAP channel change allowed without restart - * @mcc_to_scc_switch: MCC to SCC switch enabled user config - * - * Check if SAP channel change allowed without restart - * - * Restart: true or false - */ -static bool policy_mgr_is_sap_channel_change_without_restart( - uint32_t mcc_to_scc_switch) { - if (mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION || - mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { - policy_mgr_info("SAP chan change without restart allowed"); - return true; - } - return false; -} - /** * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case * @data: Pointer check concurrent channel work data @@ -637,8 +616,6 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) QDF_STATUS status; uint8_t channel, sec_ch; uint8_t operating_channel, vdev_id; - bool restart_sap; - pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -661,9 +638,6 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) return; } - restart_sap = policy_mgr_is_sap_channel_change_without_restart( - mcc_to_scc_switch) ? false : true; - if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); return; @@ -671,7 +645,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, - &channel, &sec_ch, restart_sap); + &channel, &sec_ch); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); From b256bb0e81072340ae3c893f0a495e551ab27fe7 Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Mon, 22 May 2017 15:49:00 +0530 Subject: [PATCH 05/26] qcacmn: Add support to send DBS Scan command to firmware This change adds support to send the DBS Scan command to the firmware. Change-Id: I147855690f09af03a43f85f2e57626d7f73998de CRs-Fixed: 2029402 --- .../dispatcher/inc/wlan_scan_public_structs.h | 2 + wmi/inc/wmi_unified_api.h | 2 + wmi/inc/wmi_unified_param.h | 18 +++++ wmi/inc/wmi_unified_priv.h | 3 + wmi/src/wmi_unified_api.c | 20 ++++++ wmi/src/wmi_unified_tlv.c | 71 +++++++++++++++++++ 6 files changed, 116 insertions(+) diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index a3fada2c6f..22d5bebce3 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -534,6 +534,7 @@ enum scan_dwelltime_adaptive_mode { * @extraie: list of optional/vendor specific ie's to be added in probe requests * @htcap: htcap ie * @vhtcap: vhtcap ie + * @scan_ctrl_flags_ext: scan control flag extended */ struct scan_req_params { @@ -611,6 +612,7 @@ struct scan_req_params { struct element_info extraie; struct element_info htcap; struct element_info vhtcap; + uint32_t scan_ctrl_flags_ext; }; /** diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 3f0c303d05..f413dd01b2 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1507,4 +1507,6 @@ void wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count, #endif /* WMI_INTERFACE_EVENT_LOGGING */ +QDF_STATUS wmi_unified_send_dbs_scan_sel_params_cmd(void *wmi_hdl, + struct wmi_dbs_scan_sel_params *wmi_param); #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 6be9b31a81..6f98ebee4b 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -7285,4 +7285,22 @@ struct tbttoffset_params { uint32_t tbttoffset; }; +#define WMI_SCAN_CLIENT_MAX 7 + +/** + * struct wmi_dbs_scan_sel_params - DBS scan selection params + * @num_clients: Number of scan clients dutycycle + * @pdev_id: pdev_id for identifying the MAC + * @module_id: scan client module id + * @num_dbs_scans: number of DBS scans + * @num_non_dbs_scans: number of non-DBS scans + */ +struct wmi_dbs_scan_sel_params { + uint32_t num_clients; + uint32_t pdev_id; + uint32_t module_id[WMI_SCAN_CLIENT_MAX]; + uint32_t num_dbs_scans[WMI_SCAN_CLIENT_MAX]; + uint32_t num_non_dbs_scans[WMI_SCAN_CLIENT_MAX]; +}; + #endif /* _WMI_UNIFIED_PARAM_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 569bf8ae22..09f0db08ff 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1258,6 +1258,9 @@ QDF_STATUS (*send_multiple_vdev_restart_req_cmd)(wmi_unified_t wmi_handle, QDF_STATUS (*send_adapt_dwelltime_params_cmd)(wmi_unified_t wmi_handle, struct wmi_adaptive_dwelltime_params *dwelltime_params); +QDF_STATUS (*send_dbs_scan_sel_params_cmd)(wmi_unified_t wmi_handle, + struct wmi_dbs_scan_sel_params *dbs_scan_params); + QDF_STATUS (*send_fw_test_cmd)(wmi_unified_t wmi_handle, struct set_fwtest_params *wmi_fwtest); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index b9144df4fa..2835a37bfb 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -6683,3 +6683,23 @@ QDF_STATUS wmi_unified_set_country_cmd_send(void *wmi_hdl, return QDF_STATUS_E_FAILURE; } +/** + * wmi_unified_send_dbs_scan_sel_params_cmd() - send wmi cmd of + * DBS scan selection configuration params + * @wma_handle: wma handler + * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params + * + * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure + */ +QDF_STATUS wmi_unified_send_dbs_scan_sel_params_cmd(void *wmi_hdl, + struct wmi_dbs_scan_sel_params *dbs_scan_params) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (wmi_handle->ops->send_dbs_scan_sel_params_cmd) + return wmi_handle->ops-> + send_dbs_scan_sel_params_cmd(wmi_handle, + dbs_scan_params); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index e41f82dd14..ed77cabd8d 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -2226,6 +2226,10 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, cmd->num_ssids = params->num_ssids; cmd->ie_len = params->extraie.len; cmd->n_probes = params->n_probes; + cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; + + WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); + buf_ptr += sizeof(*cmd); tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); for (i = 0; i < params->num_chan; ++i) @@ -5766,6 +5770,71 @@ QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +/** + * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection + * configuration params + * @wmi_handle: wmi handler + * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params + * + * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure + */ +static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle, + struct wmi_dbs_scan_sel_params *dbs_scan_params) +{ + wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param; + wmi_scan_dbs_duty_cycle_tlv_param *cmd; + wmi_buf_t buf; + uint8_t *buf_ptr; + QDF_STATUS err; + uint32_t i; + int len; + + len = sizeof(*dbs_scan_param); + len += WMI_TLV_HDR_SIZE; + len += dbs_scan_params->num_clients * sizeof(*cmd); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s:Failed to allocate buffer to send cmd", __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = (uint8_t *) wmi_buf_data(buf); + dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&dbs_scan_param->tlv_header, + WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_scan_dbs_duty_cycle_fixed_param)); + + dbs_scan_param->num_clients = dbs_scan_params->num_clients; + dbs_scan_param->pdev_id = dbs_scan_params->pdev_id; + buf_ptr += sizeof(*dbs_scan_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + (sizeof(*cmd) * dbs_scan_params->num_clients)); + buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE; + + for (i = 0; i < dbs_scan_params->num_clients; i++) { + cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv, + WMITLV_GET_STRUCT_TLVLEN( + wmi_scan_dbs_duty_cycle_tlv_param)); + cmd->module_id = dbs_scan_params->module_id[i]; + cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i]; + cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i]; + buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd); + } + + err = wmi_unified_cmd_send(wmi_handle, buf, + len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID); + if (QDF_IS_STATUS_ERROR(err)) { + WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} /** * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming @@ -18066,6 +18135,8 @@ struct wmi_ops tlv_ops = { .send_set_active_bpf_mode_cmd = send_set_active_bpf_mode_cmd_tlv, .send_adapt_dwelltime_params_cmd = send_adapt_dwelltime_params_cmd_tlv, + .send_dbs_scan_sel_params_cmd = + send_dbs_scan_sel_params_cmd_tlv, .init_cmd_send = init_cmd_send_tlv, .send_smart_ant_enable_cmd = send_smart_ant_enable_cmd_tlv, .send_smart_ant_set_rx_ant_cmd = send_smart_ant_set_rx_ant_cmd_tlv, From a4e0fd63ccb89d9d15774948f42d546f8f82fb78 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Mon, 12 Jun 2017 11:05:25 -0700 Subject: [PATCH 06/26] qcacmn: Add connect wakelock reason Add a wakelock reason for wifi connect to wake_lock_reason. Change-Id: I907b6e0aebeceee1172604b8142ba40f5fbcdcd9 CRs-Fixed: 2059884 --- utils/host_diag_log/inc/host_diag_core_event.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/host_diag_log/inc/host_diag_core_event.h b/utils/host_diag_log/inc/host_diag_core_event.h index 6dcb1f6851..078a02a349 100644 --- a/utils/host_diag_log/inc/host_diag_core_event.h +++ b/utils/host_diag_log/inc/host_diag_core_event.h @@ -535,6 +535,7 @@ enum wifi_connectivity_events { * @WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP: Firmware response * @WIFI_POWER_EVENT_WAKELOCK_MISC: Miscellaneous wakelocks * @WIFI_POWER_EVENT_WAKELOCK_DHCP: DHCP negotiation under way + * @WIFI_POWER_EVENT_WAKELOCK_CONNECT: connection in progress * * Indicates the reason for which the wakelock was taken/released */ @@ -558,6 +559,7 @@ enum wake_lock_reason { WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP, WIFI_POWER_EVENT_WAKELOCK_MISC, WIFI_POWER_EVENT_WAKELOCK_DHCP, + WIFI_POWER_EVENT_WAKELOCK_CONNECT, }; #ifdef __cplusplus From 1be17fcd6b45c43c240bc28c8b8268f10cf0c7f4 Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Thu, 8 Jun 2017 09:32:50 +0530 Subject: [PATCH 07/26] qcacmn: replace irq name from wlan_ahb to the actual name when we issue cat /proc/interrupts we see wlan_ahb for all wlan interrupts, now replaced it with proper names to make it easy to debug Change-Id: Ib447cce7ffc2844b9f21f579aa50b6a1cfc2e001 --- hif/src/snoc/if_ahb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hif/src/snoc/if_ahb.c b/hif/src/snoc/if_ahb.c index a527781f61..fad636fc07 100644 --- a/hif/src/snoc/if_ahb.c +++ b/hif/src/snoc/if_ahb.c @@ -301,7 +301,8 @@ int hif_ahb_configure_grp_irq(struct hif_softc *scn) ic_irqnum[hif_ext_group->irq[j]] = irq; ret = request_irq(irq, hif_ext_group_ahb_interrupt_handler, - IRQF_TRIGGER_RISING, "wlan_ahb", + IRQF_TRIGGER_RISING, + ic_irqname[hif_ext_group->irq[j]], hif_ext_group); if (ret) { dev_err(&pdev->dev, From c45b01eb2bba3d0996d0890b1bef31b8cb7201e1 Mon Sep 17 00:00:00 2001 From: Karunakar Dasineni Date: Wed, 7 Jun 2017 11:38:01 -0700 Subject: [PATCH 08/26] qcacmn: Fix bug in link descriptor pool setup Fix bug in calculation of number of link descriptor entries per bank, which was causing memory corruptions. Change-Id: I68a86b8c644a4ef48a45ad5c98b739dced68d81d CRs-Fixed: 2057893 --- dp/wifi3.0/dp_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index c83ddbda87..59b36d585e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -636,10 +636,10 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) for (i = 0; i < MAX_LINK_DESC_BANKS && soc->link_desc_banks[i].base_paddr; i++) { uint32_t num_entries = (soc->link_desc_banks[i].size - - (unsigned long)( + ((unsigned long)( soc->link_desc_banks[i].base_vaddr) - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned)) + soc->link_desc_banks[i].base_vaddr_unaligned))) / link_desc_size; unsigned long paddr = (unsigned long)( soc->link_desc_banks[i].base_paddr); @@ -694,11 +694,11 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) soc->link_desc_banks[i].base_paddr; i++) { uint32_t num_link_descs = (soc->link_desc_banks[i].size - - (unsigned long)( + ((unsigned long)( soc->link_desc_banks[i].base_vaddr) - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned)) / - link_desc_size; + soc->link_desc_banks[i].base_vaddr_unaligned))) + / link_desc_size; unsigned long paddr = (unsigned long)( soc->link_desc_banks[i].base_paddr); void *desc = NULL; From ca919bd184b8508c0f919c2f3a3e6a1a4504a0af Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Wed, 7 Jun 2017 15:25:07 +0530 Subject: [PATCH 09/26] qcacmn: Validate mode and vdev while decrementing session The function policy_mgr_decr_active_session() decrements mode and then remove the session from the pm_conn_connection_info table after validating vdev. This change adds a check to validate if the session is present with specific mode and vdev_id, and then decrement the session. If not present, then return without doing any change. Change-Id: If53d7fc9356b2c3bb72b22b228103389396910ce CRs-Fixed: 2057599 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 20 ++++++++- .../src/wlan_policy_mgr_get_set_utils.c | 44 ++++++++++++++++++- .../policy_mgr/src/wlan_policy_mgr_pcl.c | 7 ++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 728d32eb7f..6c18c484ed 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -245,9 +245,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, * mode. In the case of STA/P2P CLI/IBSS upon disconnection it is decremented * In the case of SAP/P2P GO upon bss stop it is decremented * - * Return: None + * Return: QDF_STATUS */ -void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); /** @@ -1360,6 +1360,22 @@ uint32_t policy_mgr_mode_specific_connection_count( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t *list); +/** + * policy_mgr_check_conn_with_mode_and_vdev_id() - checks if any active + * session with specific mode and vdev_id + * @psoc: PSOC object information + * @mode: type of connection + * @vdev_id: vdev_id of the connection + * + * This function checks if any active session with specific mode and vdev_id + * is present + * + * Return: QDF STATUS with success if active session is found, else failure + */ +QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t vdev_id); + /** * policy_mgr_hw_mode_transition_cb() - Callback for HW mode * transition from FW diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 9d16bdd63c..2bdebb638c 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -838,6 +838,33 @@ uint32_t policy_mgr_mode_specific_connection_count( return count; } +QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t vdev_id) +{ + QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return qdf_status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + (pm_conc_connection_list[conn_index].vdev_id == vdev_id)) { + qdf_status = QDF_STATUS_SUCCESS; + break; + } + conn_index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return qdf_status; +} + void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, uint32_t scan_config, uint32_t fw_mode_config) @@ -1122,16 +1149,27 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } -void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS qdf_status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("context is NULL"); - return; + return QDF_STATUS_E_EMPTY; + } + + qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, + policy_mgr_convert_device_mode_to_qdf_type(mode), + session_id); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + policy_mgr_err("No connection with mode:%d vdev_id:%d", + policy_mgr_convert_device_mode_to_qdf_type(mode), + session_id); + return qdf_status; } switch (mode) { @@ -1157,6 +1195,8 @@ void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); policy_mgr_dump_current_concurrency(psoc); + + return qdf_status; } QDF_STATUS policy_mgr_incr_connection_count( diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index ad0b2c9d06..6c2a697112 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -103,7 +103,12 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, return; } - policy_mgr_decr_active_session(psoc, mode, session_id); + qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + policy_mgr_err("Invalid active session"); + return; + } + /* * After the removal of this connection, we need to check if * a STA connection still exists. The reason for this is that From 9dfc3874f14d6db2525dc579d92a3d26b8b8db65 Mon Sep 17 00:00:00 2001 From: Venkata Sharath Chandra Manchala Date: Wed, 14 Jun 2017 17:37:33 -0700 Subject: [PATCH 10/26] qcacmn: Fix for Rx descriptor pool Remove the statement nbuf pointing to NULL during allocation of descriptors as nbuf in rx_desc and next pointer in dp_rx_desc_list_elem_t share the same address space and pointing to NULL will not allocate the rx descriptors. Change-Id: If4c35202c2489aed1711173b37192f565f7c3d7b CRs-Fixed: 2061564 --- dp/wifi3.0/dp_rx_desc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index bfd0679a8d..3399441413 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -55,13 +55,11 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id, rx_desc_pool->array[i].next = &rx_desc_pool->array[i+1]; rx_desc_pool->array[i].rx_desc.cookie = i | (pool_id << 18); rx_desc_pool->array[i].rx_desc.pool_id = pool_id; - rx_desc_pool->array[i].rx_desc.nbuf = NULL; } rx_desc_pool->array[i].next = NULL; rx_desc_pool->array[i].rx_desc.cookie = i | (pool_id << 18); rx_desc_pool->array[i].rx_desc.pool_id = pool_id; - rx_desc_pool->array[i].rx_desc.nbuf = NULL; qdf_spin_unlock_bh(&soc->rx_desc_mutex[pool_id]); return QDF_STATUS_SUCCESS; } From 0be8df7f5f830d52730bf0b2d02d09b599f48794 Mon Sep 17 00:00:00 2001 From: Om Prakash Tripathi Date: Tue, 13 Jun 2017 05:26:19 +0530 Subject: [PATCH 11/26] qcacmn: Add stats for mnagement tx frames Add counter stats for number of management frames sent via wmi and number of completions received. Change-Id: Id5e72858b1e258b089b170a6d15ba395782645cc CRs-Fixed: 2060117 --- dp/inc/cdp_txrx_stats_struct.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 275c3deedb..cbab616695 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -213,6 +213,11 @@ struct ol_ath_radiostats { A_INT16 chan_nf; A_UINT32 rx_last_msdu_unset_cnt; A_INT16 chan_nf_sec80; + A_UINT64 wmi_tx_mgmt; + A_UINT64 wmi_tx_mgmt_completions; + A_UINT32 wmi_tx_mgmt_completion_err; + A_UINT32 peer_delete_req; + A_UINT32 peer_delete_resp; }; #ifndef CONFIG_WIN From 15677ec8591577590b2c95cbaa9e97f59105f99d Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Tue, 6 Jun 2017 18:31:39 -0700 Subject: [PATCH 12/26] qcacmn: Add protection to access scan queue scan request queue is accessed in multiple process contexts so added mutex to scan request queue. Scan request mutex needs to be acquired before accessing the scan request queue. Change-Id: I3f0fe0513d5846f4eaf313848f00f86d29a66e35 CRs-Fixed: 2057127 --- os_if/linux/scan/inc/wlan_cfg80211_scan.h | 2 ++ os_if/linux/scan/src/wlan_cfg80211_scan.c | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/os_if/linux/scan/inc/wlan_cfg80211_scan.h b/os_if/linux/scan/inc/wlan_cfg80211_scan.h index b455b87cf3..99285eba42 100644 --- a/os_if/linux/scan/inc/wlan_cfg80211_scan.h +++ b/os_if/linux/scan/inc/wlan_cfg80211_scan.h @@ -76,11 +76,13 @@ typedef struct { /** * struct osif_scan_pdev - OS scan private strcutre * scan_req_q: Scan request queue + * scan_req_q_lock: Protect scan request queue * req_id: Scan request Id * runtime_pm_lock: Runtime suspend lock */ struct osif_scan_pdev{ qdf_list_t scan_req_q; + qdf_mutex_t scan_req_q_lock; wlan_scan_requester req_id; qdf_runtime_lock_t runtime_pm_lock; }; diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index 9381ef7b51..aa7bd25ec5 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -458,9 +458,10 @@ static int wlan_scan_request_enqueue(struct wlan_objmgr_pdev *pdev, scan_req->source = source; scan_req->scan_id = scan_id; + qdf_mutex_acquire(&osif_scan->scan_req_q_lock); status = qdf_list_insert_back(&osif_scan->scan_req_q, &scan_req->node); - + qdf_mutex_release(&osif_scan->scan_req_q_lock); if (QDF_STATUS_SUCCESS != status) { cfg80211_err("Failed to enqueue Scan Req"); qdf_mem_free(scan_req); @@ -509,8 +510,10 @@ static QDF_STATUS wlan_scan_request_dequeue( return QDF_STATUS_E_FAILURE; } + qdf_mutex_acquire(&scan_priv->scan_req_q_lock); if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&scan_priv->scan_req_q, &next_node)) { + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_err("Failed to remove Scan Req from queue"); return QDF_STATUS_E_FAILURE; } @@ -526,11 +529,13 @@ static QDF_STATUS wlan_scan_request_dequeue( *req = scan_req->scan_request; *source = scan_req->source; qdf_mem_free(scan_req); + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_info("removed Scan id: %d, req = %p, pending scans %d", scan_id, req, qdf_list_size(&scan_priv->scan_req_q)); return QDF_STATUS_SUCCESS; } else { + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_err("Failed to remove node scan id %d, pending scans %d", scan_id, qdf_list_size(&scan_priv->scan_req_q)); @@ -539,7 +544,7 @@ static QDF_STATUS wlan_scan_request_dequeue( } } while (QDF_STATUS_SUCCESS == qdf_list_peek_next(&scan_priv->scan_req_q, node, &next_node)); - + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_err("Failed to find scan id %d", scan_id); return status; @@ -770,6 +775,7 @@ QDF_STATUS wlan_cfg80211_scan_priv_init(struct wlan_objmgr_pdev *pdev) /* Initialize the scan request queue */ osif_priv->osif_scan = scan_priv; qdf_list_create(&scan_priv->scan_req_q, WLAN_MAX_SCAN_COUNT); + qdf_mutex_create(&scan_priv->scan_req_q_lock); scan_priv->req_id = req_id; scan_priv->runtime_pm_lock = qdf_runtime_lock_init("scan"); @@ -791,6 +797,7 @@ QDF_STATUS wlan_cfg80211_scan_priv_deinit(struct wlan_objmgr_pdev *pdev) osif_priv->osif_scan = NULL; ucfg_scan_unregister_requester(psoc, scan_priv->req_id); qdf_list_destroy(&scan_priv->scan_req_q); + qdf_mutex_destroy(&scan_priv->scan_req_q_lock); qdf_runtime_lock_deinit(scan_priv->runtime_pm_lock); scan_priv->runtime_pm_lock = NULL; qdf_mem_free(scan_priv); @@ -818,15 +825,16 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev) wlan_pdev_obj_unlock(pdev); scan_priv = osif_priv->osif_scan; - + qdf_mutex_acquire(&scan_priv->scan_req_q_lock); while (!qdf_list_empty(&scan_priv->scan_req_q)) { if (QDF_STATUS_SUCCESS != qdf_list_remove_front(&scan_priv->scan_req_q, &node)) { + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_err("Failed to remove scan request"); return; } - + qdf_mutex_release(&scan_priv->scan_req_q_lock); scan_req = container_of(node, struct scan_req, node); req = scan_req->scan_request; source = scan_req->source; @@ -835,7 +843,9 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev) else wlan_vendor_scan_callback(req, aborted); qdf_mem_free(scan_req); + qdf_mutex_acquire(&scan_priv->scan_req_q_lock); } + qdf_mutex_release(&scan_priv->scan_req_q_lock); return; } @@ -1109,7 +1119,9 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev, return ret; } scan_priv = osif_ctx->osif_scan; + qdf_mutex_acquire(&scan_priv->scan_req_q_lock); if (qdf_list_empty(&scan_priv->scan_req_q)) { + qdf_mutex_release(&scan_priv->scan_req_q_lock); cfg80211_err("Failed to retrieve scan id"); return ret; } @@ -1117,6 +1129,7 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev, if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&scan_priv->scan_req_q, &ptr_node)) { + qdf_mutex_release(&scan_priv->scan_req_q_lock); return ret; } @@ -1133,6 +1146,8 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev, qdf_list_peek_next(&scan_priv->scan_req_q, node, &ptr_node)); + qdf_mutex_release(&scan_priv->scan_req_q_lock); + return ret; } From 0014f6238e0a39a7c09e545309b5fb28e881d49a Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Tue, 6 Jun 2017 19:27:17 -0700 Subject: [PATCH 13/26] qcacmn: Add validation check at NL scan event callback Scan event is updated to NL on a closed wireless dev. Add validation check at scan event callback before updating the scan events to NL. Change-Id: I979b53ecb481007f663feb927b6e3e96cf73616b CRs-Fixed: 2057127 --- os_if/linux/scan/src/wlan_cfg80211_scan.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index aa7bd25ec5..52ddd5ee92 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -732,6 +732,26 @@ static void wlan_cfg80211_scan_done_callback( goto allow_suspend; } + if (req->wdev == NULL) { + cfg80211_err("wirless dev is NULL,Drop scan event Id: %d", + scan_id); + goto allow_suspend; + } + + if (req->wdev->netdev == NULL) { + cfg80211_err("net dev is NULL,Drop scan event Id: %d", + scan_id); + goto allow_suspend; + } + + /* Make sure vdev is active */ + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("Failed to get vdev reference: scan Id: %d", + scan_id); + goto allow_suspend; + } + /* * Scan can be triggred from NL or vendor scan * - If scan is triggered from NL then cfg80211 scan done should be @@ -744,6 +764,7 @@ static void wlan_cfg80211_scan_done_callback( else wlan_vendor_scan_callback(req, aborted); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); allow_suspend: osif_priv = wlan_pdev_get_ospriv(pdev); if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) From ccf859d9f563d6fe9bb266e4a91950549ca0d2fd Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 1 Jun 2017 14:31:01 -0700 Subject: [PATCH 14/26] qcacmn: Refactor Unit-Test Suspend Unit-Test suspend needs to be decoupled from the copy engine implementation in HIF. Split the HIF portion of Unit-Test suspend into their own files, and clean up naming, etc. Change-Id: Ic36c5b98c505f6b62ddf94336838a9e53fe8aa78 CRs-Fixed: 2055328 --- hif/inc/hif.h | 6 -- hif/inc/hif_unit_test_suspend.h | 59 ++++++++++++++++ hif/src/ce/ce_main.c | 11 --- hif/src/ce/ce_tasklet.c | 102 +++----------------------- hif/src/hif_main.c | 3 + hif/src/hif_main.h | 19 +---- hif/src/hif_unit_test_suspend.c | 114 ++++++++++++++++++++++++++++++ hif/src/hif_unit_test_suspend_i.h | 84 ++++++++++++++++++++++ 8 files changed, 273 insertions(+), 125 deletions(-) create mode 100644 hif/inc/hif_unit_test_suspend.h create mode 100644 hif/src/hif_unit_test_suspend.c create mode 100644 hif/src/hif_unit_test_suspend_i.h diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 2fe3d33738..a7a45cc9a6 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -853,12 +853,6 @@ int hif_bus_reset_resume(struct hif_opaque_softc *hif_ctx); void hif_set_attribute(struct hif_opaque_softc *osc, uint8_t hif_attrib); void *hif_get_lro_info(int ctx_id, struct hif_opaque_softc *hif_hdl); -#ifdef WLAN_SUSPEND_RESUME_TEST -typedef void (*hif_fake_resume_callback)(uint32_t val); -void hif_fake_apps_suspend(struct hif_opaque_softc *hif_ctx, - hif_fake_resume_callback callback); -void hif_fake_apps_resume(struct hif_opaque_softc *hif_ctx); -#endif uint32_t hif_register_ext_group_int_handler(struct hif_opaque_softc *hif_ctx, uint32_t numirq, uint32_t irq[], ext_intr_handler handler, diff --git a/hif/inc/hif_unit_test_suspend.h b/hif/inc/hif_unit_test_suspend.h new file mode 100644 index 0000000000..cb036ecabb --- /dev/null +++ b/hif/inc/hif_unit_test_suspend.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Public unit-test related APIs for triggering WoW suspend/resume while + * the application processor is still up. + */ + +#ifndef _HIF_UNIT_TEST_SUSPEND_H_ +#define _HIF_UNIT_TEST_SUSPEND_H_ + +#ifdef WLAN_SUSPEND_RESUME_TEST + +#include "qdf_status.h" +#include "hif.h" + +typedef void (*hif_ut_resume_callback)(void); + +/** + * hif_ut_apps_suspend() - Setup unit-test related suspend state. + * @opaque_scn: The HIF context to operate on + * @callback: The function to call when unit-test resume is triggered + * + * Call after a normal WoW suspend has been completed. + * + * Return: QDF_STATUS + */ +QDF_STATUS hif_ut_apps_suspend(struct hif_opaque_softc *opaque_scn, + hif_ut_resume_callback callback); + +/** + * hif_ut_apps_resume() - Cleanup unit-test related suspend state. + * @opaque_scn: The HIF context to operate on + * + * Call before doing a normal WoW resume if suspend was initiated via + * unit-test suspend. + * + * Return: QDF_STATUS + */ +QDF_STATUS hif_ut_apps_resume(struct hif_opaque_softc *opaque_scn); + +#endif /* WLAN_SUSPEND_RESUME_TEST */ + +#endif /* _HIF_UNIT_TEST_SUSPEND_H_ */ diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index d91d991d12..c03c2d1125 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -2415,16 +2415,6 @@ static inline void hif_post_static_buf_to_target(struct hif_softc *scn) } #endif -#ifdef WLAN_SUSPEND_RESUME_TEST -static void hif_fake_apps_init_ctx(struct hif_softc *scn) -{ - INIT_WORK(&scn->fake_apps_ctx.resume_work, - hif_fake_apps_resume_work); -} -#else -static inline void hif_fake_apps_init_ctx(struct hif_softc *scn) {} -#endif - /** * hif_config_ce() - configure copy engines * @scn: hif context @@ -2511,7 +2501,6 @@ int hif_config_ce(struct hif_softc *scn) HIF_DBG("%s: ce_init done", __func__); init_tasklet_workers(hif_hdl); - hif_fake_apps_init_ctx(scn); HIF_DBG("%s: X, ret = %d", __func__, rv); diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c index 8f938742c3..73e0a14443 100644 --- a/hif/src/ce/ce_tasklet.c +++ b/hif/src/ce/ce_tasklet.c @@ -270,73 +270,19 @@ int hif_drain_tasklets(struct hif_softc *scn) #ifdef WLAN_SUSPEND_RESUME_TEST /** - * hif_fake_apps_resume_work() - Work handler for fake apps resume callback - * @work: The work struct being passed from the linux kernel + * hif_interrupt_is_ut_resume(): Tests if an irq on the given copy engine should + * trigger a unit-test resume. + * @scn: The HIF context to operate on + * @ce_id: The copy engine Id from the originating interrupt * - * Return: none + * Return: true if the raised irq should trigger a unit-test resume */ -void hif_fake_apps_resume_work(struct work_struct *work) +static bool hif_interrupt_is_ut_resume(struct hif_softc *scn, int ce_id) { - struct fake_apps_context *ctx = - container_of(work, struct fake_apps_context, resume_work); - - QDF_BUG(ctx->resume_callback); - ctx->resume_callback(0); - ctx->resume_callback = NULL; -} - -/** - * hif_fake_apps_suspend(): Setup unit-test related suspend state. Call after - * a normal WoW suspend has been completed. - * @hif_ctx: The HIF context to operate on - * @callback: The function to call when fake apps resume is triggered - * - * Set the fake suspend flag such that hif knows that it will need - * to fake the apps resume process using hdd_trigger_fake_apps_resume - * - * Return: none - */ -void hif_fake_apps_suspend(struct hif_opaque_softc *hif_ctx, - hif_fake_resume_callback callback) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - scn->fake_apps_ctx.resume_callback = callback; - set_bit(HIF_FA_SUSPENDED_BIT, &scn->fake_apps_ctx.state); -} - -/** - * hif_fake_apps_resume(): Cleanup unit-test related suspend state. Call before - * doing a normal WoW resume if suspend was initiated via fake apps - * suspend. - * @hif_ctx: The HIF context to operate on - * - * Return: none - */ -void hif_fake_apps_resume(struct hif_opaque_softc *hif_ctx) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - clear_bit(HIF_FA_SUSPENDED_BIT, &scn->fake_apps_ctx.state); - scn->fake_apps_ctx.resume_callback = NULL; -} - -/** - * hif_interrupt_is_fake_apps_resume(): Determines if the raised irq should - * trigger a fake apps resume. - * @hif_ctx: The HIF context to operate on - * @ce_id: The copy engine Id from the originating interrupt - * - * Return: true if the raised irq should trigger a fake apps resume - */ -static bool hif_interrupt_is_fake_apps_resume(struct hif_opaque_softc *hif_ctx, - int ce_id) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); int errno; uint8_t wake_ce_id; - if (!test_bit(HIF_FA_SUSPENDED_BIT, &scn->fake_apps_ctx.state)) + if (!hif_is_ut_suspended(scn)) return false; /* ensure passed ce_id matches wake ce_id */ @@ -348,39 +294,13 @@ static bool hif_interrupt_is_fake_apps_resume(struct hif_opaque_softc *hif_ctx, return ce_id == wake_ce_id; } - -/** - * hif_trigger_fake_apps_resume(): Trigger a fake apps resume by scheduling the - * previously registered callback for execution - * @hif_ctx: The HIF context to operate on - * - * Return: None - */ -static void hif_trigger_fake_apps_resume(struct hif_opaque_softc *hif_ctx) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - if (!test_and_clear_bit(HIF_FA_SUSPENDED_BIT, - &scn->fake_apps_ctx.state)) - return; - - schedule_work(&scn->fake_apps_ctx.resume_work); -} - #else - static inline bool -hif_interrupt_is_fake_apps_resume(struct hif_opaque_softc *hif_ctx, int ce_id) +hif_interrupt_is_ut_resume(struct hif_softc *scn, int ce_id) { return false; } - -static inline void -hif_trigger_fake_apps_resume(struct hif_opaque_softc *hif_ctx) -{ -} - -#endif /* End of WLAN_SUSPEND_RESUME_TEST */ +#endif /* WLAN_SUSPEND_RESUME_TEST */ /** * hif_snoc_interrupt_handler() - hif_snoc_interrupt_handler @@ -482,8 +402,8 @@ irqreturn_t ce_dispatch_interrupt(int ce_id, hif_record_ce_desc_event(scn, ce_id, HIF_IRQ_EVENT, NULL, NULL, 0); hif_ce_increment_interrupt_count(hif_ce_state, ce_id); - if (unlikely(hif_interrupt_is_fake_apps_resume(hif_hdl, ce_id))) { - hif_trigger_fake_apps_resume(hif_hdl); + if (unlikely(hif_interrupt_is_ut_resume(scn, ce_id))) { + hif_ut_fw_resume(scn); hif_irq_enable(scn, ce_id); return IRQ_HANDLED; } diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index f700572b05..b19ff15175 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -50,6 +50,7 @@ #include "hal_api.h" #endif #include "hif_napi.h" +#include "hif_unit_test_suspend_i.h" void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start) { @@ -534,6 +535,8 @@ QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev, return status; } + hif_ut_suspend_init(scn); + /* * Flag to avoid potential unallocated memory access from MSI * interrupt handler which could get scheduled as soon as MSI diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 6c05fdc9d2..78f07c0cc6 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -47,6 +47,7 @@ #include "cepci.h" #include "hif.h" #include "multibus.h" +#include "hif_unit_test_suspend_i.h" #define HIF_MIN_SLEEP_INACTIVITY_TIME_MS 50 #define HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS 60 @@ -118,20 +119,6 @@ struct hif_ce_stats { int ce_ring_delta_fail_count; }; -#ifdef WLAN_SUSPEND_RESUME_TEST -struct fake_apps_context { - unsigned long state; - hif_fake_resume_callback resume_callback; - struct work_struct resume_work; -}; - -enum hif_fake_apps_state_bits { - HIF_FA_SUSPENDED_BIT = 0 -}; - -void hif_fake_apps_resume_work(struct work_struct *work); -#endif /* WLAN_SUSPEND_RESUME_TEST */ - struct hif_softc { struct hif_opaque_softc osc; struct hif_config_info hif_config; @@ -178,9 +165,7 @@ struct hif_softc { uint32_t nss_wifi_ol_mode; #endif void *hal_soc; -#ifdef WLAN_SUSPEND_RESUME_TEST - struct fake_apps_context fake_apps_ctx; -#endif /* WLAN_SUSPEND_RESUME_TEST */ + struct hif_ut_suspend_context ut_suspend_ctx; uint32_t hif_attribute; }; diff --git a/hif/src/hif_unit_test_suspend.c b/hif/src/hif_unit_test_suspend.c new file mode 100644 index 0000000000..938648c325 --- /dev/null +++ b/hif/src/hif_unit_test_suspend.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "qdf_status.h" +#include "hif_main.h" +#include "hif_unit_test_suspend.h" +#include "hif_unit_test_suspend_i.h" + +enum hif_ut_suspend_state_bits { + UT_SUSPENDED_BIT = 0 +}; + +/** + * hif_ut_fw_resume_work() - Work handler for firmware-triggered resume + * @work: The work struct being passed from the linux kernel + * + * Return: None + */ +static void hif_ut_fw_resume_work(struct work_struct *work) +{ + struct hif_ut_suspend_context *ctx = + container_of(work, struct hif_ut_suspend_context, resume_work); + + QDF_BUG(ctx); + if (!ctx) + return; + + QDF_BUG(ctx->resume_callback); + if (!ctx->resume_callback) + return; + + ctx->resume_callback(); + ctx->resume_callback = NULL; +} + +void hif_ut_suspend_init(struct hif_softc *scn) +{ + INIT_WORK(&scn->ut_suspend_ctx.resume_work, hif_ut_fw_resume_work); +} + +bool hif_is_ut_suspended(struct hif_softc *scn) +{ + QDF_BUG(scn); + if (!scn) + return false; + + return test_bit(UT_SUSPENDED_BIT, &scn->ut_suspend_ctx.state); +} + +QDF_STATUS hif_ut_apps_suspend(struct hif_opaque_softc *opaque_scn, + hif_ut_resume_callback callback) +{ + struct hif_softc *scn = HIF_GET_SOFTC(opaque_scn); + + QDF_BUG(scn); + if (!scn) + return QDF_STATUS_E_INVAL; + + QDF_BUG(callback); + if (!callback) + return QDF_STATUS_E_INVAL; + + if (test_and_set_bit(UT_SUSPENDED_BIT, &scn->ut_suspend_ctx.state)) + return QDF_STATUS_E_INVAL; + + scn->ut_suspend_ctx.resume_callback = callback; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS hif_ut_apps_resume(struct hif_opaque_softc *opaque_scn) +{ + struct hif_softc *scn = HIF_GET_SOFTC(opaque_scn); + + QDF_BUG(scn); + if (!scn) + return QDF_STATUS_E_INVAL; + + if (!test_and_clear_bit(UT_SUSPENDED_BIT, &scn->ut_suspend_ctx.state)) + return QDF_STATUS_E_INVAL; + + scn->ut_suspend_ctx.resume_callback = NULL; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn) +{ + QDF_BUG(scn); + if (!scn) + return QDF_STATUS_E_INVAL; + + if (!test_and_clear_bit(UT_SUSPENDED_BIT, &scn->ut_suspend_ctx.state)) + return QDF_STATUS_E_INVAL; + + schedule_work(&scn->ut_suspend_ctx.resume_work); + + return QDF_STATUS_SUCCESS; +} diff --git a/hif/src/hif_unit_test_suspend_i.h b/hif/src/hif_unit_test_suspend_i.h new file mode 100644 index 0000000000..dedb1e51cc --- /dev/null +++ b/hif/src/hif_unit_test_suspend_i.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: HIF internal unit-test related APIs for triggering WoW suspend/resume + * while the application processor is still up. + */ + +#ifndef _HIF_UNIT_TEST_SUSPEND_I_H_ +#define _HIF_UNIT_TEST_SUSPEND_I_H_ + +#include "qdf_status.h" +#include "hif_main.h" +#include "hif_unit_test_suspend.h" + +#ifdef WLAN_SUSPEND_RESUME_TEST + +struct hif_ut_suspend_context { + unsigned long state; + hif_ut_resume_callback resume_callback; + struct work_struct resume_work; +}; + +/** + * hif_ut_suspend_init() - Initialize the unit-test suspend context + * @scn: the hif context to initialize + * + * Return: None + */ +void hif_ut_suspend_init(struct hif_softc *scn); + +/** + * hif_is_ut_suspended() - Tests if the given hif context is unit-test suspended + * @scn: The HIF context to check + * + * Return: true, if unit-test suspended, otherwise false + */ +bool hif_is_ut_suspended(struct hif_softc *scn); + +/** + * hif_ut_fw_resume() - Initiate a firmware triggered unit-test resume + * @scn: The HIF context to operate on + * + * This schedules the callback previously registered via a call to + * hif_ut_apps_suspend for execution. + * + * Return: QDF_STATUS + */ +QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn); + +#else /* WLAN_SUSPEND_RESUME_TEST */ + +struct hif_ut_suspend_context {}; + +static inline void hif_ut_suspend_init(struct hif_softc *scn) {} + +static inline bool hif_is_ut_suspended(struct hif_softc *scn) +{ + return false; +} + +static inline QDF_STATUS hif_ut_fw_resume(struct hif_softc *scn) +{ + return QDF_STATUS_SUCCESS; +} + +#endif /* WLAN_SUSPEND_RESUME_TEST */ + +#endif /* _HIF_UNIT_TEST_SUSPEND_I_H_ */ From 1eb4e0ae5cf2e81aa8f292b184a6018926b93f8a Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 6 Jun 2017 15:07:01 -0700 Subject: [PATCH 15/26] qcacmn: Check for null resume handlers in suspend recovery After an error, during the suspend process, previously suspended components are resumed in reverse order. However, while the suspend case checks for null handlers before dispatching them, the recovery case does not. Ensure each resume handler is not null before calling it during suspend recovery. Change-Id: I86baa4cba9d2b64871da58427a4657b4b3642cdc CRs-Fixed: 2057165 --- pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c | 146 +++++++++++---------- 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c index ada0d391d9..7493d5233d 100644 --- a/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c +++ b/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c @@ -452,112 +452,114 @@ out: } QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc, - enum qdf_suspend_type suspend_type) + enum qdf_suspend_type suspend_type) { - pmo_psoc_suspend_handler handler; - uint8_t index = 0; - QDF_STATUS suspend_status = QDF_STATUS_SUCCESS; - QDF_STATUS resume_status = QDF_STATUS_SUCCESS; - void *arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS resume_status; struct wlan_pmo_ctx *pmo_ctx; + uint8_t i; + pmo_psoc_suspend_handler handler; + void *arg; PMO_ENTER(); + pmo_ctx = pmo_get_context(); if (!pmo_ctx) { - QDF_ASSERT(0); pmo_err("unable to get pmo ctx"); - suspend_status = QDF_STATUS_E_FAILURE; - goto out; + QDF_ASSERT(0); + status = QDF_STATUS_E_FAILURE; + goto exit_with_status; } - /* call all component's Suspend Handler */ - while (index < WLAN_UMAC_MAX_COMPONENTS) { + /* call each component's suspend handler */ + for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { qdf_spin_lock_bh(&pmo_ctx->lock); - if (pmo_ctx->pmo_suspend_handler[index]) { - handler = pmo_ctx->pmo_suspend_handler[index]; - arg = pmo_ctx->pmo_suspend_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - suspend_status = handler(psoc, arg); - if (suspend_status != QDF_STATUS_SUCCESS) { - pmo_err("component id: %d failed to suspend status: %d", - index, suspend_status); - QDF_ASSERT(0); - /* break, no need to suspend next components */ - break; - } - } else { - qdf_spin_unlock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_suspend_handler[i]; + arg = pmo_ctx->pmo_suspend_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(status)) { + pmo_err("component %d failed to suspend; status: %d", + i, status); + QDF_ASSERT(0); + goto suspend_recovery; } - index++; } - /* resume the succefully suspended components */ - if (suspend_status != QDF_STATUS_SUCCESS) { - while (index >= 0) { - /* - * index points to id which refuse suspend - * so go to previous id. - */ - index--; - qdf_spin_lock_bh(&pmo_ctx->lock); - handler = pmo_ctx->pmo_resume_handler[index]; - arg = pmo_ctx->pmo_resume_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - /* TODO: if resume got failed for some component ?? */ - resume_status = handler(psoc, arg); - if (resume_status != QDF_STATUS_SUCCESS) { - pmo_err("Component id: %d failed to resume status: %d", - index, resume_status); - QDF_ASSERT(0); - } + goto exit_with_status; + +suspend_recovery: + /* resume, starting with the last successfully suspended component */ + for (i -= 1; i >= 0; i--) { + qdf_spin_lock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_resume_handler[i]; + arg = pmo_ctx->pmo_resume_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + resume_status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(resume_status)) { + pmo_fatal("Non-recoverable failure occurred!"); + pmo_fatal("component %d failed to resume; status: %d", + i, resume_status); + QDF_BUG(0); } } -out: + +exit_with_status: PMO_EXIT(); - return suspend_status; + return status; } QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc, - enum qdf_suspend_type suspend_type) + enum qdf_suspend_type suspend_type) { - uint8_t index = 0; - QDF_STATUS component_ret = QDF_STATUS_SUCCESS; - void *arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; struct wlan_pmo_ctx *pmo_ctx; + uint8_t i; pmo_psoc_suspend_handler handler; + void *arg; PMO_ENTER(); + pmo_ctx = pmo_get_context(); if (!pmo_ctx) { - QDF_ASSERT(0); pmo_err("unable to get pmo ctx"); - component_ret = QDF_STATUS_E_FAILURE; - goto out; + QDF_ASSERT(0); + status = QDF_STATUS_E_FAILURE; + goto exit_with_status; } - /* call all components Resume Handler */ - while (index < WLAN_UMAC_MAX_COMPONENTS) { + /* call each component's resume handler */ + for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { qdf_spin_lock_bh(&pmo_ctx->lock); - if (pmo_ctx->pmo_resume_handler[index]) { - handler = pmo_ctx->pmo_resume_handler[index]; - arg = pmo_ctx->pmo_resume_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - component_ret = handler(psoc, arg); - if (component_ret != QDF_STATUS_SUCCESS) { - pmo_err("Component id: %d failed to resume status: %d", - index, component_ret); - QDF_ASSERT(0); - } - } else { - qdf_spin_unlock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_resume_handler[i]; + arg = pmo_ctx->pmo_resume_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(status)) { + pmo_fatal("Non-recoverable failure occurred!"); + pmo_fatal("component %d failed to resume; status: %d", + i, status); + QDF_BUG(0); } - index++; -} -out: + } + +exit_with_status: PMO_EXIT(); - return component_ret; + return status; } QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc, From 4055568bada387f32d002e0585408f6a338ae143 Mon Sep 17 00:00:00 2001 From: Karunakar Dasineni Date: Sun, 26 Mar 2017 22:44:39 -0700 Subject: [PATCH 16/26] qcacmn: Monitor status ring handling Changes to process PHY TLVs from monitor status ring and extract information required for radiotap header. Change-Id: I99d642e7506ea797b26dbfac89fd223d1a4c0a55 CRs-Fixed: 2048006 --- dp/wifi3.0/dp_htt.c | 2 +- dp/wifi3.0/dp_main.c | 15 +- dp/wifi3.0/dp_rx_mon_dest.c | 118 ++++++-------- dp/wifi3.0/dp_rx_mon_status.c | 27 ++-- dp/wifi3.0/dp_types.h | 1 - hal/wifi3.0/hal_api_mon.h | 289 +++++++++++++++++++++++++++------- hal/wifi3.0/hal_internal.h | 11 ++ qdf/inc/qdf_nbuf.h | 12 ++ qdf/linux/src/qdf_nbuf.c | 2 +- 9 files changed, 324 insertions(+), 153 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index f0c2aabbec..97a8cd47cc 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -815,7 +815,7 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET_HEADER, htt_tlv_filter->packet_header); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, ATTENTION, - htt_tlv_filter->ppdu_end_status_done); + htt_tlv_filter->attention); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_START, htt_tlv_filter->ppdu_start); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 59b36d585e..5caf47e2b0 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2389,8 +2389,8 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, htt_tlv_filter.enable_mo = 1; htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, - pdev->rxdma_mon_dst_ring.hal_srng, - RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, &htt_tlv_filter); + pdev->rxdma_mon_buf_ring.hal_srng, + RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, &htt_tlv_filter); htt_tlv_filter.mpdu_start = 1; htt_tlv_filter.msdu_start = 1; @@ -2405,13 +2405,12 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, htt_tlv_filter.ppdu_end_user_stats_ext = 1; htt_tlv_filter.ppdu_end_status_done = 1; htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.enable_md = 1; + htt_tlv_filter.enable_md = 0; htt_tlv_filter.enable_mo = 1; - /* - * htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, - * pdev->rxdma_mon_status_ring.hal_srng, - * RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - */ + + htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, + pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS, + RX_BUFFER_SIZE, &htt_tlv_filter); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 1ffa37b834..003ea4fc05 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -99,8 +99,7 @@ done: * @tail: tail of decs list to be freed * Return: number of msdu in MPDU to be popped */ -static inline -uint32_t +static inline uint32_t dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, void *rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *npackets, uint32_t *ppdu_id, @@ -161,6 +160,23 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, "[%s][%d] msdu_nbuf=%p, data=%p\n", __func__, __LINE__, msdu, data); + rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); + msdu_ppdu_id = + HAL_RX_MON_HW_DESC_GET_PPDUID_GET(rx_desc_tlv); + + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_DEBUG, + "[%s][%d] i=%d, ppdu_id=%x, msdu_ppdu_id=%x\n", + __func__, __LINE__, i, *ppdu_id, msdu_ppdu_id); + if (*ppdu_id != msdu_ppdu_id) { + *ppdu_id = msdu_ppdu_id; + return rx_bufs_used; + } + + if (hal_rx_desc_is_first_msdu(rx_desc_tlv)) + hal_rx_mon_hw_desc_get_mpdu_status(rx_desc_tlv, + &(dp_pdev->ppdu_info.rx_status)); + rx_pkt_offset = HAL_RX_MON_HW_RX_DESC_SIZE(); /* * HW structures call this L3 header padding @@ -176,7 +192,6 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_set_pktlen(msdu, rx_buf_size); - rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); #if 0 /* Disble it.see packet on msdu done set to 0 */ @@ -200,17 +215,6 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, } #endif - msdu_ppdu_id = - HAL_RX_MON_HW_DESC_GET_PPDUID_GET(rx_desc_tlv); - -#if 0 - /* Temporary only handle destination ring */ - if (*ppdu_id != msdu_ppdu_id) { - *ppdu_id = msdu_ppdu_id; - return rx_bufs_used; - } -#endif - rx_bufs_used++; QDF_TRACE(QDF_MODULE_ID_DP, @@ -306,8 +310,6 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, rx_desc = qdf_nbuf_data(head_msdu); - HAL_RX_MON_HW_DESC_GET_PPDU_START_STATUS(rx_desc, rx_status); - decap_format = HAL_RX_DESC_GET_DECAP_FORMAT(rx_desc); /* Easy case - The MSDU status indicates that this is a non-decapped @@ -616,7 +618,6 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, struct cdp_mon_status *rs = &pdev->rx_mon_recv_status; qdf_nbuf_t mon_skb, skb_next; qdf_nbuf_t mon_mpdu = NULL; - struct mon_rx_status rx_mon_status; if ((pdev->monitor_vdev == NULL) || (pdev->monitor_vdev->osif_rx_mon == NULL)) { @@ -628,13 +629,10 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, tail_msdu, rs); if (mon_mpdu) { - /* Push radiotap header */ - dp_rx_extract_radiotap_info(rs, &rx_mon_status); - - qdf_nbuf_update_radiotap(&rx_mon_status, mon_mpdu, - sizeof(struct rx_pkt_tlvs)); + qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), + mon_mpdu, sizeof(struct rx_pkt_tlvs)); pdev->monitor_vdev->osif_rx_mon( - pdev->monitor_vdev->osif_vdev, mon_mpdu, rs); + pdev->monitor_vdev->osif_vdev, mon_mpdu, NULL); } else { goto mon_deliver_fail; } @@ -676,8 +674,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) void *mon_dst_srng = pdev->rxdma_mon_dst_ring.hal_srng; union dp_rx_desc_list_elem_t *head = NULL; union dp_rx_desc_list_elem_t *tail = NULL; - struct dp_srng *dp_rxdma_srng; - struct rx_desc_pool *rx_desc_pool; + uint32_t ppdu_id; + uint32_t rx_bufs_used; #ifdef DP_INTR_POLL_BASED if (!pdev) @@ -687,12 +685,6 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) pdev_id = pdev->pdev_id; mon_dst_srng = pdev->rxdma_mon_dst_ring.hal_srng; -#if 0 - /* Temporary only handle destination ring */ - if (pdev->mon_ppdu_status != DP_PPDU_STATUS_DONE) - return; -#endif - if (!mon_dst_srng) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL Monitor Destination Ring Init \ @@ -713,44 +705,40 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) return; } + ppdu_id = pdev->ppdu_info.com_info.ppdu_id; + rx_bufs_used = 0; while (qdf_likely((rxdma_dst_ring_desc = - hal_srng_dst_peek(hal_soc, mon_dst_srng)))) { - qdf_nbuf_t head_msdu, tail_msdu; - uint32_t rx_bufs_used = 0; - uint32_t npackets, ppdu_id; - head_msdu = (qdf_nbuf_t) NULL; - tail_msdu = (qdf_nbuf_t) NULL; + hal_srng_dst_peek(hal_soc, mon_dst_srng)) && quota--)) { + qdf_nbuf_t head_msdu, tail_msdu; + uint32_t npackets; + head_msdu = (qdf_nbuf_t) NULL; + tail_msdu = (qdf_nbuf_t) NULL; - ppdu_id = pdev->mon_ppdu_id; - rx_bufs_used += dp_rx_mon_mpdu_pop(soc, mac_id, - rxdma_dst_ring_desc, - &head_msdu, &tail_msdu, - &npackets, &ppdu_id, - &head, &tail); -#if 0 - /* Temporary only handle destination ring */ - if (ppdu_id != pdev->mon_ppdu_id) { - pdev->mon_ppdu_status = DP_PPDU_STATUS_START; - break; - } -#endif + rx_bufs_used += dp_rx_mon_mpdu_pop(soc, mac_id, + rxdma_dst_ring_desc, + &head_msdu, &tail_msdu, + &npackets, &ppdu_id, + &head, &tail); - dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); + if (ppdu_id != pdev->ppdu_info.com_info.ppdu_id) { + pdev->mon_ppdu_status = DP_PPDU_STATUS_START; + qdf_mem_zero(&(pdev->ppdu_info.rx_status), + sizeof(pdev->ppdu_info.rx_status)); + break; + } - /* replenish function should be changed to include - * ring pointer */ - dp_rxdma_srng = &pdev->rxdma_mon_buf_ring; - rx_desc_pool = &soc->rx_desc_mon[pdev_id]; + dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); - dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng, - rx_desc_pool, rx_bufs_used, &head, &tail, - HAL_RX_BUF_RBM_SW3_BM); - - rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, - mon_dst_srng); + rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, + mon_dst_srng); } - hal_srng_access_end(hal_soc, mon_dst_srng); + + if (rx_bufs_used) { + dp_rx_buffers_replenish(soc, pdev_id, + &pdev->rxdma_mon_buf_ring, &soc->rx_desc_mon[pdev_id], + rx_bufs_used, &head, &tail, HAL_RX_BUF_RBM_SW3_BM); + } } static QDF_STATUS @@ -940,12 +928,6 @@ static int dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) hal_srng_src_get_next(soc->hal_soc, mon_desc_srng))) { - QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_DEBUG, - "[%s][%d] desc=%p, i=%d, vaddr=%lx, paddr=%lx", - __func__, __LINE__, desc, i, - (unsigned long)vaddr, (unsigned long)paddr); - hal_set_link_desc_addr(desc, i, paddr); num_entries--; num_replenish_buf++; diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 5e87fd654f..2e3d1a6a9d 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -36,7 +36,9 @@ * Return: none */ static inline void -dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id) { +dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, + uint32_t quota) +{ struct dp_pdev *pdev = soc->pdev_list[mac_id]; struct hal_rx_ppdu_info *ppdu_info; qdf_nbuf_t status_nbuf; @@ -73,12 +75,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id) { qdf_nbuf_free(status_nbuf); if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { - pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; - /* Temperary */ - pdev->mon_ppdu_status = - DP_PPDU_STATUS_START; - break; + dp_rx_mon_dest_process(soc, mac_id, quota); } } return; @@ -237,8 +235,8 @@ dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { uint32_t work_done; work_done = dp_rx_mon_status_srng_process(soc, mac_id, quota); - - dp_rx_mon_status_process_tlv(soc, mac_id); + quota -= work_done; + dp_rx_mon_status_process_tlv(soc, mac_id, quota); return work_done; } @@ -255,14 +253,9 @@ dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { */ uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - uint32_t work_done; - - work_done = dp_rx_mon_status_process(soc, mac_id, quota); - - dp_rx_mon_dest_process(soc, mac_id, quota); - - return work_done; + return dp_rx_mon_status_process(soc, mac_id, quota); } + /** * dp_rx_pdev_mon_detach() - detach dp rx for status ring * @pdev: core txrx pdev context @@ -397,7 +390,7 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, hal_rxdma_buff_addr_info_set(rxdma_ring_entry, paddr, (*desc_list)->rx_desc.cookie, owner); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] rx_desc=%p, cookie=%d, nbuf=%p, \ status_buf=%p paddr=%p\n", __func__, __LINE__, &(*desc_list)->rx_desc, @@ -474,6 +467,8 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev) { qdf_nbuf_queue_init(&pdev->rx_status_q); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; + qdf_mem_zero(&(pdev->ppdu_info.rx_status), + sizeof(pdev->ppdu_info.rx_status)); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 27255c187b..0d60efcd37 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -791,7 +791,6 @@ struct dp_pdev { uint8_t operating_channel; qdf_nbuf_queue_t rx_status_q; - uint32_t mon_ppdu_id; uint32_t mon_ppdu_status; struct cdp_mon_status rx_mon_recv_status; diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 14eb550e14..b78854563f 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -32,6 +32,7 @@ HAL_RX_LSB(block, field)) #define HAL_RX_PHY_DATA_RADAR 0x01 +#define HAL_SU_MU_CODING_LDPC 0x01 #define HAL_RX_FCS_LEN (4) #define KEY_EXTIV 0x20 @@ -74,6 +75,17 @@ #define HAL_MAX_UL_MU_USERS 8 +#define HAL_RX_PKT_TYPE_11A 0 +#define HAL_RX_PKT_TYPE_11B 1 +#define HAL_RX_PKT_TYPE_11N 2 +#define HAL_RX_PKT_TYPE_11AC 3 +#define HAL_RX_PKT_TYPE_11AX 4 + +#define HAL_RX_RECEPTION_TYPE_SU 0 +#define HAL_RX_RECEPTION_TYPE_MU_MIMO 1 +#define HAL_RX_RECEPTION_TYPE_OFDMA 2 +#define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3 + enum { HAL_HW_RX_DECAP_FORMAT_RAW = 0, HAL_HW_RX_DECAP_FORMAT_NWIFI, @@ -154,6 +166,16 @@ uint32_t HAL_RX_MON_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) return HAL_RX_GET(rx_attn, RX_ATTENTION_0, PHY_PPDU_ID); } +/* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ +static inline +uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + #define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \ BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \ @@ -286,7 +308,7 @@ uint32 hal_get_rx_msdu_link_desc_size(void) enum { HAL_PKT_TYPE_OFDM = 0, - HAL_CDP_PKT_TYPE_CCK, + HAL_PKT_TYPE_CCK, HAL_PKT_TYPE_HT, HAL_PKT_TYPE_VHT, HAL_PKT_TYPE_HE, @@ -313,73 +335,60 @@ enum { HAL_RX_TYPE_MU_OFDMA_MIMO, }; +/** + * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ static inline -void HAL_RX_MON_HW_DESC_GET_PPDU_START_STATUS(void *hw_desc_addr, - struct cdp_mon_status *rs) +void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr, + struct mon_rx_status *rs) { struct rx_msdu_start *rx_msdu_start; struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; - uint32_t rx_pream_type; - uint32_t rx_sgi; - uint32_t rx_type; - uint32_t rx_bw; -static uint32_t pkt_type_hw_to_cdp[] = { - CDP_PKT_TYPE_OFDM, - CDP_PKT_TYPE_CCK, - CDP_PKT_TYPE_HT, - CDP_PKT_TYPE_VHT, - CDP_PKT_TYPE_HE, - }; + uint32_t reg_value; -static uint32_t sgi_hw_to_cdp[] = { - CDP_SGI_0_8_US, - CDP_SGI_0_4_US, - CDP_SGI_1_6_US, - CDP_SGI_3_2_US, - }; - -static uint32_t rx_type_hw_to_cdp[] = { - CDP_RX_TYPE_SU, - CDP_RX_TYPE_MU_MIMO, - CDP_RX_TYPE_MU_OFDMA, - CDP_RX_TYPE_MU_OFDMA_MIMO, - }; - -static uint32_t rx_bw_hw_to_cdp[] = { - CDP_FULL_RX_BW_20, - CDP_FULL_RX_BW_40, - CDP_FULL_RX_BW_80, - CDP_FULL_RX_BW_160, - }; + static uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; - rs->cdp_rs_tstamp.cdp_tsf = rx_msdu_start->ppdu_start_timestamp; - - rx_pream_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); - rs->cdp_rs_pream_type = pkt_type_hw_to_cdp[rx_pream_type]; - - rs->cdp_rs_user_rssi = HAL_RX_GET(rx_msdu_start, + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, USER_RSSI); - - rs->cdp_rs_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - - rx_sgi = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); - rs->cdp_rs_sgi = sgi_hw_to_cdp[rx_sgi]; - - rs->cdf_rs_rate_mcs = HAL_RX_GET(rx_msdu_start, + rs->mcs = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RATE_MCS); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - rx_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); - rs->cdp_rs_reception_type = rx_type_hw_to_cdp[rx_type]; - - rx_bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEIVE_BANDWIDTH); - - rs->cdp_rs_bw = rx_bw_hw_to_cdp[rx_bw]; - - rs->cdp_rs_nss = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); + switch (reg_value) { + case HAL_RX_PKT_TYPE_11AC: + rs->vht_flags = 1; + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, + RECEIVE_BANDWIDTH); + rs->vht_flag_values2 = 0x01 << reg_value; + rs->vht_flag_values3[0] = rs->mcs << 4; + break; + case HAL_RX_PKT_TYPE_11AX: + rs->he_flags = 1; + break; + default: + break; + } + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ } struct hal_rx_ppdu_user_info { @@ -394,6 +403,7 @@ struct hal_rx_ppdu_common_info { struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; + struct mon_rx_status rx_status; }; static inline uint32_t @@ -404,9 +414,18 @@ hal_get_rx_status_buf_size(void) { static inline uint8_t* hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { - uint32_t tlv_len; + uint32_t tlv_len, tlv_tag; tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); + + /* The actual length of PPDU_END is the combined lenght of many PHY + * TLVs that follow. Skip the TLV header and + * rx_rxpcu_classification_overview that follows the header to get to + * next TLV. + */ + if (tlv_tag == WIFIRX_PPDU_END_E) + tlv_len = sizeof(struct rx_rxpcu_classification_overview); return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len + HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3))); @@ -415,7 +434,7 @@ hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { static inline uint32_t hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) { - uint32_t tlv_tag, user_id, tlv_len; + uint32_t tlv_tag, user_id, tlv_len, value; tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv); @@ -432,6 +451,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) ppdu_info->com_info.ppdu_id = HAL_RX_GET(rx_tlv, RX_PPDU_START_0, PHY_PPDU_ID); + /* TODO: Ensure channel number is set in PHY meta data */ + ppdu_info->rx_status.chan_freq = + HAL_RX_GET(rx_tlv, RX_PPDU_START_1, + SW_PHY_META_DATA); ppdu_info->com_info.ppdu_timestamp = HAL_RX_GET(rx_tlv, RX_PPDU_START_2, PPDU_START_TIMESTAMP); @@ -444,9 +467,16 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "[%s][%d] ppdu_end_e len=%d\n", __func__, __LINE__, tlv_len); + /* This is followed by sub-TLVs of PPDU_END */ break; case WIFIRXPCU_PPDU_END_INFO_E: + ppdu_info->rx_status.tsft = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, + WB_TIMESTAMP_UPPER_32); + ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) | + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0, + WB_TIMESTAMP_LOWER_32); break; case WIFIRX_PPDU_END_USER_STATS_E: @@ -459,8 +489,147 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) return HAL_TLV_STATUS_PPDU_DONE; case WIFIDUMMY_E: - return HAL_TLV_STATUS_DUMMY; + return HAL_TLV_STATUS_PPDU_DONE; + case WIFIPHYRX_HT_SIG_E: + { + uint8_t *ht_sig_info = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HT_SIG_0, + HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS); + value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1, + FEC_CODING); + ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? + 1 : 0; + break; + } + case WIFIPHYRX_VHT_SIG_A_E: + { + uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0, + VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS); + value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, + SU_MU_CODING); + ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? + 1 : 0; + break; + } + case WIFIPHYRX_HE_SIG_A_SU_E: + ppdu_info->rx_status.he_sig_A1 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0, + HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A1 |= + QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU; + /* TODO: Enabling all known bits. Check if this should be + * enabled selectively + */ + ppdu_info->rx_status.he_sig_A1_known = + QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL; + ppdu_info->rx_status.he_sig_A2 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_1, + HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A2_known = + QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL; + break; + case WIFIPHYRX_HE_SIG_A_MU_DL_E: + ppdu_info->rx_status.he_sig_A1 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0, + HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A1 |= + QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU; + ppdu_info->rx_status.he_sig_A1_known = + QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL; + + ppdu_info->rx_status.he_sig_A2 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_1, + HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A2_known = + QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL; + break; + case WIFIPHYRX_HE_SIG_B1_MU_E: + { + uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv + + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0, + HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS))); + + ppdu_info->rx_status.he_sig_b_common_RU[0] = + HAL_RX_GET(he_sig_b1_mu_info, HE_SIG_B1_MU_INFO_0, + RU_ALLOCATION); + + ppdu_info->rx_status.he_sig_b_common_known = + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; + /* TODO: Check on the availability of other fields in + * sig_b_common + */ + break; + } + case WIFIPHYRX_HE_SIG_B2_MU_E: + ppdu_info->rx_status.he_sig_b_user = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0, + HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_b_user_known = + QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; + break; + case WIFIPHYRX_HE_SIG_B2_OFDMA_E: + ppdu_info->rx_status.he_sig_b_user = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0, + HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_b_user_known = + QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; + break; + case WIFIPHYRX_RSSI_LEGACY_E: + { + uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3, + RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_PRI20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT40_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT40_HIGH20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_HIGH20_CHAIN0: %d\n", value); + break; + } case 0: return HAL_TLV_STATUS_PPDU_DONE; @@ -468,6 +637,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) break; } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s TLV type: %d, TLV len:%d\n", + __func__, tlv_tag, tlv_len); + return HAL_TLV_STATUS_PPDU_NOT_DONE; } diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 3df6f3e374..3fe719800e 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -64,7 +64,18 @@ #include "rx_ppdu_end_user_stats.h" #include "rx_ppdu_end_user_stats_ext.h" #include "rx_mpdu_desc_info.h" +#include "rxpcu_ppdu_end_info.h" +#include "phyrx_he_sig_a_su.h" +#include "phyrx_he_sig_a_mu_dl.h" +#include "phyrx_he_sig_b1_mu.h" +#include "phyrx_he_sig_b2_mu.h" +#include "phyrx_he_sig_b2_ofdma.h" +#include "phyrx_vht_sig_a.h" +#include "phyrx_ht_sig.h" #include "tx_msdu_extension.h" +#include "receive_rssi_info.h" +#include "phyrx_pkt_end.h" +#include "phyrx_rssi_legacy.h" #include "wcss_version.h" #include "pld_common.h" #include "rx_msdu_link.h" diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index d78b30a6b4..cef0e0f14b 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -178,6 +178,18 @@ struct mon_rx_status { uint8_t he_sig_b_common_RU[4]; }; +/* Masks for HE SIG known fields in mon_rx_status structure */ +#define QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL 0x000007ff +#define QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL 0x000003ff +#define QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL 0x00000ffd +#define QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL 0x00000ffd +#define QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0 0x00000001 +#define QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL 0x00fe0000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU 0x00000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_EXT_SU 0x40000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU 0x80000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_TRIG 0xc0000000 + /* DHCP Related Mask */ #define QDF_DHCP_OPTION53 (0x35) #define QDF_DHCP_OPTION53_LENGTH (1) diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 88665521dc..99141596dd 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -2752,7 +2752,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, qdf_print("ERROR: not enough space to update radiotap\n"); return 0; } - qdf_nbuf_pull_head(nbuf, headroom_sz - rtap_len); + qdf_nbuf_push_head(nbuf, rtap_len); qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len); return rtap_len; } From 274eb9e76b441013aab010518ab7ae22d29c32d5 Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Tue, 16 May 2017 18:59:10 +0530 Subject: [PATCH 17/26] qcacmn: Temporary WAR for Multicast echo check in host This is a temporary WAR in host for multicast loopback check until we finalize on exact design, and host or firmware will take care of this Change-Id: I4d2d1b0f5d2a78d4c8716740b74c4fee22c28e96 CRs-Fixed: 2039038 --- dp/wifi3.0/dp_rx.c | 9 ++++++-- dp/wifi3.0/dp_rx_err.c | 30 ++++++++++++++++++++++----- dp/wifi3.0/dp_tx.c | 42 ++++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_types.h | 11 ++++++++++ qdf/linux/src/i_qdf_nbuf.h | 18 +++------------- 5 files changed, 88 insertions(+), 22 deletions(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 64bfb92cdb..b49cb6aecb 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -337,6 +337,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) { memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); len = qdf_nbuf_len(nbuf); + qdf_nbuf_set_fctx_type(nbuf, (void *)NULL, + CB_FTYPE_INTRABSS_FWD); if (!dp_tx_send(sa_peer->vdev, nbuf)) { DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts, 1, len); @@ -363,9 +365,12 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, return false; memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb)); len = qdf_nbuf_len(nbuf_copy); - if (dp_tx_send(sa_peer->vdev, nbuf_copy)) + qdf_nbuf_set_fctx_type(nbuf_copy, (void *)NULL, + CB_FTYPE_INTRABSS_FWD); + if (dp_tx_send(sa_peer->vdev, nbuf_copy)) { + DP_STATS_INC_PKT(sa_peer, rx.intra_bss.fail, 1, len); qdf_nbuf_free(nbuf_copy); - else + } else DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts, 1, len); } /* return false as we have to still send the original pkt diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 6a65be9369..eedda2ff81 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -224,6 +224,9 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, uint16_t peer_id = 0xFFFF; struct dp_peer *peer = NULL; uint32_t sgi, rate_mcs, tid; + uint8_t count; + struct mect_entry *mect_entry; + uint8_t *nbuf_data = NULL; rx_bufs_used++; @@ -293,11 +296,6 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, "%s: %d, SGI: %d, rate_mcs: %d, tid: %d", __func__, __LINE__, sgi, rate_mcs, tid); - /* WDS Source Port Learning */ - if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet) && - (vdev->wds_enabled)) - dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf); - /* * Advance the packet start pointer by total size of * pre-header TLV's @@ -307,6 +305,28 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, if (l2_hdr_offset) qdf_nbuf_pull_head(nbuf, l2_hdr_offset); + nbuf_data = qdf_nbuf_data(nbuf); + for (count = 0; count < soc->mect_cnt; count++) { + mect_entry = &soc->mect_table[count]; + mect_entry->ts = jiffies_64; + if (!(memcmp(mect_entry->mac_addr, &nbuf_data[DP_MAC_ADDR_LEN], + DP_MAC_ADDR_LEN))) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_INFO, + FL("received pkt with same src MAC")); + + /* Drop & free packet */ + qdf_nbuf_free(nbuf); + /* Statistics */ + goto fail; + } + } + + /* WDS Source Port Learning */ + if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet) && + (vdev->wds_enabled)) + dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf); + if (hal_rx_mpdu_start_mpdu_qos_control_valid_get( rx_desc->rx_buf_start)) { /* TODO: Assuming that qos_control_valid also indicates diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 09f2a33857..85e31dd226 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1397,11 +1397,53 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) struct dp_tx_msdu_info_s msdu_info; struct dp_tx_seg_info_s seg_info; struct dp_vdev *vdev = (struct dp_vdev *) vap_dev; + struct dp_soc *soc = vdev->pdev->soc; uint16_t peer_id = HTT_INVALID_PEER; + uint8_t count; + uint8_t found = 0; + uint8_t oldest_mec_entry_idx = 0; + uint64_t oldest_mec_ts = 0; + struct mect_entry *mect_entry; qdf_mem_set(&msdu_info, sizeof(msdu_info), 0x0); qdf_mem_set(&seg_info, sizeof(seg_info), 0x0); + if (qdf_nbuf_get_ftype(nbuf) == CB_FTYPE_INTRABSS_FWD) + goto out; + + eh = (struct ether_header *)qdf_nbuf_data(nbuf); + if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) { + for (count = 0; count < soc->mect_cnt; count++) { + mect_entry = &soc->mect_table[count]; + if (!memcmp(mect_entry->mac_addr, eh->ether_shost, + DP_MAC_ADDR_LEN)) { + found = 1; + break; + } + + if (!oldest_mec_ts) { + oldest_mec_entry_idx = count; + oldest_mec_ts = mect_entry->ts; + } else if (mect_entry->ts < oldest_mec_ts) { + oldest_mec_entry_idx = count; + oldest_mec_ts = mect_entry->ts; + } + } + + if (!found) { + if (count >= DP_MAX_MECT_ENTRIES) + count = oldest_mec_entry_idx; + else + soc->mect_cnt++; + + mect_entry = &soc->mect_table[count]; + mect_entry->ts = jiffies_64; + memcpy(mect_entry->mac_addr, eh->ether_shost, + DP_MAC_ADDR_LEN); + } + } + +out: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s , skb %0x:%0x:%0x:%0x:%0x:%0x\n", __func__, nbuf->data[0], nbuf->data[1], nbuf->data[2], diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 0d60efcd37..7a472afd23 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -87,6 +87,7 @@ #define MAX_TX_HW_QUEUES 3 #define DP_MAX_INTERRUPT_CONTEXTS 8 +#define DP_MAX_MECT_ENTRIES 64 struct dp_soc_cmn; struct dp_pdev; @@ -378,6 +379,13 @@ struct dp_ast_entry { TAILQ_ENTRY(dp_ast_entry) ast_entry_elem; }; +struct mect_entry { + uint8_t idx; + uint8_t valid; + uint8_t mac_addr[6]; + uint64_t ts; +}; + /* SOC level structure for data path */ struct dp_soc { /* Common base structure - Should be the first member */ @@ -612,6 +620,9 @@ struct dp_soc { #endif qdf_list_t reo_desc_freelist; qdf_spinlock_t reo_desc_freelist_lock; + struct mect_entry mect_table[DP_MAX_MECT_ENTRIES]; + uint8_t mect_cnt; + /* Obj Mgr SoC */ struct wlan_objmgr_psoc *psoc; qdf_nbuf_t invalid_peer_head_msdu; diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 1812b8a2bd..df162f3c1b 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -569,28 +569,16 @@ void __qdf_nbuf_num_frags_init(struct sk_buff *skb) QDF_NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) = 0; } -#ifdef CONFIG_MCL typedef enum { CB_FTYPE_INVALID = 0, CB_FTYPE_MCAST2UCAST = 1, CB_FTYPE_TSO = 2, CB_FTYPE_TSO_SG = 3, CB_FTYPE_SG = 4, + CB_FTYPE_INTRABSS_FWD = 5, + CB_FTYPE_RX_INFO = 6, + CB_FTYPE_MESH_RX_INFO = 7, } CB_FTYPE; -#else -typedef enum { - CB_FTYPE_INVALID = 0, - CB_FTYPE_MCAST2UCAST = 1, - CB_FTYPE_TSO = 2, - CB_FTYPE_TSO_SG = 3, - CB_FTYPE_SG = 4, -#if ATH_DATA_RX_INFO_EN - CB_FTYPE_RX_INFO = 5, -#else - CB_FTYPE_MESH_RX_INFO = 5, -#endif -} CB_FTYPE; -#endif /* * prototypes. Implemented in qdf_nbuf.c From 20802b298f24da1e21f00807465702bfb463183a Mon Sep 17 00:00:00 2001 From: Balamurugan Mahalingam Date: Tue, 2 May 2017 19:11:38 +0530 Subject: [PATCH 18/26] qcacmn: add target_ce_config and target_service_to_ce_map for ipq8074 Populating the data structure target_ce_config and target_service_to_cemap for IPQ8074 platform. These two data structure will be passed to the Q6 target over QMI later during wifi up for the target side initialization. CRs-Fixed: 2051118 Change-Id: I5cbe62594b66dab18f01968b9c15d6bfaf93b585 --- hif/src/ce/ce_assignment.h | 17 ++++++++--------- hif/src/ce/ce_main.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h index a32a7cce3c..7dfbe3caa5 100644 --- a/hif/src/ce/ce_assignment.h +++ b/hif/src/ce/ce_assignment.h @@ -600,21 +600,20 @@ static struct CE_pipe_config target_ce_config_wlan_qca8074[] = { (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, /* NB: 50% of src nentries, since tx has 2 frags */ /* ipa_uc->target */ - { /* CE5 */ 5, PIPEDIR_OUT, 1024, 64, - (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + { /* CE5 */ 5, PIPEDIR_INOUT_H2H, 0, 0, 0, 0,}, /* Reserved for target autonomous HIF_memcpy */ - { /* CE6 */ 6, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 65535, 64, 0,}, /* CE7 used only by Host */ - { /* CE7 */ 7, PIPEDIR_INOUT_H2H, 0, 0, - (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + { /* CE7 */ 7, PIPEDIR_OUT, 32, 2048, + 8192, 0,}, /* CE8 used only by IPA */ - { /* CE8 */ 8, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + { /* CE8 */ 8, PIPEDIR_INOUT, 32, 65535, 112, 0,}, /* CE9 target->host HTT */ - { /* CE9 */ 9, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + { /* CE9 */ 9, PIPEDIR_OUT, 32, 2048, 8192, 0,}, /* CE10 target->host HTT */ - { /* CE10 */ 10, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + { /* CE10 */ 10, PIPEDIR_INOUT_H2H, 0, 0, 0, 0,}, /* Target -> host PKTLOG */ - { /* CE11 */ 11, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + { /* CE11 */ 11, PIPEDIR_IN, 32, 2048, 48, 0,}, }; static struct CE_attr host_ce_config_wlan_qca8074_pci[] = { diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index c03c2d1125..e713f0deaa 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -404,6 +404,29 @@ static struct service_to_pipe target_service_to_ce_map_wlan[] = { /* PIPEDIR_OUT = HOST to Target */ /* PIPEDIR_IN = TARGET to HOST */ +static struct service_to_pipe target_service_to_ce_map_qca8074[] = { + { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BK_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BK_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, + { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, + { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, + { WMI_CONTROL_SVC_WMAC1, PIPEDIR_OUT, 7}, + { WMI_CONTROL_SVC_WMAC1, PIPEDIR_IN, 2}, + { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 1, }, + { HTC_RAW_STREAMS_SVC, PIPEDIR_OUT, 0}, + { HTC_RAW_STREAMS_SVC, PIPEDIR_IN, 1 }, + { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, + { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, + /* (Additions here) */ + { 0, 0, 0, }, +}; + static struct service_to_pipe target_service_to_ce_map_qca6290[] = { { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, { WMI_DATA_VO_SVC, PIPEDIR_IN , 2, }, @@ -579,6 +602,11 @@ static void hif_select_service_to_pipe_map(struct hif_softc *scn, *sz_tgt_svc_map_to_use = sizeof(target_service_to_ce_map_qca6290); break; + case TARGET_TYPE_QCA8074: + *tgt_svc_map_to_use = target_service_to_ce_map_qca8074; + *sz_tgt_svc_map_to_use = + sizeof(target_service_to_ce_map_qca8074); + break; } } } From c2cb427e7f62da8fd9b0cc064c3f8fe0c924c910 Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Tue, 23 May 2017 10:09:26 +0530 Subject: [PATCH 19/26] qcacmn: Print Rx Decrypt error statistics Add support to print Rx Decrypt errors as part of DP statistics Change-Id: I03f485003dd1e0d95db21cb25b2973fa26838982 CRs-Fixed: 2004658 --- dp/wifi3.0/dp_main.c | 4 ++++ dp/wifi3.0/hal_rx.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 5caf47e2b0..480d4b405e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2863,6 +2863,9 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_TRACE_STATS(FATAL, "SOC Rx Stats:\n"); DP_TRACE_STATS(FATAL, "Errors:\n"); + DP_TRACE_STATS(FATAL, "Rx Decrypt Errors = %d", + (soc->stats.rx.err.rxdma_error[HAL_RXDMA_ERR_DECRYPT] + + soc->stats.rx.err.rxdma_error[HAL_RXDMA_ERR_TKIP_MIC])); DP_TRACE_STATS(FATAL, "Invalid RBM = %d", soc->stats.rx.err.invalid_rbm); DP_TRACE_STATS(FATAL, "Invalid Vdev = %d", @@ -2873,6 +2876,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc) soc->stats.rx.err.rx_invalid_peer.num); DP_TRACE_STATS(FATAL, "HAL Ring Access Fail = %d", soc->stats.rx.err.hal_ring_access_fail); + for (i = 0; i < MAX_RXDMA_ERRORS; i++) { index += qdf_snprint(&rxdma_error[index], DP_RXDMA_ERR_LENGTH - index, diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index c463143b7d..501baf84c9 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -1684,6 +1684,47 @@ enum hal_reo_error_code { HAL_REO_ERR_QUEUE_DESC_BLOCKED_SET }; +/** + * enum hal_rxdma_error_code: Code describing the type of RxDMA error detected + * + * @HAL_RXDMA_ERR_OVERFLOW: MPDU frame is not complete due to a FIFO overflow + * @ HAL_RXDMA_ERR_OVERFLOW : MPDU frame is not complete due to a FIFO + * overflow + * @ HAL_RXDMA_ERR_MPDU_LENGTH : MPDU frame is not complete due to receiving + * incomplete + * MPDU from the PHY + * @ HAL_RXDMA_ERR_FCS : FCS check on the MPDU frame failed + * @ HAL_RXDMA_ERR_DECRYPT : Decryption error + * @ HAL_RXDMA_ERR_TKIP_MIC : TKIP MIC error + * @ HAL_RXDMA_ERR_UNECRYPTED : Received a frame that was expected to be + * encrypted but wasn’t + * @ HAL_RXDMA_ERR_MSDU_LEN : MSDU related length error + * @ HAL_RXDMA_ERR_MSDU_LIMIT : Number of MSDUs in the MPDUs exceeded + * the max allowed + * @ HAL_RXDMA_ERR_WIFI_PARSE : wifi parsing error + * @ HAL_RXDMA_ERR_AMSDU_PARSE : Amsdu parsing error + * @ HAL_RXDMA_ERR_SA_TIMEOUT : Source Address search timeout + * @ HAL_RXDMA_ERR_DA_TIMEOUT : Destination Address search timeout + * @ HAL_RXDMA_ERR_FLOW_TIMEOUT : Flow Search Timeout + * @ HAL_RXDMA_ERR_FLUSH_REQUEST : RxDMA FIFO Flush request + */ +enum hal_rxdma_error_code { + HAL_RXDMA_ERR_OVERFLOW = 0, + HAL_RXDMA_ERR_MPDU_LENGTH, + HAL_RXDMA_ERR_FCS, + HAL_RXDMA_ERR_DECRYPT, + HAL_RXDMA_ERR_TKIP_MIC, + HAL_RXDMA_ERR_UNECRYPTED, + HAL_RXDMA_ERR_MSDU_LEN, + HAL_RXDMA_ERR_MSDU_LIMIT, + HAL_RXDMA_ERR_WIFI_PARSE, + HAL_RXDMA_ERR_AMSDU_PARSE, + HAL_RXDMA_ERR_SA_TIMEOUT, + HAL_RXDMA_ERR_DA_TIMEOUT, + HAL_RXDMA_ERR_FLOW_TIMEOUT, + HAL_RXDMA_ERR_FLUSH_REQUEST +}; + #define HAL_RX_REO_ERROR_GET(reo_desc) (((*(((uint32_t *) reo_desc)+ \ (REO_DESTINATION_RING_7_REO_ERROR_CODE_OFFSET >> 2))) & \ REO_DESTINATION_RING_7_REO_ERROR_CODE_MASK) >> \ From 3d8e1e86558db7b3208bb19d177863c92ce7454e Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Mon, 29 May 2017 14:29:31 +0530 Subject: [PATCH 20/26] qcacmn: Enable interrupts for DP Rx Error release and REO status rings Initialize correct mask values to enables Rx error and status ring interrupts Change-Id: I717fbea492f12d983fb57d964996f4b79c73cb38 CRs-Fixed: 2004658 --- dp/wifi3.0/dp_main.c | 22 ++++++++++++++++++++++ hif/inc/hif.h | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 480d4b405e..32f27d004f 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -422,9 +422,21 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) int rx_mon_mask = wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, i); + /* + * Mapping the exception/status rings to IRQ Group 0 (CPU 0). + * Later add wlan_cfg interface for these masks + */ + int rx_err_ring_mask = 0x1; + int rx_wbm_rel_ring_mask = 0x1; + int reo_status_ring_mask = 0x1; + soc->intr_ctx[i].tx_ring_mask = tx_mask; soc->intr_ctx[i].rx_ring_mask = rx_mask; soc->intr_ctx[i].rx_mon_ring_mask = rx_mon_mask; + soc->intr_ctx[i].rx_err_ring_mask = rx_err_ring_mask; + soc->intr_ctx[i].rx_wbm_rel_ring_mask = rx_wbm_rel_ring_mask; + soc->intr_ctx[i].reo_status_ring_mask = reo_status_ring_mask; + soc->intr_ctx[i].soc = soc; num_irq = 0; @@ -446,6 +458,16 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) (rxdma2host_monitor_destination_mac1 - j); } + + if (rx_wbm_rel_ring_mask & (1 << j)) + irq_id_map[num_irq++] = wbm2host_rx_release; + + if (rx_err_ring_mask & (1 << j)) + irq_id_map[num_irq++] = reo2host_exception; + + if (reo_status_ring_mask & (1 << j)) + irq_id_map[num_irq++] = reo2host_status; + } diff --git a/hif/inc/hif.h b/hif/inc/hif.h index a7a45cc9a6..c235c53e86 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -122,7 +122,7 @@ enum hif_ic_irq { host2rxdma_monitor_ring3, host2rxdma_monitor_ring2, host2rxdma_monitor_ring1, - reo2ost_exception, + reo2host_exception, wbm2host_rx_release, reo2host_status, reo2host_destination_ring4, From 9c9a2871a7bb07e9b265bf741ac19552e4272a80 Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Wed, 31 May 2017 10:06:34 +0530 Subject: [PATCH 21/26] qcacmn: Add missing lock initialization for tx_lock used for me_buf_pool CRs-Fixed: 2004658 Change-Id: I930fc823ce2b4d4a91f0bc949291d199ba783862 --- dp/wifi3.0/dp_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 32f27d004f..beb18f4dc9 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1175,6 +1175,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, TAILQ_INIT(&pdev->vdev_list); pdev->vdev_count = 0; + qdf_spinlock_create(&pdev->tx_mutex); qdf_spinlock_create(&pdev->neighbour_peer_mutex); TAILQ_INIT(&pdev->neighbour_peers_list); @@ -1370,6 +1371,7 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force) dp_rx_pdev_mon_detach(pdev); dp_neighbour_peers_detach(pdev); + qdf_spinlock_destroy(&pdev->tx_mutex); /* Setup per PDEV REO rings if configured */ if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) { From 84e3394a3ce52149794d531334e62c915780b31c Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Thu, 1 Jun 2017 07:34:51 +0530 Subject: [PATCH 22/26] qcacmn: Add a check for target_type for accessing CE legacy registers In ce_services, check if target type is srng based and access legacy registers only if it is not, for APIs which are common between legacy and srng-based targets Change-Id: I515026cd9b6d14accd4c219c6d03134a36cc3db6 --- hif/src/ce/ce_service.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 86cdcc8909..e511af4968 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -2106,12 +2106,15 @@ more_watermarks: more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { goto more_completions; } else { - HIF_ERROR( - "%s:Potential infinite loop detected during Rx processing nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x", - __func__, CE_state->dest_ring->nentries_mask, - CE_state->dest_ring->sw_index, - CE_DEST_RING_READ_IDX_GET(scn, + if (!ce_srng_based(scn)) { + HIF_ERROR( + "%s:Potential infinite loop detected during Rx processing nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x", + __func__, + CE_state->dest_ring->nentries_mask, + CE_state->dest_ring->sw_index, + CE_DEST_RING_READ_IDX_GET(scn, CE_state->ctrl_addr)); + } } } @@ -2122,12 +2125,15 @@ more_watermarks: more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { goto more_completions; } else { - HIF_ERROR( - "%s:Potential infinite loop detected during send completion nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x", - __func__, CE_state->src_ring->nentries_mask, - CE_state->src_ring->sw_index, - CE_SRC_RING_READ_IDX_GET(scn, + if (!ce_srng_based(scn)) { + HIF_ERROR( + "%s:Potential infinite loop detected during send completion nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x", + __func__, + CE_state->src_ring->nentries_mask, + CE_state->src_ring->sw_index, + CE_SRC_RING_READ_IDX_GET(scn, CE_state->ctrl_addr)); + } } } From a3088d9a346443c8909e576d12f85ea921b8365e Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Sat, 3 Jun 2017 00:16:22 +0530 Subject: [PATCH 23/26] qcacmn: WDS changes to address multi-radio scenario Because of mult-radio changes where we have soc and scn structures modified we need to address the same for WDS Change-Id: I63f95d93ac15cdbcdd2b05cb80ce364115e9c16e --- dp/wifi3.0/dp_rx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index d5715da175..67e086fade 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -343,13 +343,13 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, if (!hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr)) { ret = soc->cdp_soc.ol_ops->peer_add_wds_entry( - soc->osif_soc, + ta_peer->vdev->pdev->osif_pdev, wds_src_mac, ta_peer->mac_addr.raw, flags); } else if (sa_sw_peer_id != ta_peer->peer_ids[0]) { ret = soc->cdp_soc.ol_ops->peer_update_wds_entry( - soc->osif_soc, + ta_peer->vdev->pdev->osif_pdev, wds_src_mac, ta_peer->mac_addr.raw, flags); From 93f633c3942d8eee29648fb77a5bb3b59255ea88 Mon Sep 17 00:00:00 2001 From: Karunakar Dasineni Date: Fri, 2 Jun 2017 19:04:46 -0700 Subject: [PATCH 24/26] qcacmn: Enable REO queue stats Query REO queue stats from HW and print as part of host peer stats. Change-Id: I817be3b293e684f0fa3a0b3154f618de0245681f CRs-Fixed: 2057908 --- dp/wifi3.0/dp_internal.h | 1 + dp/wifi3.0/dp_main.c | 8 ++++ dp/wifi3.0/dp_peer.c | 91 ++++++++++++++++++++++++++++++++++++++++ hal/wifi3.0/hal_reo.h | 3 +- 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 383c004d71..5feacf88c5 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -284,4 +284,5 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, uint32_t config_param_1, uint32_t config_param_2, uint32_t config_param_3); void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf); +int dp_peer_rxtid_stats(struct dp_peer *peer); #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index beb18f4dc9..117634a0e8 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3373,7 +3373,14 @@ dp_get_host_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr) peer = (struct dp_peer *)dp_find_peer_by_addr(pdev_handle, mac_addr, &local_id); + if (!peer) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: Invalid peer\n", __func__); + return; + } + dp_print_peer_stats(peer); + dp_peer_rxtid_stats(peer); return; } @@ -3416,6 +3423,7 @@ dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, config_param0, config_param1, config_param2, config_param3); + } /* diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 646a809809..59d7ed82c4 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -318,6 +318,69 @@ int dp_peer_find_attach(struct dp_soc *soc) return 0; /* success */ } +static void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt, + union hal_reo_status *reo_status) +{ + struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; + struct hal_reo_queue_status *queue_status = &(reo_status->queue_status); + + if (queue_status->header.status != HAL_REO_CMD_SUCCESS) { + DP_TRACE_STATS(FATAL, "REO stats failure %d for TID %d\n", + queue_status->header.status, rx_tid->tid); + return; + } + + DP_TRACE_STATS(FATAL, "REO queue stats (TID: %d): \n" + "ssn: %d\n" + "curr_idx : %d\n" + "pn_31_0 : %08x\n" + "pn_63_32 : %08x\n" + "pn_95_64 : %08x\n" + "pn_127_96 : %08x\n" + "last_rx_enq_tstamp : %08x\n" + "last_rx_deq_tstamp : %08x\n" + "rx_bitmap_31_0 : %08x\n" + "rx_bitmap_63_32 : %08x\n" + "rx_bitmap_95_64 : %08x\n" + "rx_bitmap_127_96 : %08x\n" + "rx_bitmap_159_128 : %08x\n" + "rx_bitmap_191_160 : %08x\n" + "rx_bitmap_223_192 : %08x\n" + "rx_bitmap_255_224 : %08x\n" + "curr_mpdu_cnt : %d\n" + "curr_msdu_cnt : %d\n" + "fwd_timeout_cnt : %d\n" + "fwd_bar_cnt : %d\n" + "dup_cnt : %d\n" + "frms_in_order_cnt : %d\n" + "bar_rcvd_cnt : %d\n" + "mpdu_frms_cnt : %d\n" + "msdu_frms_cnt : %d\n" + "total_byte_cnt : %d\n" + "late_recv_mpdu_cnt : %d\n" + "win_jump_2k : %d\n" + "hole_cnt : %d\n", + rx_tid->tid, + queue_status->ssn, queue_status->curr_idx, + queue_status->pn_31_0, queue_status->pn_63_32, + queue_status->pn_95_64, queue_status->pn_127_96, + queue_status->last_rx_enq_tstamp, + queue_status->last_rx_deq_tstamp, + queue_status->rx_bitmap_31_0, queue_status->rx_bitmap_63_32, + queue_status->rx_bitmap_95_64, queue_status->rx_bitmap_127_96, + queue_status->rx_bitmap_159_128, + queue_status->rx_bitmap_191_160, + queue_status->rx_bitmap_223_192, + queue_status->rx_bitmap_255_224, + queue_status->curr_mpdu_cnt, queue_status->curr_msdu_cnt, + queue_status->fwd_timeout_cnt, queue_status->fwd_bar_cnt, + queue_status->dup_cnt, queue_status->frms_in_order_cnt, + queue_status->bar_rcvd_cnt, queue_status->mpdu_frms_cnt, + queue_status->msdu_frms_cnt, queue_status->total_cnt, + queue_status->late_recv_mpdu_cnt, queue_status->win_jump_2k, + queue_status->hole_cnt); +} + static inline void dp_peer_find_add_id(struct dp_soc *soc, uint8_t *peer_mac_addr, uint16_t peer_id, uint16_t hw_peer_id, uint8_t vdev_id) @@ -1536,3 +1599,31 @@ uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle, qdf_mem_copy(peer_mac, peer->mac_addr.raw, 6); return peer->vdev->vdev_id; } + +/** + * dp_peer_rxtid_stats: Retried Rx TID (REO queue) stats from HW + * @peer: DP peer handle + * + * Return: 0 on success, error code on failure + */ +int dp_peer_rxtid_stats(struct dp_peer *peer) +{ + struct dp_soc *soc = peer->vdev->pdev->soc; + struct hal_reo_cmd_params params; + int i; + + qdf_mem_zero(¶ms, sizeof(params)); + for (i = 0; i < DP_MAX_TIDS; i++) { + struct dp_rx_tid *rx_tid = &peer->rx_tid[i]; + if (rx_tid->hw_qdesc_vaddr_unaligned != NULL) { + params.std.need_status = 1; + params.std.addr_lo = + rx_tid->hw_qdesc_paddr & 0xffffffff; + params.std.addr_hi = + (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; + dp_reo_send_cmd(soc, CMD_GET_QUEUE_STATS, ¶ms, + dp_rx_tid_stats_cb, rx_tid); + } + } + return 0; +} diff --git a/hal/wifi3.0/hal_reo.h b/hal/wifi3.0/hal_reo.h index b34f55f27a..8986f43794 100644 --- a/hal/wifi3.0/hal_reo.h +++ b/hal/wifi3.0/hal_reo.h @@ -136,7 +136,8 @@ enum reo_thres_index_reg { enum reo_cmd_exec_status { HAL_REO_CMD_SUCCESS = 0, HAL_REO_CMD_BLOCKED = 1, - HAL_REO_CMD_FAILED = 2 + HAL_REO_CMD_FAILED = 2, + HAL_REO_CMD_RESOURCE_BLOCKED = 3 }; /** From 5379474f6982c744ff147460ed0c64e764086101 Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Sat, 3 Jun 2017 11:24:32 +0530 Subject: [PATCH 25/26] qcacmn: Enabled asserts in Rx error path Enable qdf_assert on rx error path to detect corruption issues. Also add a magic word in rx_desc and compare on rx indications to detect any corruption issues early in the path Change-Id: I4df1220f19c891928f9687f40de6f2118b530db2 CRs-Fixed: 2004658 --- dp/wifi3.0/dp_rx.c | 15 +++++++++++- dp/wifi3.0/dp_rx.h | 5 ++++ dp/wifi3.0/dp_rx_err.c | 53 ++++++++++++++++++++++++++++-------------- dp/wifi3.0/hal_rx.h | 4 ---- 4 files changed, 55 insertions(+), 22 deletions(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index b49cb6aecb..617583136f 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -29,6 +29,19 @@ #include "dp_internal.h" #include "dp_rx_mon.h" +#ifdef RX_DESC_DEBUG_CHECK +static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf) +{ + rx_desc->magic = DP_RX_DESC_MAGIC; + rx_desc->nbuf = nbuf; +} +#else +static inline void dp_rx_desc_prep(struct dp_rx_desc *rx_desc, qdf_nbuf_t nbuf) +{ + rx_desc->nbuf = nbuf; +} +#endif + /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization @@ -160,7 +173,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, next = (*desc_list)->next; - (*desc_list)->rx_desc.nbuf = rx_netbuf; + dp_rx_desc_prep(&((*desc_list)->rx_desc), rx_netbuf); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "rx_netbuf=%p, buf=%p, paddr=0x%llx, cookie=%d\n", diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 67e086fade..447c514a32 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -45,6 +45,8 @@ (((_peer_metadata) & DP_PEER_METADATA_VDEV_ID_MASK) \ >> DP_PEER_METADATA_VDEV_ID_SHIFT) +#define DP_RX_DESC_MAGIC 0xdec0de + /** * struct dp_rx_desc * @@ -65,6 +67,9 @@ struct dp_rx_desc { uint8_t *rx_buf_start; uint32_t cookie; uint8_t pool_id; +#ifdef RX_DESC_DEBUG_CHECK + uint32_t magic; +#endif }; #define RX_DESC_COOKIE_INDEX_SHIFT 0 diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index eedda2ff81..cfd054eb44 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -31,6 +31,22 @@ #include "dp_rx_defrag.h" #include /* LLC_SNAP_HDR_LEN */ +#ifdef RX_DESC_DEBUG_CHECK +static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc) +{ + if (qdf_unlikely(rx_desc->magic != DP_RX_DESC_MAGIC)) { + return false; + } + rx_desc->magic = 0; + return true; +} +#else +static inline bool dp_rx_desc_check_magic(struct dp_rx_desc *rx_desc) +{ + return true; +} +#endif + /** * dp_rx_msdus_drop() - Drops all MSDU's per MPDU * @@ -46,10 +62,10 @@ * Return: uint32_t: No. of elements processed */ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, - struct hal_rx_mpdu_desc_info *mpdu_desc_info, - union dp_rx_desc_list_elem_t **head, - union dp_rx_desc_list_elem_t **tail, - uint32_t quota) + struct hal_rx_mpdu_desc_info *mpdu_desc_info, + union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail, + uint32_t quota) { uint32_t rx_bufs_used = 0; void *link_desc_va; @@ -72,6 +88,13 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, qdf_assert(rx_desc); + if (!dp_rx_desc_check_magic(rx_desc)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid rx_desc cookie=%d"), + msdu_list.sw_cookie[i]); + return rx_bufs_used; + } + rx_bufs_used++; /* Just free the buffers */ @@ -653,12 +676,20 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie); qdf_assert(rx_desc); + if (!dp_rx_desc_check_magic(rx_desc)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid rx_desc cookie=%d"), + rx_buf_cookie); + continue; + } + /* XXX */ buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc); + /* * For WBM ring, expect only MSDU buffers */ - qdf_assert(buf_type == HAL_RX_WBM_BUF_TYPE_REL_BUF); + qdf_assert_always(buf_type == HAL_RX_WBM_BUF_TYPE_REL_BUF); if (wbm_err_src == HAL_RX_WBM_ERR_SRC_REO) { @@ -726,18 +757,6 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) } } else { /* Should not come here */ - rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc); - rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie); - - qdf_assert(rx_desc); - - qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf, - QDF_DMA_BIDIRECTIONAL); - - rx_desc->rx_buf_start = qdf_nbuf_data(rx_desc->nbuf); - hal_rx_dump_pkt_tlvs(rx_desc->rx_buf_start, - QDF_TRACE_LEVEL_INFO); - qdf_assert(0); } diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index 501baf84c9..cb53401274 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -1957,10 +1957,6 @@ enum hal_rx_wbm_rxdma_push_reason { HAL_RX_BUF_COOKIE_GET(&((struct wbm_release_ring *) \ wbm_desc)->released_buff_or_desc_addr_info) -#define HAL_RX_WBM_BUF_COOKIE_GET(wbm_desc) \ - HAL_RX_BUF_COOKIE_GET(&((struct wbm_release_ring *) \ - wbm_desc)->released_buff_or_desc_addr_info) - /** * hal_rx_dump_rx_attention_tlv: dump RX attention TLV in structured * humman readable format. From 6b0d2a800c6160dd8f4af3f7d0ec85d1bf6b563a Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Fri, 9 Jun 2017 04:46:32 +0530 Subject: [PATCH 26/26] qcacmn: Add a configure interface to get max_peers from OL_IF to DP Currently max_peer value is hardcoded with DP wlan_cfg. This change adds a generic interface to obtain a configuration parameter from OL_IF and store in DP Change-Id: Id437ab3bcd02fb1cbcbe8b56d55d19780af87066 CRs-Fixed: 2004658 --- dp/inc/cdp_txrx_cfg.h | 5 +++++ dp/inc/cdp_txrx_cmn_struct.h | 9 +++++++++ dp/inc/cdp_txrx_ops.h | 1 + dp/wifi3.0/dp_main.c | 10 ++++++++++ wlan_cfg/wlan_cfg.c | 10 ++++++++-- wlan_cfg/wlan_cfg.h | 3 +++ 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dp/inc/cdp_txrx_cfg.h b/dp/inc/cdp_txrx_cfg.h index b9715a56c1..d5ef3eb7f9 100644 --- a/dp/inc/cdp_txrx_cfg.h +++ b/dp/inc/cdp_txrx_cfg.h @@ -254,4 +254,9 @@ static inline void cdp_cfg_set_flow_steering(ol_txrx_soc_handle soc, return; } + +static inline void cdp_cfg_get_max_peer_id(ol_txrx_soc_handle soc, + struct cdp_cfg *cfg_pdev) +{ +} #endif /* _CDP_TXRX_CFG_H_ */ diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 2a7d2c3f7b..dba86835a4 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -89,6 +89,15 @@ WME_AC_VO) #define CDP_MAX_RX_RINGS 4 + +/* + * DP configuration parameters + */ +enum cdp_cfg_param_type { + CDP_CFG_MAX_PEER_ID, + CDP_CFG_NUM_PARAMS +}; + /* * htt_dbg_stats_type - * bit positions for each stats type within a stats type bitmask diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 2d7ef00cb9..c35002d86a 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -615,6 +615,7 @@ struct ol_if_ops { uint8_t vdev_id, uint8_t *peer_mac_addr); int (*peer_unmap_event)(void *ol_soc_handle, uint16_t peer_id); + int (*get_dp_cfg_param)(void *ol_soc_handle, enum cdp_cfg_param_type param_num); /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 117634a0e8..6efeee3164 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4037,6 +4037,16 @@ void *dp_soc_attach_wifi3(void *osif_soc, void *hif_handle, FL("wlan_cfg_soc_attach failed")); goto fail2; } + + if (soc->cdp_soc.ol_ops->get_dp_cfg_param) { + int ret = soc->cdp_soc.ol_ops->get_dp_cfg_param(soc, + CDP_CFG_MAX_PEER_ID); + + if (ret != -EINVAL) { + wlan_cfg_set_max_peer_id(soc->wlan_cfg_ctx, ret); + } + } + qdf_spinlock_create(&soc->peer_ref_mutex); qdf_spinlock_create(&soc->reo_desc_freelist_lock); diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index f1a9c959c7..72a6a341af 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -182,9 +182,10 @@ struct wlan_cfg_dp_pdev_ctxt { * * Return: wlan_cfg_ctx - Handle to Configuration context */ -struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void) +struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach() { int i = 0; + struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = qdf_mem_malloc(sizeof(struct wlan_cfg_dp_soc_ctxt)); @@ -202,8 +203,8 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void) wlan_cfg_ctx->num_tx_ext_desc_pool = WLAN_CFG_NUM_TXEXT_DESC_POOL; wlan_cfg_ctx->num_tx_desc = WLAN_CFG_NUM_TX_DESC; wlan_cfg_ctx->num_tx_ext_desc = WLAN_CFG_NUM_TX_EXT_DESC; - wlan_cfg_ctx->max_peer_id = WLAN_CFG_MAX_PEER_ID; wlan_cfg_ctx->htt_packet_type = WLAN_CFG_HTT_PKT_TYPE; + wlan_cfg_ctx->max_peer_id = WLAN_CFG_MAX_PEER_ID; for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) { wlan_cfg_ctx->int_tx_ring_mask[i] = tx_ring_mask[i]; @@ -249,6 +250,11 @@ void wlan_cfg_set_num_contexts(struct wlan_cfg_dp_soc_ctxt *cfg, int num) cfg->num_int_ctxts = num; } +void wlan_cfg_set_max_peer_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint32_t val) +{ + cfg->max_peer_id = val;; +} + void wlan_cfg_set_tx_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask) { diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index a497843753..e6fa45c9a4 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -106,6 +106,9 @@ void wlan_cfg_set_ce_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask); void wlan_cfg_set_rxbuf_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask); + +void wlan_cfg_set_max_peer_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint32_t val); + /** * wlan_cfg_get_num_contexts() - Number of interrupt contexts to be registered * @wlan_cfg_ctx - Configuration Handle