diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index a34d21e8d00b..51903f51d31d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1579,7 +1579,6 @@ struct fw_scan_channels { * @rssi_threshold_offset_5g: Lookup threshold offset for 5G band * @early_stop_scan_min_threshold: Set early stop scan min * @early_stop_scan_max_threshold: Set early stop scan max - * @first_scan_bucket_threshold: Set first scan bucket * @roam_dense_traffic_threshold: Dense traffic threshold * @roam_dense_rssi_thre_offset: Sets dense roam RSSI threshold diff * @roam_dense_min_aps: Sets minimum number of AP for dense roam @@ -1691,7 +1690,6 @@ struct wlan_mlme_lfr_cfg { uint8_t rssi_threshold_offset_5g; uint8_t early_stop_scan_min_threshold; uint8_t early_stop_scan_max_threshold; - uint8_t first_scan_bucket_threshold; uint32_t roam_dense_traffic_threshold; uint32_t roam_dense_rssi_thre_offset; uint32_t roam_dense_min_aps; diff --git a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c index 293a1df1907d..b9d3b56f6992 100644 --- a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c +++ b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c @@ -845,6 +845,22 @@ static QDF_STATUS target_if_cm_roam_scan_rssi_change_cmd( params); } +/** + * target_if_cm_roam_offload_chan_list - Send WMI_ROAM_CHAN_LIST command to + * firmware + * @wmi_handle: Pointer to wmi handle + * @rso_chan_info: RSO channel list info + * + * Return: QDF_STATUS + */ +static QDF_STATUS target_if_cm_roam_offload_chan_list( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_channel_list *rso_chan_info) +{ + return wmi_unified_roam_scan_offload_chan_list_cmd(wmi_handle, + rso_chan_info); +} + /** * target_if_cm_roam_send_start() - Send roam start related commands * to wmi @@ -913,6 +929,14 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) goto end; + status = target_if_cm_roam_offload_chan_list(wmi_handle, + &req->rso_chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("vdev:%d Send channel list command failed", + req->rso_chan_info.vdev_id); + goto end; + } + if (wmi_service_enabled(wmi_handle, wmi_service_mawc_support)) { status = target_if_cm_roam_scan_mawc_params(wmi_handle, &req->mawc_params); @@ -1041,6 +1065,14 @@ target_if_cm_roam_send_stop(struct wlan_objmgr_vdev *vdev, mode = WMI_ROAM_SCAN_MODE_NONE; } + status = target_if_cm_roam_scan_offload_mode(wmi_handle, + &req->rso_config); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("vdev:%d Send RSO mode cmd failed", + req->rso_config.vdev_id); + goto end; + } + /* * After sending the roam scan mode because of a disconnect, * clear the scan bitmap client as well by sending @@ -1112,6 +1144,14 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev, goto end; } + status = target_if_cm_roam_scan_offload_mode(wmi_handle, + &req->rso_config); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("vdev:%d Send RSO mode cmd failed", + req->rso_config.vdev_id); + goto end; + } + status = target_if_cm_roam_scan_filter(wmi_handle, ROAM_SCAN_OFFLOAD_UPDATE_CFG, &req->scan_filter_params); @@ -1149,6 +1189,15 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev, &req->profile_params); if (QDF_IS_STATUS_ERROR(status)) goto end; + + status = target_if_cm_roam_offload_chan_list(wmi_handle, + &req->rso_chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("vdev:%d Send channel list command failed", + req->rso_chan_info.vdev_id); + goto end; + } + psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { target_if_err("psoc handle is NULL"); diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c index 86fa044eec4d..689330a2d85c 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c @@ -816,6 +816,7 @@ cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev, QDF_STATUS status; struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id); + bool sup_disabled_roam; cm_roam_roam_invoke_in_progress(psoc, vdev_id, false); @@ -830,6 +831,27 @@ cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev, cm_roam_switch_to_rso_stop(pdev, vdev_id, reason); break; case WLAN_ROAM_RSO_STOPPED: + /* + * When Supplicant disabled roaming is set and roam invoke + * command is received from userspace, fw starts to roam. + * But meanwhile if a disassoc/deauth is received from AP or if + * NB disconnect is initiated while supplicant disabled roam, + * RSO stop with ROAM scan mode as 0 is not sent to firmware + * since the previous state was RSO_STOPPED. This could lead + * to firmware not sending peer unmap event for the current + * AP. To avoid this, if previous RSO stop was sent with + * ROAM scan mode as 4, send RSO stop with Roam scan mode as 0 + * and then switch to ROAM_DEINIT. + */ + sup_disabled_roam = + mlme_get_supplicant_disabled_roaming(psoc, + vdev_id); + if (sup_disabled_roam) { + mlme_err("vdev[%d]: supplicant disabled roam. clear roam scan mode", + vdev_id); + cm_roam_switch_to_rso_stop(pdev, vdev_id, reason); + } + case WLAN_ROAM_INIT: break; diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h index 69428b24d5cc..a66d1f97aa77 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h @@ -1005,6 +1005,22 @@ struct wlan_roam_scan_period_params { uint32_t roam_scan_period_after_inactivity; uint32_t full_scan_period; }; + +#define ROAM_MAX_CHANNELS 80 +/** + * wlan_roam_scan_channel_list - Roam Scan channel list related + * parameters + * @vdev_id: Vdev id + * @chan_count: Channel count + * @chan_freq_list: Frequency list pointer + * @chan_cache_type: Static or dynamic channel cache + */ +struct wlan_roam_scan_channel_list { + uint32_t vdev_id; + uint8_t chan_count; + uint32_t chan_freq_list[ROAM_MAX_CHANNELS]; + uint8_t chan_cache_type; +}; #endif /** @@ -1034,6 +1050,7 @@ struct wlan_roam_rssi_change_params { * @scan_period_params: roam scan period parameters * @rssi_change_params: Roam offload RSSI change parameters * @profile_params: ap profile parameters + * @rso_chan_info: Roam scan channel list parameters * @mawc_params: mawc parameters * @scan_filter_params: roam scan filter parameters * @btm_config: btm configuration @@ -1051,6 +1068,7 @@ struct wlan_roam_start_config { struct wlan_roam_scan_offload_params rso_config; struct wlan_roam_rssi_change_params rssi_change_params; struct ap_profile_params profile_params; + struct wlan_roam_scan_channel_list rso_chan_info; struct wlan_roam_mawc_params mawc_params; struct wlan_roam_scan_filter_params scan_filter_params; struct wlan_roam_btm_config btm_config; @@ -1097,6 +1115,7 @@ struct wlan_roam_stop_config { * @rssi_change_params: roam scan rssi change parameters * @rso_config: roam scan mode configurations * @profile_params: ap profile parameters + * @rso_chan_info: Roam scan channel list parameters * @rssi_params: roam scan rssi threshold parameters * @disconnect_params: disconnect params * @idle_params: idle params @@ -1109,6 +1128,7 @@ struct wlan_roam_update_config { struct wlan_roam_rssi_change_params rssi_change_params; struct wlan_roam_scan_offload_params rso_config; struct ap_profile_params profile_params; + struct wlan_roam_scan_channel_list rso_chan_info; struct wlan_roam_offload_scan_rssi_params rssi_params; struct wlan_roam_disconnect_params disconnect_params; struct wlan_roam_idle_params idle_params; diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h index 7a0daefa39a6..a8f8273c1587 100644 --- a/components/wmi/inc/wmi_unified_roam_api.h +++ b/components/wmi/inc/wmi_unified_roam_api.h @@ -330,25 +330,19 @@ QDF_STATUS wmi_unified_roam_scan_offload_cmd(wmi_unified_t wmi_handle, uint32_t command, uint32_t vdev_id); +#ifdef ROAM_OFFLOAD_V1 /** - * wmi_unified_roam_scan_offload_chan_list_cmd() - set roam offload channel list + * wmi_unified_roam_scan_offload_chan_list_cmd - Roam scan offload channel + * list command * @wmi_handle: wmi handle - * @chan_count: channel count - * @chan_list: channel list - * @list_type: list type - * @vdev_id: vdev id + * @rso_ch_info: roam scan offload channel info * - * Set roam offload channel list. - * - * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * Return: QDF_STATUS */ QDF_STATUS wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle, - uint8_t chan_count, - uint32_t *chan_list, - uint8_t list_type, - uint32_t vdev_id); -#ifdef ROAM_OFFLOAD_V1 + struct wlan_roam_scan_channel_list *rso_ch_info); + /** * wmi_unified_roam_scan_offload_rssi_change_cmd() - set roam offload RSSI * threshold @@ -381,6 +375,25 @@ wmi_unified_roam_scan_offload_rssi_change_cmd(wmi_unified_t wmi_handle, int32_t rssi_change_thresh, uint32_t bcn_rssi_weight, uint32_t hirssi_delay_btw_scans); + +/** + * wmi_unified_roam_scan_offload_chan_list_cmd() - set roam offload channel list + * @wmi_handle: wmi handle + * @chan_count: channel count + * @chan_list: channel list + * @list_type: list type + * @vdev_id: vdev id + * + * Set roam offload channel list. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle, + uint8_t chan_count, + uint32_t *chan_list, + uint8_t list_type, + uint32_t vdev_id); #endif /** diff --git a/components/wmi/src/wmi_unified_roam_api.c b/components/wmi/src/wmi_unified_roam_api.c index 1a511853f906..1ec8bc5c59b8 100644 --- a/components/wmi/src/wmi_unified_roam_api.c +++ b/components/wmi/src/wmi_unified_roam_api.c @@ -257,6 +257,19 @@ QDF_STATUS wmi_unified_roam_scan_offload_cmd(wmi_unified_t wmi_handle, return QDF_STATUS_E_FAILURE; } +#ifdef ROAM_OFFLOAD_V1 +QDF_STATUS +wmi_unified_roam_scan_offload_chan_list_cmd( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_channel_list *rso_ch_info) +{ + if (wmi_handle->ops->send_roam_scan_offload_chan_list_cmd) + return wmi_handle->ops->send_roam_scan_offload_chan_list_cmd( + wmi_handle, rso_ch_info); + + return QDF_STATUS_E_FAILURE; +} +#else QDF_STATUS wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle, uint8_t chan_count, @@ -271,6 +284,7 @@ wmi_unified_roam_scan_offload_chan_list_cmd(wmi_unified_t wmi_handle, return QDF_STATUS_E_FAILURE; } +#endif #ifdef ROAM_OFFLOAD_V1 QDF_STATUS wmi_unified_roam_scan_offload_rssi_change_cmd( diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 6c2c09dcf4ee..e9b7ac7cb955 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -2329,7 +2329,7 @@ send_roam_scan_offload_mode_cmd_tlv( /* Ensure there is no additional IEs */ scan_cmd_fp->ie_len = 0; - buf += sizeof(wmi_start_scan_cmd_fixed_param); + buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); status = wmi_fill_rso_tlvs(wmi_handle, buf_ptr, rso_req); if (QDF_IS_STATUS_ERROR(status)) { @@ -3118,6 +3118,74 @@ error: return status; } +#ifdef ROAM_OFFLOAD_V1 +/** + * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list + * @wmi_handle: wmi handle + * + * Set roam offload channel list. + * + * Return: QDF status + */ +static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_channel_list *rso_ch_info) +{ + wmi_buf_t buf = NULL; + QDF_STATUS status; + int len, list_tlv_len; + int i; + uint8_t *buf_ptr; + wmi_roam_chan_list_fixed_param *chan_list_fp; + uint32_t *roam_chan_list_array; + uint8_t chan_count = rso_ch_info->chan_count; + uint32_t *chan_list = rso_ch_info->chan_freq_list; + + /* Channel list is a table of 2 TLV's */ + list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t); + len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) + return QDF_STATUS_E_NOMEM; + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + chan_list_fp = (wmi_roam_chan_list_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&chan_list_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_chan_list_fixed_param)); + chan_list_fp->vdev_id = rso_ch_info->vdev_id; + chan_list_fp->num_chan = chan_count; + if (rso_ch_info->chan_cache_type == WMI_CHANNEL_LIST_STATIC) + /* external app is controlling channel list */ + chan_list_fp->chan_list_type = + WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; + else + /* umac supplied occupied channel list in LFR */ + chan_list_fp->chan_list_type = + WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; + + buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (chan_list_fp->num_chan * sizeof(uint32_t))); + roam_chan_list_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); + for (i = 0; ((i < chan_list_fp->num_chan) && + (i < WMI_ROAM_MAX_CHANNELS)); i++) + roam_chan_list_array[i] = chan_list[i]; + + wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, + len, WMI_ROAM_CHAN_LIST); + if (QDF_IS_STATUS_ERROR(status)) + goto error; + + return QDF_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return status; +} +#else /** * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list * @wmi_handle: wmi handle @@ -3189,6 +3257,7 @@ error: return status; } +#endif #ifdef ROAM_OFFLOAD_V1 /** diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index ea15f60fbc88..7b0fecb65240 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1808,7 +1808,6 @@ QDF_STATUS csr_create_bg_scan_roam_channel_list(struct mac_context *mac, return status; } -#ifndef ROAM_OFFLOAD_V1 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) /** * csr_check_band_freq_match() - check if passed band and ch freq match @@ -1889,7 +1888,6 @@ is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint32_t freq, return false; } #endif -#endif #ifdef FEATURE_WLAN_ESE /** @@ -19878,6 +19876,359 @@ csr_cm_roam_scan_offload_ap_profile(struct mac_context *mac_ctx, mac_ctx->mlme_cfg->trig_score_delta[BTM_ROAM_TRIGGER]; } +/** + * csr_cm_populate_roam_chan_list() - Populate roam channel list + * parameters + * @mac_ctx: global mac ctx + * @dst: Destination roam channel buf to populate the roam chan list + * @src: Source channel list + * + * Return: QDF_STATUS enumeration + */ +static QDF_STATUS +csr_cm_populate_roam_chan_list(struct mac_context *mac_ctx, + struct wlan_roam_scan_channel_list *dst, + tCsrChannelInfo *src) +{ + enum band_info band; + uint32_t band_cap; + uint8_t i = 0; + uint8_t num_channels = 0; + uint32_t *freq_lst = src->freq_list; + + /* + * The INI channels need to be filtered with respect to the current band + * that is supported. + */ + band_cap = mac_ctx->mlme_cfg->gen.band_capability; + if (!band_cap) { + sme_err("Invalid band_cap(%d), roam scan offload req aborted", + band_cap); + return QDF_STATUS_E_FAILURE; + } + + band = wlan_reg_band_bitmap_to_band_info(band_cap); + num_channels = dst->chan_count; + for (i = 0; i < src->numOfChannels; i++) { + if (csr_is_channel_present_in_list(dst->chan_freq_list, + num_channels, *freq_lst)) { + freq_lst++; + continue; + } + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *freq_lst, band)) { + freq_lst++; + continue; + } + dst->chan_freq_list[num_channels++] = *freq_lst; + freq_lst++; + } + dst->chan_count = num_channels; + + return QDF_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_ESE +static void csr_cm_fetch_ch_lst_from_received_list( + struct mac_context *mac_ctx, + tpCsrNeighborRoamControlInfo roam_info, + tCsrChannelInfo *curr_ch_lst_info, + struct wlan_roam_scan_channel_list *rso_chan_info) +{ + uint8_t i = 0; + uint8_t num_channels = 0; + uint32_t *freq_lst = NULL; + enum band_info band = BAND_ALL; + + if (curr_ch_lst_info->numOfChannels == 0) + return; + + freq_lst = curr_ch_lst_info->freq_list; + for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) { + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *freq_lst, band)) { + freq_lst++; + continue; + } + rso_chan_info->chan_freq_list[num_channels++] = *freq_lst; + freq_lst++; + } + rso_chan_info->chan_count = num_channels; + rso_chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; +} +#else +static void csr_cm_fetch_ch_lst_from_received_list( + struct mac_context *mac_ctx, + tpCsrNeighborRoamControlInfo roam_info, + tCsrChannelInfo *curr_ch_lst_info, + struct wlan_roam_scan_channel_list *rso_chan_info) +{} +#endif + +static void csr_cm_fetch_ch_lst_from_occupied_lst( + struct mac_context *mac_ctx, + tpCsrNeighborRoamControlInfo roam_info, + struct wlan_roam_scan_channel_list *rso_chan_info, + uint8_t vdev_id, uint8_t reason) +{ + uint8_t i = 0; + uint8_t num_channels = 0; + uint32_t op_freq; + struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); + uint32_t *ch_lst; + enum band_info band = BAND_ALL; + + if (!session) { + sme_err("session NULL for vdev:%d", vdev_id); + return; + } + + ch_lst = mac_ctx->scan.occupiedChannels[vdev_id].channel_freq_list; + op_freq = session->connectedProfile.op_freq; + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) + band = BAND_5G; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) + band = BAND_2G; + else + band = BAND_UNKNOWN; + } + + for (i = 0; i < mac_ctx->scan.occupiedChannels[vdev_id].numChannels; + i++) { + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_lst, band)) { + ch_lst++; + continue; + } + rso_chan_info->chan_freq_list[num_channels++] = *ch_lst; + ch_lst++; + } + rso_chan_info->chan_count = num_channels; + rso_chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; +} + +/** + * csr_cm_add_ch_lst_from_roam_scan_list() - channel from roam scan chan list + * parameters + * @mac_ctx: Global mac ctx + * @rso_chan_info: RSO channel info + * @roam_info: roam info struct + * + * Return: QDF_STATUS + */ +static QDF_STATUS csr_cm_add_ch_lst_from_roam_scan_list( + struct mac_context *mac_ctx, + struct wlan_roam_scan_channel_list *rso_chan_info, + tpCsrNeighborRoamControlInfo roam_info) +{ + QDF_STATUS status; + tCsrChannelInfo *pref_chan_info = &roam_info->cfgParams.pref_chan_info; + + if (!pref_chan_info->numOfChannels) + return QDF_STATUS_SUCCESS; + + status = csr_cm_populate_roam_chan_list(mac_ctx, + rso_chan_info, + pref_chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to copy channels to roam list"); + return status; + } + sme_dump_freq_list(pref_chan_info); + rso_chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; + + return QDF_STATUS_SUCCESS; +} + +/** + * csr_cm_fetch_valid_ch_lst() - fetch channel list from valid channel list and + * update rso req msg + * parameters + * @mac_ctx: global mac ctx + * @rso_chan_buf: out param, roam offload scan request channel info buffer + * @vdev_id: Vdev id + * + * Return: QDF_STATUS + */ +static QDF_STATUS +csr_cm_fetch_valid_ch_lst(struct mac_context *mac_ctx, + struct wlan_roam_scan_channel_list *rso_chan_info, + uint8_t vdev_id) +{ + QDF_STATUS status; + uint32_t host_channels = 0; + uint32_t *ch_freq_list = NULL; + uint8_t i = 0, num_channels = 0; + enum band_info band = BAND_ALL; + uint32_t op_freq; + struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); + + if (!session) { + sme_err("session NULL for vdev:%d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + op_freq = session->connectedProfile.op_freq; + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) + band = BAND_5G; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) + band = BAND_2G; + else + band = BAND_UNKNOWN; + } + host_channels = sizeof(mac_ctx->roam.valid_ch_freq_list); + status = csr_get_cfg_valid_channels(mac_ctx, + mac_ctx->roam.valid_ch_freq_list, + &host_channels); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to get the valid channel list"); + return status; + } + + ch_freq_list = mac_ctx->roam.valid_ch_freq_list; + mac_ctx->roam.numValidChannels = host_channels; + + for (i = 0; i < mac_ctx->roam.numValidChannels; i++) { + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_freq_list, + band)) { + ch_freq_list++; + continue; + } + rso_chan_info->chan_freq_list[num_channels++] = *ch_freq_list; + ch_freq_list++; + } + rso_chan_info->chan_count = num_channels; + rso_chan_info->chan_cache_type = CHANNEL_LIST_DYNAMIC; + + return status; +} + +/** + * csr_cm_fetch_ch_lst_from_ini() - fetch channel list from ini and update req msg + * parameters + * @mac_ctx: global mac ctx + * @roam_info: roam info struct + * @rso_chan_info: + * + * Return: QDF_STATUS + */ +static QDF_STATUS csr_cm_fetch_ch_lst_from_ini( + struct mac_context *mac_ctx, + tpCsrNeighborRoamControlInfo roam_info, + struct wlan_roam_scan_channel_list *rso_chan_info) +{ + QDF_STATUS status; + tCsrChannelInfo *specific_chan_info; + + specific_chan_info = &roam_info->cfgParams.specific_chan_info; + + status = csr_cm_populate_roam_chan_list(mac_ctx, rso_chan_info, + specific_chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to copy channels to roam list"); + return status; + } + rso_chan_info->chan_cache_type = CHANNEL_LIST_STATIC; + + return QDF_STATUS_SUCCESS; +} + +static void +csr_cm_fill_rso_channel_list(struct mac_context *mac_ctx, + struct wlan_roam_scan_channel_list *rso_chan_info, + uint8_t vdev_id, uint8_t reason) +{ + tpCsrNeighborRoamControlInfo roam_info = + &mac_ctx->roam.neighborRoamInfo[vdev_id]; + tCsrChannelInfo *specific_chan_info = + &roam_info->cfgParams.specific_chan_info; + tpCsrChannelInfo curr_ch_lst_info = + &roam_info->roamChannelInfo.currentChannelListInfo; + QDF_STATUS status; + bool ese_neighbor_list_recvd = false; + uint8_t ch_cache_str[128] = {0}; + uint8_t i, j; + +#ifdef FEATURE_WLAN_ESE + /* + * this flag will be true if connection is ESE and no neighbor + * list received or if the connection is not ESE + */ + ese_neighbor_list_recvd = ((roam_info->isESEAssoc) + && (roam_info->roamChannelInfo.IAPPNeighborListReceived + == false)) || (!roam_info->isESEAssoc); +#endif /* FEATURE_WLAN_ESE */ + + rso_chan_info->vdev_id = vdev_id; + if (ese_neighbor_list_recvd || + curr_ch_lst_info->numOfChannels == 0) { + /* + * Retrieve the Channel Cache either from ini or from + * the occupied channels list along with preferred + * channel list configured by the client. + * Give Preference to INI Channels + */ + if (specific_chan_info->numOfChannels) { + status = csr_cm_fetch_ch_lst_from_ini(mac_ctx, + roam_info, + rso_chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Fetch channel list from ini failed"); + return; + } + } else if (reason == REASON_FLUSH_CHANNEL_LIST) { + rso_chan_info->chan_cache_type = CHANNEL_LIST_STATIC; + rso_chan_info->chan_count = 0; + } else { + csr_cm_fetch_ch_lst_from_occupied_lst(mac_ctx, + roam_info, + rso_chan_info, + vdev_id, reason); + /* Add the preferred channel list configured by + * client to the roam channel list along with + * occupied channel list. + */ + csr_cm_add_ch_lst_from_roam_scan_list(mac_ctx, + rso_chan_info, + roam_info); + } + } else { + /* + * If ESE is enabled, and a neighbor Report is received, + * then Ignore the INI Channels or the Occupied Channel + * List. Consider the channels in the neighbor list sent + * by the ESE AP + */ + csr_cm_fetch_ch_lst_from_received_list(mac_ctx, roam_info, + curr_ch_lst_info, + rso_chan_info); + } + + if (!rso_chan_info->chan_count && + reason != REASON_FLUSH_CHANNEL_LIST) { + /* Maintain the Valid Channels List */ + status = csr_cm_fetch_valid_ch_lst(mac_ctx, rso_chan_info, + vdev_id); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Fetch channel list fail"); + return; + } + } + + for (i = 0, j = 0; i < rso_chan_info->chan_count; i++) { + if (j < sizeof(ch_cache_str)) + j += snprintf(ch_cache_str + j, + sizeof(ch_cache_str) - j, " %d", + rso_chan_info->chan_freq_list[i]); + else + break; + } + + sme_debug("ChnlCacheType:%d, No of Chnls:%d,Channels: %s", + rso_chan_info->chan_cache_type, + rso_chan_info->chan_count, ch_cache_str); +} + #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) static bool csr_cm_fill_rso_sae_single_pmk_info(struct mac_context *mac_ctx, @@ -20430,6 +20781,8 @@ wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, csr_cm_roam_scan_offload_ap_profile(mac_ctx, session, &req->profile_params); + csr_cm_fill_rso_channel_list(mac_ctx, &req->rso_chan_info, vdev_id, + reason); csr_cm_roam_scan_filter(mac_ctx, vdev_id, ROAM_SCAN_OFFLOAD_START, reason, &req->scan_filter_params); @@ -20537,6 +20890,8 @@ wlan_cm_roam_fill_update_config_req(struct wlan_objmgr_psoc *psoc, csr_cm_roam_scan_offload_ap_profile(mac_ctx, session, &req->profile_params); + csr_cm_fill_rso_channel_list(mac_ctx, &req->rso_chan_info, vdev_id, + reason); return QDF_STATUS_SUCCESS; }