diff --git a/htc/htc_send.c b/htc/htc_send.c index c58b37c109..f10b1c9073 100644 --- a/htc/htc_send.c +++ b/htc/htc_send.c @@ -633,9 +633,13 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, ("hif_send Failed status:%d\n", status)); } - qdf_nbuf_unmap(target->osdev, - GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket), - QDF_DMA_TO_DEVICE); + + /* only unmap if we mapped in this function */ + if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) + qdf_nbuf_unmap(target->osdev, + GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket), + QDF_DMA_TO_DEVICE); + if (!pEndpoint->async_update) { LOCK_HTC_TX(target); } diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 50cfb8e6a9..242f857cbf 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -1436,6 +1436,14 @@ QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc( QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_psoc_user_config *user_config_data); +/** + * wlan_objmgr_psoc_check_for_pdev_leaks() - Assert no pdevs attached to @psoc + * @psoc: The psoc to check + * + * Return: None + */ +void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc); + /** * wlan_objmgr_psoc_check_for_vdev_leaks() - Assert no vdevs attached to @psoc * @psoc: The psoc to check 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 cc5cf350b1..31e29874bd 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 @@ -2005,6 +2005,55 @@ QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_objmgr_psoc_objmgr *_psoc; + int pdev_id; + int ref_id; + + QDF_BUG(psoc); + if (!psoc) + return; + + wlan_psoc_obj_lock(psoc); + _psoc = &psoc->soc_objmgr; + if (!_psoc->wlan_pdev_count) { + wlan_psoc_obj_unlock(psoc); + return; + } + + obj_mgr_err("objmgr pdev leaks detected for psoc %u!", _psoc->psoc_id); + obj_mgr_err("--------------------------------------------------------"); + obj_mgr_err("Pdev Id Refs Module"); + obj_mgr_err("--------------------------------------------------------"); + + for (pdev_id = 0; pdev_id < WLAN_UMAC_MAX_PDEVS; pdev_id++) { + struct wlan_objmgr_pdev *pdev = _psoc->wlan_pdev_list[pdev_id]; + qdf_atomic_t *ref_id_dbg; + + if (!pdev) + continue; + + wlan_pdev_obj_lock(pdev); + ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; + for (ref_id = 0; ref_id < WLAN_REF_ID_MAX; ref_id++) { + int32_t refs = qdf_atomic_read(&ref_id_dbg[ref_id]); + + if (refs <= 0) + continue; + + obj_mgr_err("%7u %4u x %s", + pdev_id, refs, string_from_dbgid(ref_id)); + } + wlan_pdev_obj_unlock(pdev); + } + + wlan_psoc_obj_unlock(psoc); + + QDF_DEBUG_PANIC(); +} +qdf_export_symbol(wlan_objmgr_psoc_check_for_pdev_leaks); + void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) { struct wlan_objmgr_psoc_objmgr *_psoc; diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h index caa38c6de7..2da8cdad83 100644 --- a/umac/scan/core/src/wlan_scan_main.h +++ b/umac/scan/core/src/wlan_scan_main.h @@ -219,10 +219,12 @@ struct pdev_scan_info { * struct scan_vdev_obj - scan vdev obj * @pno_match_evt_received: pno match received * @pno_in_progress: pno in progress + * @is_vdev_delete_in_progress: flag to indicate if vdev del is in progress */ struct scan_vdev_obj { bool pno_match_evt_received; bool pno_in_progress; + bool is_vdev_delete_in_progress; }; /** diff --git a/umac/scan/core/src/wlan_scan_manager.c b/umac/scan/core/src/wlan_scan_manager.c index 3bbe50564d..5dbe64cf4e 100644 --- a/umac/scan/core/src/wlan_scan_manager.c +++ b/umac/scan/core/src/wlan_scan_manager.c @@ -369,8 +369,9 @@ scm_scan_start_req(struct scheduler_msg *msg) { struct wlan_serialization_command cmd = {0, }; enum wlan_serialization_status ser_cmd_status; - struct scan_start_request *req; + struct scan_start_request *req = NULL; struct wlan_scan_obj *scan_obj; + struct scan_vdev_obj *scan_vdev_priv_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg) { @@ -388,7 +389,8 @@ scm_scan_start_req(struct scheduler_msg *msg) scan_obj = wlan_vdev_get_scan_obj(req->vdev); if (!scan_obj) { scm_debug("Couldn't find scan object"); - return QDF_STATUS_E_NULL_VALUE; + status = QDF_STATUS_E_NULL_VALUE; + goto err; } cmd.cmd_type = WLAN_SER_CMD_SCAN; @@ -409,6 +411,18 @@ scm_scan_start_req(struct scheduler_msg *msg) req, req->scan_req.scan_req_id, req->scan_req.scan_id, req->scan_req.vdev_id); + scan_vdev_priv_obj = wlan_get_vdev_scan_obj(req->vdev); + if (!scan_vdev_priv_obj) { + scm_debug("Couldn't find scan priv object"); + status = QDF_STATUS_E_NULL_VALUE; + goto err; + } + if (scan_vdev_priv_obj->is_vdev_delete_in_progress) { + scm_err("Can't allow scan on vdev_id:%d", + wlan_vdev_get_id(req->vdev)); + status = QDF_STATUS_E_NULL_VALUE; + goto err; + } ser_cmd_status = wlan_serialization_request(&cmd); scm_info("wlan_serialization_request status:%d", ser_cmd_status); @@ -427,21 +441,22 @@ scm_scan_start_req(struct scheduler_msg *msg) */ scm_post_internal_scan_complete_event(req, SCAN_REASON_INTERNAL_FAILURE); - /* cmd can't be serviced. - * release vdev reference and free scan_start_request memory - */ - wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); - scm_scan_free_scan_request_mem(req); - break; + goto err; default: QDF_ASSERT(0); status = QDF_STATUS_E_INVAL; - /* cmd can't be serviced. - * release vdev reference and free scan_start_request memory - */ + goto err; + } + + return status; +err: + /* + * cmd can't be serviced. + * release vdev reference and free scan_start_request memory + */ + if (req) { wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); scm_scan_free_scan_request_mem(req); - break; } return status; diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h index 5eb8f371f3..e9b9bb50c4 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h @@ -590,4 +590,19 @@ void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, * Return: true if enabled else false. */ bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_scan_set_vdev_del_in_progress() - API to mark vdev delete in progress + * @vdev: pointer to vdev object + * + * Return: none + */ +void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev); +/** + * ucfg_scan_clear_vdev_del_in_progress() - API to reset vdev delete in progress + * @vdev: pointer to vdev object + * + * Return: none + */ +void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev); #endif diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index 556f4147f9..0cbfba94e1 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -2178,6 +2178,38 @@ bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) return scan_obj->bt_a2dp_enabled; } +void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev) +{ + struct scan_vdev_obj *scan_vdev_obj; + + if (!vdev) { + scm_err("invalid vdev"); + return; + } + scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); + if (!scan_vdev_obj) { + scm_err("null scan_vdev_obj"); + return; + } + scan_vdev_obj->is_vdev_delete_in_progress = true; +} + +void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev) +{ + struct scan_vdev_obj *scan_vdev_obj; + + if (!vdev) { + scm_err("invalid vdev"); + return; + } + scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); + if (!scan_vdev_obj) { + scm_err("null scan_vdev_obj"); + return; + } + scan_vdev_obj->is_vdev_delete_in_progress = false; +} + QDF_STATUS ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, enum scan_config config, uint32_t val) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 4397b32d4f..864850ce0d 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -9294,7 +9294,7 @@ static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, QDF_STATUS ret; wmi_req_stats_ext_cmd_fixed_param *cmd; wmi_buf_t buf; - uint16_t len; + size_t len; uint8_t *buf_ptr; len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;