diff --git a/target_if/scan/src/target_if_scan.c b/target_if/scan/src/target_if_scan.c index 2e6e8dc49c..9786690cde 100644 --- a/target_if/scan/src/target_if_scan.c +++ b/target_if/scan/src/target_if_scan.c @@ -77,6 +77,9 @@ target_if_scan_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) qdf_mem_free(event_info); return -EINVAL; } + } else { + qdf_mem_free(event_info); + return -EINVAL; } return 0; @@ -126,6 +129,9 @@ int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data, qdf_mem_free(event_info); return -EINVAL; } + } else { + qdf_mem_free(event_info); + return -EINVAL; } return 0; @@ -173,6 +179,9 @@ int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data, qdf_mem_free(event_info); return -EINVAL; } + } else { + qdf_mem_free(event_info); + return -EINVAL; } return 0; diff --git a/umac/scan/core/src/wlan_scan_cache_db.c b/umac/scan/core/src/wlan_scan_cache_db.c index 16d7a75204..90b30bff8a 100644 --- a/umac/scan/core/src/wlan_scan_cache_db.c +++ b/umac/scan/core/src/wlan_scan_cache_db.c @@ -562,6 +562,8 @@ QDF_STATUS scm_handle_bcn_probe(struct scheduler_msg *msg) } free_nbuf: + if (bcn->psoc) + wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID); if (pdev) wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); if (bcn->rx_data) @@ -755,7 +757,9 @@ qdf_list_t *scm_get_scan_result(struct wlan_objmgr_pdev *pdev, return NULL; } + wlan_pdev_obj_lock(pdev); psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); if (!psoc) { scm_err("psoc is NULL"); return NULL; @@ -837,7 +841,9 @@ scm_iterate_scan_db(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } + wlan_pdev_obj_lock(pdev); psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); if (!psoc) { scm_err("psoc is NULL"); return QDF_STATUS_E_INVAL; @@ -923,7 +929,9 @@ QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } + wlan_pdev_obj_lock(pdev); psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); if (!psoc) { scm_err("psoc is NULL"); return QDF_STATUS_E_INVAL; @@ -985,7 +993,9 @@ void scm_filter_valid_channel(struct wlan_objmgr_pdev *pdev, return; } + wlan_pdev_obj_lock(pdev); psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); if (!psoc) { scm_err("psoc is NULL"); return; diff --git a/umac/scan/core/src/wlan_scan_cache_db_i.h b/umac/scan/core/src/wlan_scan_cache_db_i.h index 69a1881c78..3b6fdfce01 100644 --- a/umac/scan/core/src/wlan_scan_cache_db_i.h +++ b/umac/scan/core/src/wlan_scan_cache_db_i.h @@ -183,7 +183,9 @@ wlan_pdev_get_scan_db(struct wlan_objmgr_psoc *psoc, scm_err("pdev is NULL"); return NULL; } + wlan_pdev_obj_lock(pdev); pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + wlan_pdev_obj_unlock(pdev); return wlan_pdevid_get_scan_db(psoc, pdev_id); } diff --git a/umac/scan/core/src/wlan_scan_main.c b/umac/scan/core/src/wlan_scan_main.c index 09475f4806..bfc6630800 100644 --- a/umac/scan/core/src/wlan_scan_main.c +++ b/umac/scan/core/src/wlan_scan_main.c @@ -54,8 +54,11 @@ QDF_STATUS wlan_scan_psoc_destroyed_notification( void *scan_obj = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; + wlan_psoc_obj_lock(psoc); scan_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_SCAN); + WLAN_UMAC_COMP_SCAN); + wlan_psoc_obj_unlock(psoc); + if (!scan_obj) { scm_err("Failed to detach scan in psoc ctx"); return QDF_STATUS_E_FAILURE; @@ -83,7 +86,7 @@ QDF_STATUS wlan_scan_vdev_created_notification(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NOMEM; } - /* Attach scan private date to psoc */ + /* Attach scan private date to vdev */ status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_SCAN, (void *)scan_vdev_obj, QDF_STATUS_SUCCESS); @@ -104,8 +107,11 @@ QDF_STATUS wlan_scan_vdev_destroyed_notification( void *scan_vdev_obj = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; + wlan_vdev_obj_lock(vdev); scan_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, - WLAN_UMAC_COMP_SCAN); + WLAN_UMAC_COMP_SCAN); + wlan_vdev_obj_unlock(vdev); + if (!scan_vdev_obj) { scm_err("Failed to detach scan in vdev ctx"); return QDF_STATUS_E_FAILURE; diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h index 1af2771fc5..8d5fde271d 100644 --- a/umac/scan/core/src/wlan_scan_main.h +++ b/umac/scan/core/src/wlan_scan_main.h @@ -355,9 +355,15 @@ struct wlan_scan_obj { static inline struct wlan_scan_obj * wlan_psoc_get_scan_obj(struct wlan_objmgr_psoc *psoc) { - return (struct wlan_scan_obj *) + struct wlan_scan_obj *scan_obj; + + wlan_psoc_obj_lock(psoc); + scan_obj = (struct wlan_scan_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_SCAN); + wlan_psoc_obj_unlock(psoc); + + return scan_obj; } /** @@ -369,7 +375,11 @@ wlan_psoc_get_scan_obj(struct wlan_objmgr_psoc *psoc) static inline struct wlan_scan_obj * wlan_pdev_get_scan_obj(struct wlan_objmgr_pdev *pdev) { - struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + struct wlan_objmgr_psoc *psoc; + + wlan_pdev_obj_lock(pdev); + psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); return wlan_psoc_get_scan_obj(psoc); } @@ -383,7 +393,11 @@ wlan_pdev_get_scan_obj(struct wlan_objmgr_pdev *pdev) static inline struct wlan_scan_obj * wlan_vdev_get_scan_obj(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct wlan_objmgr_pdev *pdev; + + wlan_vdev_obj_lock(vdev); + pdev = wlan_vdev_get_pdev(vdev); + wlan_vdev_obj_unlock(vdev); return wlan_pdev_get_scan_obj(pdev); } @@ -397,13 +411,19 @@ wlan_vdev_get_scan_obj(struct wlan_objmgr_vdev *vdev) static inline struct scan_vdev_obj * wlan_get_vdev_scan_obj(struct wlan_objmgr_vdev *vdev) { - return (struct scan_vdev_obj *) + struct scan_vdev_obj *scan_vdev_obj; + + wlan_vdev_obj_lock(vdev); + scan_vdev_obj = (struct scan_vdev_obj *) wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_SCAN); + wlan_vdev_obj_unlock(vdev); + + return scan_vdev_obj; } /** - * wlan_scan_vdev_get_pdev_id)() - private API to get pdev id from vdev object + * wlan_scan_vdev_get_pdev_id() - private API to get pdev id from vdev object * @vdev: vdev object * * Return: parent pdev id @@ -411,7 +431,11 @@ wlan_get_vdev_scan_obj(struct wlan_objmgr_vdev *vdev) static inline uint8_t wlan_scan_vdev_get_pdev_id(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct wlan_objmgr_pdev *pdev; + + wlan_vdev_obj_lock(vdev); + pdev = wlan_vdev_get_pdev(vdev); + wlan_vdev_obj_unlock(vdev); return wlan_objmgr_pdev_get_pdev_id(pdev); } @@ -426,9 +450,17 @@ wlan_scan_vdev_get_pdev_id(struct wlan_objmgr_vdev *vdev) static inline struct pdev_scan_ev_handler* wlan_pdev_get_pdev_scan_ev_handlers(struct wlan_objmgr_pdev *pdev) { - uint8_t pdevid = wlan_objmgr_pdev_get_pdev_id(pdev); - struct wlan_scan_obj *scan = wlan_pdev_get_scan_obj(pdev); - struct pdev_scan_ev_handler *pdev_ev_handler = + uint8_t pdevid; + struct wlan_scan_obj *scan; + struct pdev_scan_ev_handler *pdev_ev_handler; + + wlan_pdev_obj_lock(pdev); + pdevid = wlan_objmgr_pdev_get_pdev_id(pdev); + wlan_pdev_obj_unlock(pdev); + + scan = wlan_pdev_get_scan_obj(pdev); + + pdev_ev_handler = &scan->global_evhandlers.pdev_ev_handlers[pdevid]; return pdev_ev_handler; @@ -444,7 +476,11 @@ wlan_pdev_get_pdev_scan_ev_handlers(struct wlan_objmgr_pdev *pdev) static inline struct pdev_scan_ev_handler* wlan_vdev_get_pdev_scan_ev_handlers(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + struct wlan_objmgr_pdev *pdev; + + wlan_vdev_obj_lock(vdev); + pdev = wlan_vdev_get_pdev(vdev); + wlan_vdev_obj_unlock(vdev); return wlan_pdev_get_pdev_scan_ev_handlers(pdev); } diff --git a/umac/scan/core/src/wlan_scan_manager.c b/umac/scan/core/src/wlan_scan_manager.c index 4d5ef4e6cd..b1d935d963 100644 --- a/umac/scan/core/src/wlan_scan_manager.c +++ b/umac/scan/core/src/wlan_scan_manager.c @@ -30,8 +30,8 @@ #include #endif -static QDF_STATUS -scm_free_scan_request_mem(struct scan_start_request *req) +QDF_STATUS +scm_scan_free_scan_request_mem(struct scan_start_request *req) { void *ie; @@ -322,9 +322,10 @@ scm_scan_serialize_callback(struct wlan_serialization_command *cmd, case WLAN_SER_CB_RELEASE_MEM_CMD: /* command successfully completed. - * release scan_start_request memory + * Release vdev reference and free scan_start_request memory */ - status = scm_free_scan_request_mem(req); + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); + status = scm_scan_free_scan_request_mem(req); break; default: @@ -398,13 +399,19 @@ 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 scan_start_request memory. + * release vdev reference and free scan_start_request memory */ - scm_free_scan_request_mem(req); + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); + scm_scan_free_scan_request_mem(req); break; default: QDF_ASSERT(0); status = QDF_STATUS_E_INVAL; + /* 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; } @@ -482,6 +489,11 @@ scm_scan_cancel_req(struct scheduler_msg *msg) status = QDF_STATUS_E_INVAL; break; } + + /* Release vdev reference and scan cancel request + * processing is complete + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); /* Free cancel request memory */ qdf_mem_free(req); diff --git a/umac/scan/core/src/wlan_scan_manager.h b/umac/scan/core/src/wlan_scan_manager.h index 7f3718187f..82acf1e051 100644 --- a/umac/scan/core/src/wlan_scan_manager.h +++ b/umac/scan/core/src/wlan_scan_manager.h @@ -76,4 +76,13 @@ QDF_STATUS scm_scan_cancel_req(struct scheduler_msg *msg); * Return: QDF_STATUS */ QDF_STATUS scm_scan_event_handler(struct scheduler_msg *msg); + +/** + * scm_scan_free_scan_request_mem() - Free scan request memory + * @req: scan_start_request object + * + * Return: QDF_STATUS + */ +QDF_STATUS scm_scan_free_scan_request_mem(struct scan_start_request *req); + #endif diff --git a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c index 169b7582be..e3cdda9d3b 100644 --- a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c @@ -44,7 +44,9 @@ wlan_vdev_get_scan_txops(struct wlan_objmgr_vdev *vdev) { struct wlan_objmgr_psoc *psoc = NULL; + wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); return wlan_psoc_get_scan_txops(psoc); } @@ -54,7 +56,9 @@ wlan_vdev_get_scan_rxops(struct wlan_objmgr_vdev *vdev) { struct wlan_objmgr_psoc *psoc = NULL; + wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); return &((psoc->soc_cb.rx_ops.scan)); } @@ -64,10 +68,14 @@ wlan_vdev_get_scan_rxops(struct wlan_objmgr_vdev *vdev) QDF_STATUS tgt_scan_pno_start(struct wlan_objmgr_vdev *vdev, struct pno_scan_req_params *req) { - struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL; - struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + struct wlan_lmac_if_scan_tx_ops *scan_ops; + struct wlan_objmgr_psoc *psoc; - scan_ops = wlan_vdev_get_scan_txops(vdev); + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + + scan_ops = wlan_psoc_get_scan_txops(psoc); /* invoke wmi_unified_pno_start_cmd() */ QDF_ASSERT(scan_ops->pno_start); if (scan_ops->pno_start) @@ -79,11 +87,14 @@ QDF_STATUS tgt_scan_pno_start(struct wlan_objmgr_vdev *vdev, QDF_STATUS tgt_scan_pno_stop(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id) { - struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL; - struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); + struct wlan_lmac_if_scan_tx_ops *scan_ops; + struct wlan_objmgr_psoc *psoc; - scan_ops = wlan_vdev_get_scan_txops(vdev); + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + scan_ops = wlan_psoc_get_scan_txops(psoc); /* invoke wmi_unified_pno_stop_cmd() */ QDF_ASSERT(scan_ops->pno_stop); if (scan_ops->pno_stop) @@ -96,10 +107,15 @@ QDF_STATUS tgt_scan_pno_stop(struct wlan_objmgr_vdev *vdev, QDF_STATUS tgt_scan_start(struct scan_start_request *req) { - struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL; - struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(req->vdev); + struct wlan_lmac_if_scan_tx_ops *scan_ops; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev = req->vdev; - scan_ops = wlan_vdev_get_scan_txops(req->vdev); + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + + scan_ops = wlan_psoc_get_scan_txops(psoc); /* invoke wmi_unified_scan_start_cmd_send() */ QDF_ASSERT(scan_ops->scan_start); if (scan_ops->scan_start) @@ -112,10 +128,15 @@ tgt_scan_start(struct scan_start_request *req) QDF_STATUS tgt_scan_cancel(struct scan_cancel_request *req) { - struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL; - struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(req->vdev); + struct wlan_lmac_if_scan_tx_ops *scan_ops; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev = req->vdev; - scan_ops = wlan_vdev_get_scan_txops(req->vdev); + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + + scan_ops = wlan_psoc_get_scan_txops(psoc); /* invoke wmi_unified_scan_stop_cmd_send() */ QDF_ASSERT(scan_ops->scan_cancel); if (scan_ops->scan_cancel) @@ -191,7 +212,6 @@ tgt_scan_event_handler(struct wlan_objmgr_psoc *psoc, status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { - qdf_mem_free(event_info); wlan_objmgr_vdev_release_ref(event_info->vdev, WLAN_SCAN_ID); } @@ -233,6 +253,16 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, bcn->frm_type = MGMT_SUBTYPE_PROBE_RESP; else bcn->frm_type = MGMT_SUBTYPE_BEACON; + + status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID); + if (QDF_IS_STATUS_ERROR(status)) { + scm_info("unable to get reference"); + qdf_mem_free(bcn->rx_data); + qdf_mem_free(bcn); + qdf_nbuf_free(buf); + return status; + } + bcn->psoc = psoc; bcn->buf = buf; qdf_mem_copy(bcn->rx_data, rx_param, sizeof(*rx_param)); @@ -243,6 +273,7 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); if (!QDF_IS_STATUS_SUCCESS(status)) { + wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID); scm_err("failed to post to QDF_MODULE_ID_TARGET_IF"); qdf_mem_free(bcn->rx_data); qdf_mem_free(bcn); diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index 22954baf0d..a4e10f5f31 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -334,18 +334,33 @@ ucfg_scan_start(struct scan_start_request *req) if (!req || !req->vdev) { scm_err("vdev: %p, req: %p", req->vdev, req); + if (req) + scm_scan_free_scan_request_mem(req); return QDF_STATUS_E_NULL_VALUE; } scm_info("reqid: %d, scanid: %d, vdevid: %d", req->scan_req.scan_req_id, req->scan_req.scan_id, req->scan_req.vdev_id); + + /* Try to get vdev reference. Return if reference could + * not be taken. Reference will be released once scan + * request handling completes along with free of @req. + */ + status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_SCAN_ID); + if (QDF_IS_STATUS_ERROR(status)) { + scm_info("unable to get reference"); + scm_scan_free_scan_request_mem(req); + return status; + } + msg.bodyptr = req; msg.callback = scm_scan_start_req; status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - if (!QDF_IS_STATUS_SUCCESS(status)) { + if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); scm_err("failed to post to QDF_MODULE_ID_OS_IF"); - qdf_mem_free(req); + scm_scan_free_scan_request_mem(req); } return status; @@ -366,12 +381,20 @@ ucfg_scan_cancel(struct scan_cancel_request *req) scm_info("reqid: %d, scanid: %d, vdevid: %d, type: %d", req->cancel_req.requester, req->cancel_req.scan_id, req->cancel_req.vdev_id, req->cancel_req.req_type); + + /* Get vdev reference unconditionally. + * Reference will be released once scan cancel is + * posted to FW. + */ + wlan_objmgr_vdev_get_ref(req->vdev, WLAN_SCAN_ID); + msg.bodyptr = req; msg.callback = scm_scan_cancel_req; status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - if (!QDF_IS_STATUS_SUCCESS(status)) { + if (QDF_IS_STATUS_ERROR(status)) { scm_err("failed to post to QDF_MODULE_ID_OS_IF"); + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID); qdf_mem_free(req); }