diff --git a/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c b/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c index e401864b04..b3cb8e1889 100644 --- a/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c +++ b/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c @@ -717,6 +717,29 @@ static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev, wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID); } +#ifdef WLAN_FEATURE_11BE_MLO +/** + * if_mgr_get_conc_ext_flags() - get extended flags for concurrency check + * @vdev: pointer to vdev on which new connection is coming up + * @candidate_info: interface manager validate candidate data + * + * Return: extended flags for concurrency check + */ +static inline uint32_t +if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, + struct validate_bss_data *candidate_info) +{ + return policy_mgr_get_conc_ext_flags(vdev, candidate_info->is_mlo); +} +#else +static inline uint32_t +if_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, + struct validate_bss_data *candidate_info) +{ + return 0; +} +#endif + QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev, struct if_mgr_event_data *event_data) { @@ -728,7 +751,7 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev, struct validate_bss_data *candidate_info = &event_data->validate_bss_info; uint32_t chan_freq = candidate_info->chan_freq; - uint32_t conc_freq = 0; + uint32_t conc_freq = 0, conc_ext_flags; op_mode = wlan_vdev_mlme_get_opmode(vdev); @@ -764,9 +787,12 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev, * Valid multichannel concurrent sessions exempted */ mode = policy_mgr_convert_device_mode_to_qdf_type(op_mode); + /* If concurrency is not allowed select next bss */ + conc_ext_flags = if_mgr_get_conc_ext_flags(vdev, candidate_info); if (!policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq, - HW_MODE_20_MHZ)) { + HW_MODE_20_MHZ, + conc_ext_flags)) { ifmgr_info("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next", chan_freq, QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes)); diff --git a/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 0e195df8b4..e8f3542769 100644 --- a/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1026,6 +1026,7 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( * @mode: new connection mode * @ch_freq: channel frequency on which new connection is coming up * @bw: Bandwidth requested by the connection (optional) + * @ext_flags: extended flags for concurrency check (union conc_ext_flag) * * When a new connection is about to come up check if current * concurrency combination including the new connection is @@ -1036,7 +1037,8 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, - enum hw_mode_bandwidth bw); + enum hw_mode_bandwidth bw, + uint32_t ext_flags); /** * policy_mgr_nan_sap_pre_enable_conc_check() - Check if NAN+SAP SCC is @@ -2361,6 +2363,7 @@ QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc, * @weight: Pointer to the structure containing pcl, saved channel list and * weighed channel list * @mode: Policy manager connection mode + * @vdev: pointer to vdev on which new connection is coming up * * Provides the weightage for all valid channels. This compares the PCL list * with the valid channel list. The channels present in the PCL get their @@ -2371,7 +2374,7 @@ QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, struct policy_mgr_pcl_chan_weights *weight, - enum policy_mgr_con_mode mode); + enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev); /** * policy_mgr_set_hw_mode_on_channel_switch() - Set hw mode @@ -3988,6 +3991,20 @@ void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc, */ bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc, bool is_new_vdev_mlo); + +/** + * policy_mgr_get_conc_ext_flags() - get extended flags for concurrency check + * @vdev: pointer to vdev on which new connection is coming up + * @force_mlo: true means it's a MLO connection, false means uncertain + * + * In some scenario the flag WLAN_VDEV_FEXT2_MLO may not set for vdev when + * checking concurrency, then caller can set force_mlo accordingly to get + * proper extended flags. + * + * Return: extended flags for concurrency check + */ +uint32_t +policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo); #else static inline bool policy_mgr_is_mlo_sap_concurrency_allowed( @@ -3996,6 +4013,12 @@ static inline bool policy_mgr_is_mlo_sap_concurrency_allowed( { return true; } + +static inline uint32_t +policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo) +{ + return 0; +} #endif /** diff --git a/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 4452a639e9..a89baa7932 100644 --- a/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -39,6 +39,10 @@ #include "wlan_mlme_api.h" #include "wlan_mlme_main.h" #include "wlan_mlme_vdev_mgr_interface.h" +#ifdef WLAN_FEATURE_11BE_MLO +#include "wlan_mlo_mgr_sta.h" +#endif + /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 @@ -3357,14 +3361,11 @@ static inline bool policy_mgr_is_concurrency_allowed_4_port( * policy_mgr_allow_multiple_sta_connections() - check whether multiple STA * concurrency is allowed and F/W supported * @psoc: Pointer to soc - * @second_sta_freq: 2nd STA channel frequency - * @first_sta_freq: 1st STA channel frequency * * Return: true if supports else false. */ -static bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, - uint32_t second_sta_freq, - uint32_t first_sta_freq) +static bool +policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc) { struct wmi_unified *wmi_handle; @@ -3456,8 +3457,127 @@ static bool policy_mgr_is_6g_channel_allowed( } #ifdef WLAN_FEATURE_11BE_MLO -bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc, - bool is_new_vdev_mlo) +uint32_t +policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo) +{ + struct wlan_objmgr_vdev *assoc_vdev; + union conc_ext_flag conc_ext_flags; + + conc_ext_flags.value = 0; + if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) + return conc_ext_flags.value; + + if (!force_mlo && !wlan_vdev_mlme_is_mlo_vdev(vdev)) + return conc_ext_flags.value; + + conc_ext_flags.mlo = 1; + if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) { + assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev); + if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev)) + conc_ext_flags.mlo_link_assoc_connected = 1; + } + + return conc_ext_flags.value; +} + +/** + * policy_mgr_allow_sta_concurrency() - check whether STA concurrency is allowed + * @psoc: Pointer to soc + * @freq: frequency to be checked + * @ext_flags: extended flags for concurrency check + * + * Return: true if supports else false. + */ +static bool +policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq, + uint32_t ext_flags) +{ + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct wlan_objmgr_vdev *vdev; + bool is_mlo, mlo_sap_present = false, mlo_sta_present = false; + uint8_t vdev_id, sta_cnt = 0; + enum policy_mgr_con_mode mode; + union conc_ext_flag conc_ext_flags; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + conc_ext_flags.value = ext_flags; + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + mode = pm_conc_connection_list[conn_index].mode; + if ((mode != PM_STA_MODE && mode != PM_SAP_MODE) || + !pm_conc_connection_list[conn_index].in_use) + continue; + + vdev_id = pm_conc_connection_list[conn_index].vdev_id; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_POLICY_MGR_ID); + if (!vdev) + continue; + + is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev); + if (mode == PM_SAP_MODE) { + if (is_mlo) + mlo_sap_present = true; + + goto next; + } + + /* Skip the link vdev for MLO STA */ + if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) + goto next; + + sta_cnt++; + if (!is_mlo) + goto next; + + mlo_sta_present = true; +next: + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + /* Reject if multiple STA connections are not allowed */ + if (sta_cnt && + !policy_mgr_allow_multiple_sta_connections(psoc)) { + policy_mgr_rl_debug("Disallow Multiple STA connections"); + return false; + } + + if (mlo_sta_present && conc_ext_flags.mlo_link_assoc_connected) { + policy_mgr_rl_debug("Allow secondary MLO link"); + return true; + } + + if (conc_ext_flags.mlo && (mlo_sta_present || mlo_sap_present)) { + policy_mgr_rl_debug("Disallow ML STA when ML STA/SAP is present"); + return false; + } + + /* + * Reject a 3rd STA. + * Treat a MLO STA(including the primary and secondary link vdevs) + * as 1 STA here. + */ + if (sta_cnt >= 2) { + policy_mgr_rl_debug("Disallow 3rd STA"); + return false; + } + + return true; +} + +bool +policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc, + bool is_new_vdev_mlo) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t conn_index; @@ -3505,6 +3625,31 @@ bool policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc, return ret; } +#else +static bool +policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc, + qdf_freq_t freq, + uint32_t ext_flags) +{ + uint32_t count; + + count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + NULL); + if (!count) + return true; + + if (count >= 2) { + policy_mgr_rl_debug("Disallow 3rd STA"); + return false; + } + + if (!policy_mgr_allow_multiple_sta_connections(psoc)) { + policy_mgr_rl_debug("Multiple STA connections is not allowed"); + return false; + } + + return true; +} #endif #ifdef WLAN_FEATURE_P2P_P2P_STA @@ -3583,7 +3728,8 @@ static bool policy_mgr_is_third_conn_sta_p2p_p2p_valid( bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, - enum hw_mode_bandwidth bw) + enum hw_mode_bandwidth bw, + uint32_t ext_flags) { uint32_t num_connections = 0, count = 0, index = 0; bool status = false, match = false; @@ -3591,7 +3737,6 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; bool go_force_scc; - uint32_t sta_freq; enum channel_state chan_state; bool is_dfs_ch = false; @@ -3677,19 +3822,9 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } } - /* Check for STA+STA concurrency */ - count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, - list); - if (mode == PM_STA_MODE && count) { - if (count >= 2) { - policy_mgr_rl_debug("3rd STA isn't permitted"); - return status; - } - sta_freq = pm_conc_connection_list[list[0]].freq; - if (!policy_mgr_allow_multiple_sta_connections(psoc, ch_freq, - sta_freq)) - return status; - } + if (mode == PM_STA_MODE && + !policy_mgr_allow_sta_concurrency(psoc, ch_freq, ext_flags)) + return status; if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq, WLAN_INVALID_VDEV_ID)) { @@ -3739,7 +3874,8 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, - enum hw_mode_bandwidth bw) + enum hw_mode_bandwidth bw, + uint32_t ext_flags) { QDF_STATUS status; struct policy_mgr_pcl_list pcl; @@ -3754,7 +3890,8 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, return false; } - allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq, bw); + allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq, + bw, ext_flags); /* Fourth connection concurrency check */ if (allowed && policy_mgr_get_connection_count(psoc) == 3) @@ -3777,8 +3914,9 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, info[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t num_cxn_del = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; - uint32_t old_ch_freq; + uint32_t old_ch_freq, conc_ext_flags; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -3824,8 +3962,14 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, policy_mgr_store_and_del_conn_info_by_vdev_id( psoc, vdev_id, info, &num_cxn_del); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_POLICY_MGR_ID); + conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false); allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq, - HW_MODE_20_MHZ); + HW_MODE_20_MHZ, conc_ext_flags); + if (vdev) + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + /* Restore the connection entry */ if (num_cxn_del > 0) policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); @@ -3964,6 +4108,8 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode; bool ret; struct policy_mgr_psoc_priv_obj *pm_ctx; + struct wlan_objmgr_vdev *vdev; + uint32_t conc_ext_flags; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -3986,8 +4132,16 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, return false; } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, + WLAN_POLICY_MGR_ID); + /* Take care of 160MHz and 80+80Mhz later */ - ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ); + conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false); + ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ, + conc_ext_flags); + if (vdev) + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + if (false == ret) { policy_mgr_err("Connection failed due to conc check fail"); return 0; diff --git a/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index fb9ca89354..199bf6f8af 100644 --- a/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -389,6 +389,25 @@ struct policy_mgr_mac_ss_bw_info { uint32_t mac_band_cap; }; +#ifdef WLAN_FEATURE_11BE_MLO +/** + * union conc_ext_flag - extended flags for concurrency check + * + * @mlo: the new connection is MLO + * @mlo_link_assoc_connected: the new connection is secondary MLO link and + * the corresponding assoc link is connected + * @value: uint32 value for extended flags + */ +union conc_ext_flag { + struct { + uint32_t mlo: 1; + uint32_t mlo_link_assoc_connected: 1; + }; + + uint32_t value; +}; +#endif + struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( struct wlan_objmgr_psoc *psoc); QDF_STATUS policy_mgr_get_updated_scan_config( @@ -792,6 +811,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, * @mode: new connection mode * @ch_freq: channel frequency on which new connection is coming up * @bw: Bandwidth requested by the connection (optional) + * @ext_flags: extended flags for concurrency check (union conc_ext_flag) * * When a new connection is about to come up check if current * concurrency combination including the new connection is @@ -803,5 +823,6 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, - enum hw_mode_bandwidth bw); + enum hw_mode_bandwidth bw, + uint32_t ext_flags); #endif diff --git a/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index 6d21349e09..f92eb402b0 100644 --- a/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -2379,7 +2379,7 @@ policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, struct policy_mgr_pcl_chan_weights *weight, - enum policy_mgr_con_mode mode) + enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev) { uint32_t i, j; struct policy_mgr_conc_connection_info @@ -2418,7 +2418,8 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, for (i = 0; i < weight->saved_num_chan; i++) { if (policy_mgr_is_concurrency_allowed (psoc, mode, weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + HW_MODE_20_MHZ, + policy_mgr_get_conc_ext_flags(vdev, false))) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } diff --git a/nan/core/src/nan_main.c b/nan/core/src/nan_main.c index 7785051cdf..19d3257345 100644 --- a/nan/core/src/nan_main.c +++ b/nan/core/src/nan_main.c @@ -1114,7 +1114,8 @@ bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq) return (NAN_DISC_DISABLED == nan_get_discovery_state(psoc) && ucfg_is_nan_conc_control_supported(psoc) && policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE, - nan_ch_freq, HW_MODE_20_MHZ)); + nan_ch_freq, HW_MODE_20_MHZ, + 0)); } bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc) diff --git a/nan/dispatcher/src/nan_ucfg_api.c b/nan/dispatcher/src/nan_ucfg_api.c index 9e3c24d2a7..ffc48aa7cf 100644 --- a/nan/dispatcher/src/nan_ucfg_api.c +++ b/nan/dispatcher/src/nan_ucfg_api.c @@ -1069,7 +1069,7 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc, { uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - uint32_t ndi_cnt, sta_cnt, id; + uint32_t ndi_cnt, sta_cnt, id, conc_ext_flags; sta_cnt = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL); @@ -1113,9 +1113,11 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(psoc)) return false; + conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false); + /* The final freq would be provided by FW, it is not known now */ return policy_mgr_allow_concurrency(psoc, PM_NDI_MODE, 0, - HW_MODE_20_MHZ); + HW_MODE_20_MHZ, conc_ext_flags); } bool diff --git a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c index 0f076e4415..cce3ba3a35 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c @@ -111,7 +111,7 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, status = policy_mgr_get_valid_chan_weights( psoc, (struct policy_mgr_pcl_chan_weights *)weights, - PM_STA_MODE); + PM_STA_MODE, vdev); qdf_mem_free(freq_list);