diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 9797b120ed32..ddb34f8f59cf 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1422,6 +1422,8 @@ struct bss_load_trigger { * @roam_scan_period_after_inactivity: Roam scan period after device was in * inactive state * @fw_akm_bitmap: Supported Akm suites of firmware + * @roam_full_scan_period: Idle period in seconds between two successive + * full channel roam scans */ struct wlan_mlme_lfr_cfg { bool mawc_roam_enabled; @@ -1524,6 +1526,7 @@ struct wlan_mlme_lfr_cfg { uint32_t roam_inactive_data_packet_count; uint32_t roam_scan_period_after_inactivity; uint32_t fw_akm_bitmap; + uint32_t roam_full_scan_period; }; /** diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 1fdede4af1d1..56d430fd5001 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -3869,4 +3869,13 @@ ucfg_mlme_get_peer_phymode(struct wlan_objmgr_psoc *psoc, uint8_t *mac, { return mlme_get_peer_phymode(psoc, mac, peer_phymode); } + +/** + * ucfg_mlme_validate_full_roam_scan_period() - Validate full roam scan period + * @full_roam_scan_period: Idle period in seconds between two successive + * full channel roam scans + * + * Return: True if full_roam_scan_period is in expected range, false otherwise. + */ +bool ucfg_mlme_validate_full_roam_scan_period(uint32_t full_roam_scan_period); #endif /* _WLAN_MLME_UCFG_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index b5ba15fda340..964371982639 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1666,3 +1666,19 @@ ucfg_mlme_set_channel_bonding_5ghz(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +bool ucfg_mlme_validate_full_roam_scan_period(uint32_t full_roam_scan_period) +{ + bool is_valid = true; + uint32_t min, max; + + if (!cfg_in_range(CFG_LFR_FULL_ROAM_SCAN_REFRESH_PERIOD, + full_roam_scan_period)) { + min = (cfg_min(CFG_LFR_FULL_ROAM_SCAN_REFRESH_PERIOD)); + max = (cfg_max(CFG_LFR_FULL_ROAM_SCAN_REFRESH_PERIOD)); + mlme_legacy_err("Full roam scan period value %d is out of range (Min: %d Max: %d)", + full_roam_scan_period, min, max); + is_valid = false; + } + + return is_valid; +} diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 2d31d30ee877..68f3d3fbf55e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4111,8 +4111,41 @@ hdd_send_roam_scan_channel_freq_list_to_sme(struct hdd_context *hdd_ctx, static const struct nla_policy roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = { [PARAM_FREQ_LIST_SCHEME] = {.type = NLA_NESTED}, + [QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD] = {.type = NLA_U32}, }; +/** + * hdd_send_roam_full_scan_period_to_sme() - Send full roam scan period to SME + * @hdd_ctx: HDD context + * @vdev_id: vdev id + * @full_roam_scan_period: Idle period in seconds between two successive + * full channel roam scans + * + * Validate the full roam scan period and send it to firmware + * + * Return: QDF_STATUS + */ +static QDF_STATUS +hdd_send_roam_full_scan_period_to_sme(struct hdd_context *hdd_ctx, + uint8_t vdev_id, + uint32_t full_roam_scan_period) +{ + QDF_STATUS status; + + if (!ucfg_mlme_validate_full_roam_scan_period(full_roam_scan_period)) + return QDF_STATUS_E_INVAL; + + hdd_debug("Received Command to Set full roam scan period = %u", + full_roam_scan_period); + + status = sme_update_full_roam_scan_period(hdd_ctx->mac_handle, vdev_id, + full_roam_scan_period); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Failed to set full scan period"); + + return status; +} + /** * hdd_set_roam_with_control_config() - Set roam control configuration * @hdd_ctx: HDD context @@ -4131,6 +4164,7 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, { QDF_STATUS status = QDF_STATUS_SUCCESS; struct nlattr *tb2[QCA_ATTR_ROAM_CONTROL_MAX + 1], *attr; + uint32_t value; /* The command must carry PARAM_ROAM_CONTROL_CONFIG */ if (!tb[PARAM_ROAM_CONTROL_CONFIG]) { @@ -4154,6 +4188,17 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, hdd_err("failed to config roam control"); } + attr = tb2[QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD]; + if (attr) { + hdd_debug("Parse and send full scan period to firmware"); + value = nla_get_u32(attr); + status = hdd_send_roam_full_scan_period_to_sme(hdd_ctx, + vdev_id, + value); + if (status) + hdd_err("failed to config full scan period"); + } + return qdf_status_to_os_return(status); } diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index ad0695a05936..85b84e60cf0a 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -2251,6 +2251,7 @@ struct roam_offload_scan_req { uint32_t btm_query_bitmask; struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_TRIGGERS]; struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS]; + uint32_t full_roam_scan_period; }; struct roam_offload_scan_rsp { diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index c1e3e2e5531c..a2459a4c10c5 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -64,6 +64,7 @@ typedef struct sCsrNeighborRoamCfgParams { uint32_t hi_rssi_scan_delay; int32_t hi_rssi_scan_rssi_ub; tCsrChannelInfo pref_chan_info; + uint32_t full_roam_scan_period; } tCsrNeighborRoamCfgParams, *tpCsrNeighborRoamCfgParams; #define CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX 255 @@ -250,6 +251,7 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ptr); #define REASON_FILS_PARAMS_CHANGED 41 #define REASON_SME_ISSUED 42 #define REASON_DRIVER_ENABLED 43 +#define REASON_ROAM_FULL_SCAN_PERIOD_CHANGED 44 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) QDF_STATUS csr_roam_offload_scan(struct mac_context *mac, uint8_t sessionId, diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index b6e7ad128f80..250617bbc999 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -817,6 +817,20 @@ uint16_t sme_get_neighbor_scan_refresh_period(mac_handle_t mac_handle); uint16_t sme_get_empty_scan_refresh_period(mac_handle_t mac_handle); QDF_STATUS sme_update_empty_scan_refresh_period(mac_handle_t mac_handle, uint8_t sessionId, uint16_t empty_scan_refresh_period); +/** + * sme_update_full_roam_scan_period() - Send full roam scan period to SME + * @mac_handle: Opaque handle to the MAC context + * @vdev_id: vdev id + * @full_roam_scan_period: Idle period in seconds between two successive + * full channel roam scans + * + * Updated full scan period in roam info and a roam_offload_scan request. + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_update_full_roam_scan_period(mac_handle_t mac_handle, + uint8_t vdev_id, + uint32_t full_roam_scan_period); QDF_STATUS sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle, const uint16_t nNeighborScanMinChanTime, uint8_t sessionId); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 8fbc0f1bee2c..52428bfce90c 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -6799,6 +6799,41 @@ QDF_STATUS sme_update_empty_scan_refresh_period(mac_handle_t mac_handle, return status; } +QDF_STATUS sme_update_full_roam_scan_period(mac_handle_t mac_handle, + uint8_t vdev_id, + uint32_t full_roam_scan_period) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + QDF_STATUS status; + tpCsrNeighborRoamControlInfo neighbor_roam_info; + + if (vdev_id >= WLAN_MAX_VDEVS) { + sme_err("Invalid vdev_id: %d", vdev_id); + return QDF_STATUS_E_INVAL; + } + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + neighbor_roam_info = &mac->roam.neighborRoamInfo[vdev_id]; + sme_debug("LFR runtime successfully set full roam scan period to %d -old value is %d - roam state is %s", + full_roam_scan_period, + neighbor_roam_info->cfgParams.full_roam_scan_period, + mac_trace_get_neighbour_roam_state( + neighbor_roam_info->neighborRoamState)); + neighbor_roam_info->cfgParams.full_roam_scan_period = + full_roam_scan_period; + if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) { + csr_roam_offload_scan(mac, vdev_id, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_FULL_SCAN_PERIOD_CHANGED); + } + sme_release_global_lock(&mac->sme); + + return status; +} + /* * sme_set_neighbor_scan_min_chan_time() - * Update nNeighborScanMinChanTime diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 3146844fafbc..07f0b8a6fa6d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -2471,6 +2471,8 @@ QDF_STATUS csr_change_default_config_param(struct mac_context *mac, mac->mlme_cfg->lfr.roam_bmiss_final_bcnt); sme_debug("roam_beacon_rssi_weight: %d", mac->mlme_cfg->lfr.roam_beacon_rssi_weight); + sme_debug("full_scan_period: %u", + mac->mlme_cfg->lfr.roam_full_scan_period); mac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan; mac->roam.configParam.fScanTwice = pParam->fScanTwice; /* This parameter is not available in cfg and not passed from @@ -18142,6 +18144,8 @@ csr_create_roam_scan_offload_request(struct mac_context *mac_ctx, roam_info->cfgParams.maxChannelScanTime; req_buf->EmptyRefreshScanPeriod = roam_info->cfgParams.emptyScanRefreshPeriod; + req_buf->full_roam_scan_period = + roam_info->cfgParams.full_roam_scan_period; req_buf->roam_scan_inactivity_time = mac_ctx->mlme_cfg->lfr.roam_scan_inactivity_time; req_buf->roam_inactive_data_packet_count = diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index ebb4461574e8..fb62b9757c3b 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -1246,6 +1246,8 @@ QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId) mac->mlme_cfg->lfr.neighbor_scan_results_refresh_period; pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = mac->mlme_cfg->lfr.empty_scan_refresh_period; + pNeighborRoamInfo->cfgParams.full_roam_scan_period = + mac->mlme_cfg->lfr.roam_full_scan_period; specific_chan_info = &pNeighborRoamInfo->cfgParams.specific_chan_info; specific_chan_info->numOfChannels = diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 76cba7b620f4..278a1c6dcbf8 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -624,6 +624,7 @@ wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle, roam_req->roam_inactive_data_packet_count; scan_period_params.roam_scan_period_after_inactivity = roam_req->roam_scan_period_after_inactivity; + scan_period_params.full_scan_period = roam_req->full_roam_scan_period; return wmi_unified_roam_scan_offload_scan_period(wma_handle->wmi_handle, &scan_period_params);