qcacld-3.0: Changes for PER based roaming

DUT should be able to roam to a better access point if current
AP is having congestion/packet error.

This roam also devise a new selection logic for candidate
selection which considers channel congestion and AP capabilities.

Change-Id: I39594e37bd209be2603a4636514e2c9b1a907761
CRs-Fixed: 1090934
This commit is contained in:
Kapil Gupta 2016-12-29 18:44:26 +05:30 • committed by qcabuildsw
commit 5cda2251d6
10 changed files with 411 additions and 0 deletions

View file

@ -8890,6 +8890,134 @@ enum hdd_wext_control {
#endif
/*
* <ini>
* gper_roam_enabled - To enabled/disable PER based roaming in FW
* @Min: 0
* @Max: 1
* @Default: 1
*
* This ini is used to enable/disable Packet error based roaming, enabling this
* will cause DUT to monitor Tx and Rx traffic and roam to a better candidate
* if current is not good enough.
*
* Related: gper_roam_high_rate_th, gper_roam_low_rate_th,
* gper_roam_th_percent, gper_roam_rest_time
*
* Supported Feature: LFR-3.0
*
* Usage: Internal
*
* </ini>
*/
#define CFG_PER_ROAM_ENABLE_NAME "gper_roam_enabled"
#define CFG_PER_ROAM_ENABLE_MIN (0)
#define CFG_PER_ROAM_ENABLE_MAX (1)
#define CFG_PER_ROAM_ENABLE_DEFAULT (CFG_PER_ROAM_ENABLE_MAX)
/*
* <ini>
* gper_roam_high_rate_th - Rate at which PER based roam will stop
* @Min: 1 Mbps
* @Max: 0xffffffff
* @Default: 40 Mbps
*
* This ini is used to define the data rate in mbps*10 at which FW will stop
* monitoring the traffic for PER based roam.
*
* Related: gper_roam_enabled, gper_roam_low_rate_th,
* gper_roam_th_percent, gper_roam_rest_time
*
* Supported Feature: LFR-3.0
*
* Usage: Internal
*
* </ini>
*/
#define CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_NAME "gper_roam_high_rate_th"
#define CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_MIN (10)
#define CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_MAX (0xffffffff)
#define CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_DEFAULT (400)
/*
* <ini>
* gper_roam_low_rate_th - Rate at which FW starts considering traffic for PER
* based roam.
*
* @Min: 1 Mbps
* @Max: 0xffffffff
* @Default: 20 Mbps
*
* This ini is used to define the rate in mbps*10 at which FW starts considering
* traffic for PER based roam, if gper_roam_th_percent of data is below this
* rate, FW will issue a roam scan.
*
* Related: gper_roam_enabled, gper_roam_high_rate_th,
* gper_roam_th_percent, gper_roam_rest_time
*
* Supported Feature: LFR-3.0
*
* Usage: Internal
*
* </ini>
*/
#define CFG_PER_ROAM_CONFIG_LOW_RATE_TH_NAME "gper_roam_low_rate_th"
#define CFG_PER_ROAM_CONFIG_LOW_RATE_TH_MIN (10)
#define CFG_PER_ROAM_CONFIG_LOW_RATE_TH_MAX (0xffffffff)
#define CFG_PER_ROAM_CONFIG_LOW_RATE_TH_DEFAULT (200)
/*
* <ini>
* gper_roam_th_percent - Percentage at which FW will issue a roam scan if
* traffic is below gper_roam_low_rate_th rate.
*
* @Min: 10%
* @Max: 100%
* @Default: 60%
*
* This ini is used to define the percentage at which FW will issue a roam scan
* if traffic is below gper_roam_low_rate_th rate.
*
* Related: gper_roam_enabled, gper_roam_high_rate_th,
* gper_roam_high_rate_th, gper_roam_rest_time
*
* Supported Feature: LFR-3.0
*
* Usage: Internal
*
* </ini>
*/
#define CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_NAME "gper_roam_th_percent"
#define CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_MIN (10)
#define CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_MAX (100)
#define CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_DEFAULT (60)
/*
* <ini>
* gper_roam_rest_time - Time for which FW will wait once it issues a
* roam scan.
*
* @Min: 10 seconds
* @Max: 3600 seconds
* @Default: 300 seconds
*
* This ini is used to define the time for which FW will wait once it issues a
* PER based roam scan.
*
* Related: gper_roam_enabled, gper_roam_high_rate_th,
* gper_roam_high_rate_th, gper_roam_th_percent
*
* Supported Feature: LFR-3.0
*
* Usage: Internal
*
* </ini>
*/
#define CFG_PER_ROAM_REST_TIME_NAME "gper_roam_rest_time"
#define CFG_PER_ROAM_REST_TIME_MIN (10)
#define CFG_PER_ROAM_REST_TIME_MAX (3600)
#define CFG_PER_ROAM_REST_TIME_DEFAULT (300)
/*
* Type declarations
*/
@ -9592,6 +9720,11 @@ struct hdd_config {
enum hdd_wext_control standard_wext_control;
enum hdd_wext_control private_wext_control;
bool sap_internal_restart;
bool is_per_roam_enabled;
uint32_t per_roam_high_rate_threshold;
uint32_t per_roam_low_rate_threshold;
uint32_t per_roam_th_percent;
uint32_t per_roam_rest_time;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

View file

@ -4188,6 +4188,7 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT,
CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN,
CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX),
REG_VARIABLE(CFG_STANDARD_WEXT_CONTROL_NAME, WLAN_PARAM_Integer,
struct hdd_config, standard_wext_control,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@ -4200,12 +4201,48 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_PRIVATE_WEXT_CONTROL_DEFAULT,
CFG_PRIVATE_WEXT_CONTROL_MIN,
CFG_PRIVATE_WEXT_CONTROL_MAX),
REG_VARIABLE(CFG_SAP_INTERNAL_RESTART_NAME, WLAN_PARAM_Integer,
struct hdd_config, sap_internal_restart,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_SAP_INTERNAL_RESTART_DEFAULT,
CFG_SAP_INTERNAL_RESTART_MIN,
CFG_SAP_INTERNAL_RESTART_MAX),
REG_VARIABLE(CFG_PER_ROAM_ENABLE_NAME, WLAN_PARAM_Integer,
struct hdd_config, is_per_roam_enabled,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_PER_ROAM_ENABLE_DEFAULT,
CFG_PER_ROAM_ENABLE_MIN,
CFG_PER_ROAM_ENABLE_MAX),
REG_VARIABLE(CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_NAME, WLAN_PARAM_Integer,
struct hdd_config, per_roam_high_rate_threshold,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_DEFAULT,
CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_MIN,
CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_MAX),
REG_VARIABLE(CFG_PER_ROAM_CONFIG_LOW_RATE_TH_NAME, WLAN_PARAM_Integer,
struct hdd_config, per_roam_low_rate_threshold,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_PER_ROAM_CONFIG_LOW_RATE_TH_DEFAULT,
CFG_PER_ROAM_CONFIG_LOW_RATE_TH_MIN,
CFG_PER_ROAM_CONFIG_LOW_RATE_TH_MAX),
REG_VARIABLE(CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_NAME,
WLAN_PARAM_Integer, struct hdd_config, per_roam_th_percent,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_DEFAULT,
CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_MIN,
CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_MAX),
REG_VARIABLE(CFG_PER_ROAM_REST_TIME_NAME, WLAN_PARAM_Integer,
struct hdd_config, per_roam_rest_time,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_PER_ROAM_REST_TIME_DEFAULT,
CFG_PER_ROAM_REST_TIME_MIN,
CFG_PER_ROAM_REST_TIME_MAX),
};
/**
@ -4980,6 +5017,31 @@ static void hdd_cfg_print_runtime_pm(hdd_context_t *hdd_ctx)
}
#endif
/**
* hdd_per_roam_print_ini_config()- Print PER roam specific INI configuration
* @hdd_ctx: handle to hdd context
*
* Return: None
*/
static void hdd_per_roam_print_ini_config(hdd_context_t *hdd_ctx)
{
hdd_info("Name = [%s] Value = [%u]",
CFG_PER_ROAM_ENABLE_NAME,
hdd_ctx->config->is_per_roam_enabled);
hdd_info("Name = [%s] Value = [%u]",
CFG_PER_ROAM_CONFIG_HIGH_RATE_TH_NAME,
hdd_ctx->config->per_roam_high_rate_threshold);
hdd_info("Name = [%s] Value = [%u]",
CFG_PER_ROAM_CONFIG_LOW_RATE_TH_NAME,
hdd_ctx->config->per_roam_low_rate_threshold);
hdd_info("Name = [%s] Value = [%u]",
CFG_PER_ROAM_CONFIG_RATE_TH_PERCENT_NAME,
hdd_ctx->config->per_roam_th_percent);
hdd_info("Name = [%s] Value = [%u]",
CFG_PER_ROAM_REST_TIME_NAME,
hdd_ctx->config->per_roam_rest_time);
}
/**
* hdd_cfg_print() - print the hdd configuration
* @iniTable: pointer to hdd context
@ -5655,6 +5717,7 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_info("Name = [%s] Value = [%d]",
CFG_SAP_INTERNAL_RESTART_NAME,
pHddCtx->config->sap_internal_restart);
hdd_per_roam_print_ini_config(pHddCtx);
}
@ -6810,6 +6873,43 @@ void hdd_set_pno_channel_prediction_config(
hdd_ctx->config->pnoscan_adaptive_dwell_mode;
}
#endif
/**
* hdd_update_per_config_to_sme() -initializes the sme config for PER roam
*
* @hdd_ctx: the pointer to hdd context
* @sme_config: sme configuation pointer
*
* Return: None
*/
static void hdd_update_per_config_to_sme(hdd_context_t *hdd_ctx,
tSmeConfigParams *sme_config)
{
sme_config->csrConfig.per_roam_config.enable =
hdd_ctx->config->is_per_roam_enabled;
/* Assigning Tx and Rx for same value */
sme_config->csrConfig.per_roam_config.tx_high_rate_thresh =
hdd_ctx->config->per_roam_high_rate_threshold;
sme_config->csrConfig.per_roam_config.rx_high_rate_thresh =
hdd_ctx->config->per_roam_high_rate_threshold;
/* Assigning Tx and Rx for same value */
sme_config->csrConfig.per_roam_config.tx_low_rate_thresh =
hdd_ctx->config->per_roam_low_rate_threshold;
sme_config->csrConfig.per_roam_config.rx_low_rate_thresh =
hdd_ctx->config->per_roam_low_rate_threshold;
/* Assigning Tx and Rx for same value */
sme_config->csrConfig.per_roam_config.tx_rate_thresh_percnt =
hdd_ctx->config->per_roam_th_percent;
sme_config->csrConfig.per_roam_config.rx_rate_thresh_percnt =
hdd_ctx->config->per_roam_th_percent;
sme_config->csrConfig.per_roam_config.per_rest_time =
hdd_ctx->config->per_roam_rest_time;
}
/**
* hdd_set_sme_config() -initializes the sme configuration parameters
*
@ -7135,6 +7235,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
smeConfig->csrConfig.roamscan_adaptive_dwell_mode =
pHddCtx->config->roamscan_adaptive_dwell_mode;
hdd_update_per_config_to_sme(pHddCtx, smeConfig);
smeConfig->csrConfig.enable_edca_params =
pConfig->enable_edca_params;

View file

@ -615,6 +615,10 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_SET_WOW_PULSE_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369)
#define SIR_HAL_SET_UDP_RESP_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 370)
#define SIR_HAL_SET_PER_ROAM_CONFIG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 371)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */

View file

@ -1309,6 +1309,7 @@ typedef struct tagCsrConfigParam {
struct csr_sta_roam_policy_params sta_roam_policy_params;
uint32_t tx_aggregation_size;
uint32_t rx_aggregation_size;
struct wmi_per_roam_config per_roam_config;
} tCsrConfigParam;
/* Tush */

View file

@ -638,6 +638,7 @@ typedef struct tagCsrConfig {
struct csr_sta_roam_policy_params sta_roam_policy;
uint32_t tx_aggregation_size;
uint32_t rx_aggregation_size;
struct wmi_per_roam_config per_roam_config;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {

View file

@ -2516,6 +2516,23 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pMac->roam.configParam.roamscan_adaptive_dwell_mode =
pParam->roamscan_adaptive_dwell_mode;
pMac->roam.configParam.per_roam_config.enable =
pParam->per_roam_config.enable;
pMac->roam.configParam.per_roam_config.tx_high_rate_thresh =
pParam->per_roam_config.tx_high_rate_thresh;
pMac->roam.configParam.per_roam_config.rx_high_rate_thresh =
pParam->per_roam_config.rx_high_rate_thresh;
pMac->roam.configParam.per_roam_config.tx_low_rate_thresh =
pParam->per_roam_config.tx_low_rate_thresh;
pMac->roam.configParam.per_roam_config.rx_low_rate_thresh =
pParam->per_roam_config.rx_low_rate_thresh;
pMac->roam.configParam.per_roam_config.tx_rate_thresh_percnt =
pParam->per_roam_config.tx_rate_thresh_percnt;
pMac->roam.configParam.per_roam_config.rx_rate_thresh_percnt =
pParam->per_roam_config.rx_rate_thresh_percnt;
pMac->roam.configParam.per_roam_config.per_rest_time =
pParam->per_roam_config.per_rest_time;
/* update p2p offload status */
pMac->pnoOffload = pParam->pnoOffload;
@ -2722,6 +2739,23 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
cfg_params->scan_adaptive_dwell_mode;
pParam->roamscan_adaptive_dwell_mode =
cfg_params->roamscan_adaptive_dwell_mode;
pParam->per_roam_config.enable = cfg_params->per_roam_config.enable;
pParam->per_roam_config.tx_high_rate_thresh =
cfg_params->per_roam_config.tx_high_rate_thresh;
pParam->per_roam_config.rx_high_rate_thresh =
cfg_params->per_roam_config.rx_high_rate_thresh;
pParam->per_roam_config.tx_low_rate_thresh =
cfg_params->per_roam_config.tx_low_rate_thresh;
pParam->per_roam_config.rx_low_rate_thresh =
cfg_params->per_roam_config.rx_low_rate_thresh;
pParam->per_roam_config.tx_rate_thresh_percnt =
cfg_params->per_roam_config.tx_rate_thresh_percnt;
pParam->per_roam_config.rx_rate_thresh_percnt =
cfg_params->per_roam_config.rx_rate_thresh_percnt;
pParam->per_roam_config.per_rest_time =
cfg_params->per_roam_config.per_rest_time;
pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
pParam->is_sta_connection_in_5gz_enabled =
@ -17548,6 +17582,104 @@ static void csr_update_driver_assoc_ies(tpAniSirGlobal mac_ctx,
}
/**
* csr_create_per_roam_request() - create PER roam offload scan request
*
* parameters
* @mac_ctx: global mac ctx
* @session_id: session id
*
* Return: per roam config request packet buffer
*/
static struct wmi_per_roam_config_req *
csr_create_per_roam_request(tpAniSirGlobal mac_ctx, uint8_t session_id)
{
struct wmi_per_roam_config_req *req_buf = NULL;
req_buf = qdf_mem_malloc(sizeof(struct wmi_per_roam_config_req));
if (!req_buf) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("Mem alloc for per roam req failed."));
return NULL;
}
req_buf->vdev_id = session_id;
req_buf->per_config.enable =
mac_ctx->roam.configParam.per_roam_config.enable;
req_buf->per_config.tx_high_rate_thresh =
mac_ctx->roam.configParam.per_roam_config.tx_high_rate_thresh;
req_buf->per_config.rx_high_rate_thresh =
mac_ctx->roam.configParam.per_roam_config.rx_high_rate_thresh;
req_buf->per_config.tx_low_rate_thresh =
mac_ctx->roam.configParam.per_roam_config.tx_low_rate_thresh;
req_buf->per_config.rx_low_rate_thresh =
mac_ctx->roam.configParam.per_roam_config.rx_low_rate_thresh;
req_buf->per_config.per_rest_time =
mac_ctx->roam.configParam.per_roam_config.per_rest_time;
req_buf->per_config.tx_rate_thresh_percnt =
mac_ctx->roam.configParam.per_roam_config.tx_rate_thresh_percnt;
req_buf->per_config.rx_rate_thresh_percnt =
mac_ctx->roam.configParam.per_roam_config.rx_rate_thresh_percnt;
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
FL("PER based roaming configuaration enable=%d vdev=%d high_rate_thresh=%d low_rate_thresh=%d rate_thresh_percnt=%d per_rest_time=%d"),
req_buf->per_config.enable, session_id,
req_buf->per_config.tx_high_rate_thresh,
req_buf->per_config.tx_low_rate_thresh,
req_buf->per_config.tx_rate_thresh_percnt,
req_buf->per_config.per_rest_time);
return req_buf;
}
/**
* csr_roam_offload_per_scan() - populates roam offload scan request and sends
* to WMA
*
* parameters
* @mac_ctx: global mac ctx
* @session_id: session id
*
* Return: result of operation
*/
static QDF_STATUS
csr_roam_offload_per_scan(tpAniSirGlobal mac_ctx, uint8_t session_id)
{
tpCsrNeighborRoamControlInfo roam_info =
&mac_ctx->roam.neighborRoamInfo[session_id];
struct wmi_per_roam_config_req *req_buf;
struct scheduler_msg msg;
/*
* No need to update in case of stop command, FW takes care of stopping
* this internally
*/
if (roam_info->last_sent_cmd == ROAM_SCAN_OFFLOAD_STOP)
return QDF_STATUS_SUCCESS;
if (!mac_ctx->roam.configParam.per_roam_config.enable) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("PER based roaming is disabled in configuration"));
return QDF_STATUS_SUCCESS;
}
req_buf = csr_create_per_roam_request(mac_ctx, session_id);
if (!req_buf) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("Failed to create req packet"));
return QDF_STATUS_E_FAILURE;
}
msg.type = WMA_SET_PER_ROAM_CONFIG_CMD;
msg.reserved = 0;
msg.bodyptr = req_buf;
if (!QDF_IS_STATUS_SUCCESS(scheduler_post_msg(QDF_MODULE_ID_WMA,
&msg))) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
"%s: Unable to post WMA_SET_PER_ROAM_CONFIG_CMD to WMA",
__func__);
qdf_mem_free(req_buf);
}
return QDF_STATUS_SUCCESS;
}
/**
* csr_roam_offload_scan() - populates roam offload scan request and sends to
* WMA
@ -17780,6 +17912,8 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
"Roam Scan Offload Command %d, Reason %d", command, reason);
/* Update PER config to FW after sending the command */
csr_roam_offload_per_scan(mac_ctx, session_id);
return status;
}

View file

@ -186,6 +186,16 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event,
uint32_t len);
#endif
/**
* wma_update_per_roam_config() -per roam config parameter updation to FW
* @handle: wma handle
* @req_buf: per roam config parameters
*
* Return: none
*/
void wma_update_per_roam_config(WMA_HANDLE handle,
struct wmi_per_roam_config_req *req_buf);
QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
tSirScanOffloadReq *scan_req,
struct scan_start_params *cmd);

View file

@ -486,6 +486,8 @@
#define WMA_SET_WOW_PULSE_CMD SIR_HAL_SET_WOW_PULSE_CMD
#define WMA_SET_PER_ROAM_CONFIG_CMD SIR_HAL_SET_PER_ROAM_CONFIG_CMD
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40

View file

@ -6789,6 +6789,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, struct scheduler_msg *msg)
(struct wifi_epno_params *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_SET_PER_ROAM_CONFIG_CMD:
wma_update_per_roam_config(wma_handle,
(struct wmi_per_roam_config_req *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_SET_PASSPOINT_LIST_REQ:
/* Issue reset passpoint network list first and clear
* the entries */

View file

@ -2039,6 +2039,25 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
return qdf_status;
}
void wma_update_per_roam_config(WMA_HANDLE handle,
struct wmi_per_roam_config_req *req_buf)
{
int status;
tp_wma_handle wma_handle = (tp_wma_handle) handle;
if (!wma_handle || !wma_handle->wmi_handle) {
WMA_LOGE("%s: WMA is closed, cannot send per roam config",
__func__);
return;
}
status = wmi_unified_set_per_roam_config(wma_handle->wmi_handle,
req_buf);
if (status != EOK)
WMA_LOGE("%s: failed to set per roam config to FW",
__func__);
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**