diff --git a/umac/cmn_services/utils/inc/wlan_utility.h b/umac/cmn_services/utils/inc/wlan_utility.h index e67f7959cf8f..11a8db725448 100644 --- a/umac/cmn_services/utils/inc/wlan_utility.h +++ b/umac/cmn_services/utils/inc/wlan_utility.h @@ -236,6 +236,23 @@ QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev, unsigned long *vdev_id_map, wlan_objmgr_ref_dbgid dbg_id); +/** + * wlan_pdev_chan_change_pending_vdevs_down() - function to test/set down + * change pending flag + * @pdev: pdev object + * @vdev_id_map: bitmap to derive channel change vdevs + * @ref_id: object manager ref id + * + * This function test/set channel change pending flag + * + * Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs, + * otherwise QDF_STATUS_E_FAILURE + */ +QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down( + struct wlan_objmgr_pdev *pdev, + unsigned long *vdev_id_map, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_chan_eq() - function to check whether both channels are same * @chan1: channel1 object diff --git a/umac/cmn_services/utils/src/wlan_utility.c b/umac/cmn_services/utils/src/wlan_utility.c index d6cdd29eb21c..d4e1dd68ab7e 100644 --- a/umac/cmn_services/utils/src/wlan_utility.c +++ b/umac/cmn_services/utils/src/wlan_utility.c @@ -286,6 +286,48 @@ QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +static void wlan_vdev_down_pending(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + unsigned long *vdev_id_map = (unsigned long *)arg; + uint8_t id = 0; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return; + + wlan_vdev_obj_lock(vdev); + if (wlan_vdev_mlme_is_init_state(vdev) != QDF_STATUS_SUCCESS) { + id = wlan_vdev_get_id(vdev); + /* Invalid vdev id */ + if (id >= wlan_psoc_get_max_vdev_count(psoc)) { + wlan_vdev_obj_unlock(vdev); + return; + } + + wlan_util_change_map_index(vdev_id_map, id, 1); + } + + wlan_vdev_obj_unlock(vdev); +} + +QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down( + struct wlan_objmgr_pdev *pdev, + unsigned long *vdev_id_map, + wlan_objmgr_ref_dbgid dbg_id) +{ + if (!pdev) + return QDF_STATUS_E_INVAL; + + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_vdev_down_pending, + vdev_id_map, 0, dbg_id); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2) { if ((chan1->ch_ieee == chan2->ch_ieee) &&