qcacld-3.0: Migrate validate beacon interval API

Move the beacon interval validation logic from the CSR module to the
interface manager module.
Add a path to send events to the SAP event handler from the MLME
module.

Change-Id: Ia86f219b3f209b53e7818a80f95b2c0555550736
CRs-fixed: 2796676
Bu işleme şunda yer alıyor:
Lincoln Tran
2020-10-12 17:00:26 -07:00
işlemeyi yapan: snandini
ebeveyn 4dc88ec52f
işleme 746140e284
12 değiştirilmiş dosya ile 772 ekleme ve 503 silme

Dosyayı Görüntüle

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -54,6 +54,49 @@ struct bssid_search_arg {
uint8_t vdev_id;
};
/**
* allow_mcc_go_diff_bi_definition - Defines the config values for allowing
* different beacon intervals between P2P-G0 and STA
* @ALLOW_MCC_GO_DIFF_BI_WFA_CERT: GO Beacon interval is not changed.
* MCC GO doesn't work well in optimized way. In worst scenario, it may
* invite STA disconnection.
* @ALLOW_MCC_GO_DIFF_BI_WORKAROUND: Workaround 1 disassoc all the clients and
* update beacon Interval.
* @ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN: Tear down the P2P link in
* auto/Non-autonomous -GO case.
* @ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT: Don't disconnect the P2P client in
* autonomous/Non-autonomous -GO case update the BI dynamically
*/
enum allow_mcc_go_diff_bi_definition {
ALLOW_MCC_GO_DIFF_BI_WFA_CERT = 1,
ALLOW_MCC_GO_DIFF_BI_WORKAROUND,
ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN,
ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT,
};
/**
* struct beacon_interval_arg - Contains beacon interval validation arguments
* @curr_vdev_id: current iterator vdev ID
* @curr_bss_opmode: current iterator BSS's opmode
* @ch_freq: current operating channel frequency
* @bss_beacon_interval: beacon interval that can be updated by callee
* @status: status to be filled by callee
* @is_done: boolean to stop iterating
* @update_beacon_interval: boolean to mark beacon interval as updated by callee
*
* This structure is used to pass the candidate validation information to the
* callback
*/
struct beacon_interval_arg {
uint8_t curr_vdev_id;
enum QDF_OPMODE curr_bss_opmode;
qdf_freq_t ch_freq;
uint16_t bss_beacon_interval;
QDF_STATUS status;
bool is_done;
bool update_beacon_interval;
};
/**
* if_mgr_enable_roaming() - interface manager enable roaming
* @pdev: pdev object
@@ -120,6 +163,23 @@ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
struct wlan_objmgr_vdev *vdev,
enum wlan_cm_rso_control_requestor requestor);
/**
* if_mgr_is_beacon_interval_valid() - checks if the concurrent session is
* valid
* @pdev: pdev object
* @vdev_id: vdev ID
* @candidate: concurrent candidate info
*
* This function validates the beacon interval with all other active vdevs.
*
* Context: It should run in thread context
*
* Return: true if session is valid, false if not
*/
bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
uint8_t vdev_id,
struct validate_bss_data *candidate);
/**
* if_mgr_validate_candidate() - validate candidate event handler
* @vdev: vdev object

Dosyayı Görüntüle

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -29,6 +29,9 @@
#include "wlan_p2p_ucfg_api.h"
#include "cds_api.h"
#include "sme_api.h"
#include "wlan_vdev_mgr_utils_api.h"
#include "wni_api.h"
#include "wlan_mlme_vdev_mgr_interface.h"
static void if_mgr_enable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
@@ -177,6 +180,519 @@ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
return status;
}
/**
* if_mgr_calculate_mcc_beacon_interval() - Calculates the new beacon interval
* @sta_bi: station beacon interval
* @go_given_bi: P2P GO's given beacon interval
*
* This function has 3 stages. First it modifies the input go_given_bi to be
* within 100 to 199. Then it checks if the sta_bi and go_given_bi are multiples
* of each other. If they are, that means the 2 values are compatible, and just
* return as is, otherwise, find new compatible BI for P2P GO
*
* Return: valid beacon interval value
*/
static uint16_t if_mgr_calculate_mcc_beacon_interval(uint16_t sta_bi,
uint16_t go_given_bi)
{
uint8_t num_beacons, is_multiple;
uint16_t go_calculated_bi, go_final_bi, sta_calculated_bi;
/* ensure BI ranges between 100 and 200 */
if (go_given_bi < 100)
go_calculated_bi = 100;
else
go_calculated_bi = 100 + (go_given_bi % 100);
if (sta_bi == 0) {
/* There is possibility to receive zero as value.
* Which will cause divide by zero. Hence initialise with 100
*/
sta_bi = 100;
ifmgr_warn("sta_bi 2nd parameter is zero, initialize to %d",
sta_bi);
}
/* check, if either one is multiple of another */
if (sta_bi > go_calculated_bi)
is_multiple = !(sta_bi % go_calculated_bi);
else
is_multiple = !(go_calculated_bi % sta_bi);
/* if it is multiple, then accept GO's beacon interval
* range [100,199] as it is
*/
if (is_multiple)
return go_calculated_bi;
/* else , if it is not multiple, then then check for number of beacons
* to be inserted based on sta BI
*/
num_beacons = sta_bi / 100;
if (num_beacons) {
/* GO's final beacon interval will be aligned to sta beacon
* interval, but in the range of [100, 199].
*/
sta_calculated_bi = sta_bi / num_beacons;
go_final_bi = sta_calculated_bi;
} else {
/* if STA beacon interval is less than 100, use GO's change
* beacon interval instead of updating to STA's beacon interval.
*/
go_final_bi = go_calculated_bi;
}
return go_final_bi;
}
static QDF_STATUS
if_mgr_send_chng_mcc_beacon_interval(struct wlan_objmgr_vdev *vdev,
struct beacon_interval_arg *bss_arg)
{
struct scheduler_msg msg = {0};
struct wlan_change_bi *p_msg;
uint16_t len = 0;
QDF_STATUS status;
uint8_t *mac_addr;
if (!bss_arg->update_beacon_interval)
return QDF_STATUS_SUCCESS;
bss_arg->update_beacon_interval = false;
len = sizeof(*p_msg);
p_msg = qdf_mem_malloc(len);
if (!p_msg)
return QDF_STATUS_E_NOMEM;
p_msg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
p_msg->length = len;
mac_addr = wlan_vdev_get_hw_macaddr(vdev);
qdf_mem_copy(&p_msg->bssid, mac_addr, QDF_MAC_ADDR_SIZE);
ifmgr_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
p_msg->session_id = wlan_vdev_get_id(vdev);
ifmgr_debug("session %d BeaconInterval %d", p_msg->session_id,
bss_arg->bss_beacon_interval);
p_msg->beacon_interval = bss_arg->bss_beacon_interval;
msg.type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
msg.bodyval = 0;
msg.bodyptr = p_msg;
status = scheduler_post_message(QDF_MODULE_ID_PE,
QDF_MODULE_ID_PE,
QDF_MODULE_ID_PE, &msg);
if (status != QDF_STATUS_SUCCESS)
qdf_mem_free(p_msg);
return status;
}
static void if_mgr_update_beacon_interval(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
struct wlan_objmgr_psoc *psoc;
uint8_t allow_mcc_go_diff_bi;
struct wlan_objmgr_peer *peer;
enum wlan_peer_type bss_persona;
struct beacon_interval_arg *bss_arg = arg;
struct wlan_objmgr_vdev *vdev = object;
uint8_t vdev_id = wlan_vdev_get_id(vdev);
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc)
return;
policy_mgr_get_allow_mcc_go_diff_bi(psoc, &allow_mcc_go_diff_bi);
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
if (!peer)
return;
bss_persona = wlan_peer_get_peer_type(peer);
wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
/*
* If GO in MCC support different beacon interval,
* change the BI of the P2P-GO
*/
if (bss_persona == WLAN_PEER_P2P_GO)
return;
/*
* Handle different BI scenario based on the
* configuration set. If Config is not set to 0x04 then
* Disconnect all the P2P clients associated. If config
* is set to 0x04 then update the BI without
* disconnecting all the clients
*/
if (allow_mcc_go_diff_bi == ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT &&
bss_arg->update_beacon_interval) {
bss_arg->status =
if_mgr_send_chng_mcc_beacon_interval(vdev, bss_arg);
return;
} else if (bss_arg->update_beacon_interval) {
/*
* If the configuration of fAllowMCCGODiffBI is set to
* other than 0x04
*/
bss_arg->status = wlan_sap_disconnect_all_p2p_client(vdev_id);
return;
}
}
static QDF_STATUS
if_mgr_update_mcc_p2p_beacon_interval(struct wlan_objmgr_vdev *vdev,
struct beacon_interval_arg *bss_arg)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
uint8_t enable_mcc_mode;
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev)
return QDF_STATUS_E_FAILURE;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc)
return QDF_STATUS_E_FAILURE;
/* If MCC is not supported just break and return SUCCESS */
wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
if (!enable_mcc_mode)
return QDF_STATUS_E_FAILURE;
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
if_mgr_update_beacon_interval,
bss_arg, 0, WLAN_IF_MGR_ID);
return bss_arg->status;
}
static bool if_mgr_validate_sta_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
struct beacon_interval_arg *bss_arg)
{
struct wlan_objmgr_psoc *psoc;
struct vdev_mlme_obj *vdev_mlme;
struct wlan_objmgr_peer *peer;
uint16_t new_bcn_interval;
uint32_t beacon_interval;
struct wlan_channel *chan;
enum QDF_OPMODE curr_persona;
enum wlan_peer_type bss_persona;
uint8_t allow_mcc_go_diff_bi;
uint8_t conc_rule1 = 0, conc_rule2 = 0;
uint8_t vdev_id = wlan_vdev_get_id(vdev);
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc)
return false;
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
if (!peer)
return false;
curr_persona = wlan_vdev_mlme_get_opmode(vdev);
bss_persona = wlan_peer_get_peer_type(peer);
wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
if (curr_persona == QDF_P2P_CLIENT_MODE) {
ifmgr_debug("Bcn Intrvl validation not require for STA/CLIENT");
return false;
}
chan = wlan_vdev_get_active_channel(vdev);
if (!chan) {
ifmgr_err("failed to get active channel");
return false;
}
vdev_mlme =
wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_IF_MGR);
if (!vdev_mlme) {
QDF_ASSERT(0);
return false;
}
wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
&beacon_interval);
if (bss_persona == WLAN_PEER_AP &&
(chan->ch_cfreq1 != bss_arg->ch_freq ||
chan->ch_cfreq2 != bss_arg->ch_freq)) {
ifmgr_debug("*** MCC with SAP+STA sessions ****");
bss_arg->status = QDF_STATUS_SUCCESS;
return true;
}
if (bss_persona == WLAN_PEER_P2P_GO &&
(chan->ch_cfreq1 != bss_arg->ch_freq ||
chan->ch_cfreq2 != bss_arg->ch_freq) &&
beacon_interval != bss_arg->bss_beacon_interval) {
policy_mgr_get_allow_mcc_go_diff_bi(psoc,
&allow_mcc_go_diff_bi);
switch (allow_mcc_go_diff_bi) {
case ALLOW_MCC_GO_DIFF_BI_WFA_CERT:
bss_arg->status = QDF_STATUS_SUCCESS;
return true;
case ALLOW_MCC_GO_DIFF_BI_WORKAROUND:
/* fall through */
case ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT:
policy_mgr_get_conc_rule1(psoc, &conc_rule1);
policy_mgr_get_conc_rule2(psoc, &conc_rule2);
if (conc_rule1 || conc_rule2)
new_bcn_interval = CUSTOM_CONC_GO_BI;
else
new_bcn_interval =
if_mgr_calculate_mcc_beacon_interval(
bss_arg->bss_beacon_interval,
beacon_interval);
ifmgr_debug("Peer AP BI : %d, new Beacon Interval: %d",
bss_arg->bss_beacon_interval,
new_bcn_interval);
/* Update the beacon interval */
if (new_bcn_interval != beacon_interval) {
ifmgr_err("Beacon Interval got changed config used: %d",
allow_mcc_go_diff_bi);
bss_arg->bss_beacon_interval = new_bcn_interval;
bss_arg->update_beacon_interval = true;
bss_arg->status =
if_mgr_update_mcc_p2p_beacon_interval(
vdev,
bss_arg);
return true;
}
bss_arg->status = QDF_STATUS_SUCCESS;
return true;
case ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN:
bss_arg->update_beacon_interval = false;
bss_arg->status = wlan_sap_stop_bss(vdev_id);
return true;
default:
ifmgr_err("BcnIntrvl is diff can't connect to preferred AP");
bss_arg->status = QDF_STATUS_E_FAILURE;
return true;
}
}
return false;
}
static bool if_mgr_validate_p2pcli_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
struct beacon_interval_arg *bss_arg)
{
enum QDF_OPMODE curr_persona;
enum wlan_peer_type bss_persona;
uint32_t beacon_interval;
struct wlan_channel *chan;
struct wlan_objmgr_peer *peer;
struct vdev_mlme_obj *vdev_mlme;
curr_persona = wlan_vdev_mlme_get_opmode(vdev);
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
if (!peer)
return false;
bss_persona = wlan_peer_get_peer_type(peer);
wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);
chan = wlan_vdev_get_active_channel(vdev);
if (!chan) {
ifmgr_err("failed to get active channel");
return false;
}
vdev_mlme =
wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_IF_MGR);
if (!vdev_mlme) {
QDF_ASSERT(0);
return false;
}
wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
&beacon_interval);
if (curr_persona == QDF_STA_MODE) {
ifmgr_debug("Ignore Beacon Interval Validation...");
} else if (bss_persona == WLAN_PEER_P2P_GO) {
if ((chan->ch_cfreq1 != bss_arg->ch_freq ||
chan->ch_cfreq2 != bss_arg->ch_freq) &&
beacon_interval != bss_arg->bss_beacon_interval) {
ifmgr_err("BcnIntrvl is diff can't connect to P2P_GO network");
bss_arg->status = QDF_STATUS_E_FAILURE;
return true;
}
}
return false;
}
static bool
if_mgr_validate_p2pgo_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
struct beacon_interval_arg *bss_arg)
{
struct wlan_objmgr_psoc *psoc;
struct vdev_mlme_obj *vdev_mlme;
enum QDF_OPMODE curr_persona;
uint32_t beacon_interval;
struct wlan_channel *chan;
uint8_t conc_rule1 = 0, conc_rule2 = 0;
uint16_t new_bcn_interval;
curr_persona = wlan_vdev_mlme_get_opmode(vdev);
chan = wlan_vdev_get_active_channel(vdev);
if (!chan) {
ifmgr_err("failed to get active channel");
return false;
}
vdev_mlme =
wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_IF_MGR);
if (!vdev_mlme) {
QDF_ASSERT(0);
return false;
}
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc)
return false;
wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
&beacon_interval);
if ((curr_persona == QDF_P2P_CLIENT_MODE) ||
(curr_persona == QDF_STA_MODE)) {
/* check for P2P_client scenario */
if ((chan->ch_cfreq1 == 0) && (chan->ch_cfreq2 == 0) &&
(beacon_interval == 0))
return false;
if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP &&
(chan->ch_cfreq1 != bss_arg->ch_freq ||
chan->ch_cfreq2 != bss_arg->ch_freq) &&
beacon_interval != bss_arg->bss_beacon_interval) {
/*
* Updated beaconInterval should be used only when
* we are starting a new BSS not incase of
* client or STA case
*/
policy_mgr_get_conc_rule1(psoc, &conc_rule1);
policy_mgr_get_conc_rule2(psoc, &conc_rule2);
/* Calculate beacon Interval for P2P-GO incase of MCC */
if (conc_rule1 || conc_rule2) {
new_bcn_interval = CUSTOM_CONC_GO_BI;
} else {
new_bcn_interval =
if_mgr_calculate_mcc_beacon_interval(
beacon_interval,
bss_arg->bss_beacon_interval);
}
if (new_bcn_interval != bss_arg->bss_beacon_interval)
bss_arg->bss_beacon_interval = new_bcn_interval;
bss_arg->status = QDF_STATUS_SUCCESS;
return true;
}
}
return false;
}
static void if_mgr_validate_beacon_interval(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
struct beacon_interval_arg *bss_arg = arg;
struct wlan_objmgr_vdev *vdev = object;
uint8_t iter_vdev_id = wlan_vdev_get_id(vdev);
bool is_done = false;
if (iter_vdev_id == bss_arg->curr_vdev_id)
return;
if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
return;
if (bss_arg->is_done)
return;
switch (bss_arg->curr_bss_opmode) {
case QDF_STA_MODE:
is_done = if_mgr_validate_sta_bcn_intrvl(vdev, bss_arg);
break;
case QDF_P2P_CLIENT_MODE:
is_done = if_mgr_validate_p2pcli_bcn_intrvl(vdev, bss_arg);
break;
case QDF_SAP_MODE:
case QDF_IBSS_MODE:
break;
case QDF_P2P_GO_MODE:
is_done = if_mgr_validate_p2pgo_bcn_intrvl(vdev, bss_arg);
break;
default:
ifmgr_err("BSS opmode not supported: %d",
bss_arg->curr_bss_opmode);
}
if (is_done)
bss_arg->is_done = is_done;
}
bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
uint8_t vdev_id,
struct validate_bss_data *candidate)
{
struct wlan_objmgr_psoc *psoc;
struct beacon_interval_arg bss_arg;
uint8_t enable_mcc_mode;
struct wlan_objmgr_vdev *vdev;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc)
return false;
wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
if (!enable_mcc_mode)
return false;
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
WLAN_IF_MGR_ID);
if (!vdev)
return false;
bss_arg.curr_vdev_id = vdev_id;
bss_arg.curr_bss_opmode = wlan_vdev_mlme_get_opmode(vdev);
bss_arg.ch_freq = candidate->chan_freq;
bss_arg.bss_beacon_interval = candidate->beacon_interval;
bss_arg.is_done = false;
wlan_objmgr_vdev_release_ref(vdev, WLAN_IF_MGR_ID);
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
if_mgr_validate_beacon_interval,
&bss_arg, 0,
WLAN_IF_MGR_ID);
if (!bss_arg.is_done)
return true;
if (bss_arg.bss_beacon_interval != candidate->beacon_interval) {
candidate->beacon_interval = bss_arg.bss_beacon_interval;
if (bss_arg.status == QDF_STATUS_SUCCESS)
return true;
}
return false;
}
static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
@@ -213,7 +729,10 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
enum QDF_OPMODE op_mode;
enum policy_mgr_con_mode mode;
struct bssid_search_arg bssid_arg;
uint32_t chan_freq = event_data->validate_bss_info.chan_freq;
struct validate_bss_data *candidate_info =
&event_data->validate_bss_info;
uint32_t chan_freq = candidate_info->chan_freq;
uint32_t conc_freq = 0;
op_mode = wlan_vdev_mlme_get_opmode(vdev);
@@ -229,7 +748,7 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
* Ignore the BSS if any other vdev is already connected to it.
*/
qdf_copy_macaddr(&bssid_arg.peer_addr,
&event_data->validate_bss_info.peer_addr);
&candidate_info->peer_addr);
bssid_arg.vdev_id = WLAN_INVALID_VDEV_ID;
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
if_mgr_get_vdev_id_from_bssid,
@@ -253,7 +772,8 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
if (!policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq,
HW_MODE_20_MHZ)) {
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));
chan_freq,
QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
return QDF_STATUS_E_INVAL;
}
@@ -268,5 +788,33 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_E_INVAL;
}
/* validate beacon interval */
if (policy_mgr_concurrent_open_sessions_running(psoc) &&
!if_mgr_is_beacon_interval_valid(pdev, wlan_vdev_get_id(vdev),
candidate_info)) {
conc_freq = wlan_get_conc_freq();
ifmgr_debug("csr Conc Channel freq: %d",
conc_freq);
if (conc_freq) {
if ((conc_freq == chan_freq) ||
(policy_mgr_is_hw_dbs_capable(psoc) &&
!wlan_reg_is_same_band_freqs(conc_freq,
chan_freq))) {
/*
* make this 0 because we do not want the below
* check to pass as we don't want to connect on
* other channel
*/
ifmgr_debug("Conc chnl freq match: %d",
conc_freq);
conc_freq = 0;
}
}
}
if (conc_freq)
return QDF_STATUS_E_INVAL;
return QDF_STATUS_SUCCESS;
}