diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index a22337c8b557..a7e19d092111 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -604,4 +604,20 @@ QDF_STATUS wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, enum wlan_serialization_cmd_type cmd_type, wlan_ser_umac_cmd_cb umac_cmd_cb); + +/** + * wlan_serialization_purge_all_pdev_cmd() - purge all command for given pdev + * @pdev: objmgr pdev pointer + * + * Return: void + */ +void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_serialization_purge_all_cmd() - purge all command for psoc + * @psoc: objmgr psoc pointer + * + * Return: void + */ +void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc); #endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index de9ae64ade2e..bebc087fd5b8 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -781,3 +781,44 @@ wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, return status; } + +void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_ser_pdev_obj *ser_pdev_obj; + + if (!pdev) { + ser_err("NULL pdev"); + return; + } + + ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); + if (!ser_pdev_obj) { + ser_err("invalid ser_pdev_obj"); + return; + } + + wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_SCAN, false); + wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_SCAN, true); + wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_NONSCAN, false); + wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_NONSCAN, true); +} + +static inline +void wlan_ser_purge_pdev_cmd_cb(struct wlan_objmgr_psoc *psoc, + void *object, void *arg) +{ + struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; + + wlan_serialization_purge_all_pdev_cmd(pdev); +} + +void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc) +{ + wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, + wlan_ser_purge_pdev_cmd_cb, NULL, 1, + WLAN_SERIALIZATION_ID); +} diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main.c b/umac/cmn_services/serialization/src/wlan_serialization_main.c index dbb7fb33355c..f663a8d096c0 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_main.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -41,6 +41,12 @@ QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc) ser_err("invalid ser_soc_obj"); goto error; } + + /* + * purge all serialization command if there are any pending to make + * sure memory and vdev ref are freed. + */ + wlan_serialization_purge_all_cmd(psoc); /* clean up all timers before exiting */ status = wlan_serialization_cleanup_all_timers(ser_soc_obj); if (status != QDF_STATUS_SUCCESS)