qcacld-3.0: Enable obss detection offload

Enable firmware based obss detection.

Change-Id: I218337092e553bca0737864214c16b0dacbfa3be
CRs-Fixed: 2171944
This commit is contained in:
Arif Hussain
2018-01-05 19:56:31 -08:00
committed by snandini
parent ee10f9089e
commit 1513cb2384
13 changed files with 555 additions and 17 deletions

View File

@@ -828,7 +828,7 @@ typedef struct sAniSirLim {
uint8_t scan_disabled;
uint8_t beacon_probe_rsp_cnt_per_scan;
wlan_scan_requester req_id;
uint8_t obss_detection_offloaded;
bool global_obss_offload_enabled;
} tAniSirLim, *tpAniSirLim;
struct mgmt_frm_reg_info {

View File

@@ -115,6 +115,7 @@ struct bss_color_info {
* @obss_ht_legacy_detect_mode: detection mode for ht ap with legacy mode.
* @obss_ht_mixed_detect_mode: detection mode for ht ap with mixed mode.
* @obss_ht_20mhz_detect_mode: detection mode for ht ap with 20mhz mode.
* @obss_current_detection_masks: current detection masks.
*/
struct obss_detection_cfg {
uint8_t obss_11b_ap_detect_mode;
@@ -124,6 +125,7 @@ struct obss_detection_cfg {
uint8_t obss_ht_legacy_detect_mode;
uint8_t obss_ht_mixed_detect_mode;
uint8_t obss_ht_20mhz_detect_mode;
uint32_t obss_current_detection_masks;
};
typedef struct sPESession /* Added to Support BT-AMP */
@@ -547,7 +549,8 @@ typedef struct sPESession /* Added to Support BT-AMP */
/* previous auth frame's sequence number */
uint16_t prev_auth_seq_num;
struct obss_detection_cfg obss_offload_cfg;
bool enable_obss_detection_offload;
bool is_session_obss_offload_enabled;
bool is_obss_reset_timer_initialized;
} tPESession, *tpPESession;
/*-------------------------------------------------------------------------

View File

@@ -470,7 +470,7 @@ static tSirRetStatus __lim_init_config(tpAniSirGlobal pMac)
if (eSIR_SUCCESS != wlan_cfg_get_int(pMac,
WNI_CFG_OBSS_DETECTION_OFFLOAD,
(uint32_t *)&pMac->lim.
obss_detection_offloaded)) {
global_obss_offload_enabled)) {
pe_err("cfg get obss_detection_offloaded failed");
return eSIR_FAILURE;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -3087,6 +3087,9 @@ lim_delete_dph_hash_entry(tpAniSirGlobal mac_ctx, tSirMacAddr sta_addr,
lim_send_beacon_params(mac_ctx, &beacon_params,
session_entry);
}
lim_obss_send_detection_cfg(mac_ctx, session_entry, false);
#ifdef WLAN_FEATURE_11W
if (sta_ds->rmfEnabled) {
pe_debug("delete pmf timer sta-idx:%d assoc-id:%d",

View File

@@ -1901,6 +1901,7 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
msg->bodyptr = NULL;
break;
case WMA_OBSS_DETECTION_INFO:
lim_process_obss_detection_ind(mac_ctx, msg->bodyptr);
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
break;

View File

@@ -255,6 +255,7 @@ void lim_process_mlm_start_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
psessionEntry->ssId.ssId,
psessionEntry->currentOperChannel);
lim_send_beacon_ind(pMac, psessionEntry);
lim_enable_obss_detection_config (pMac, psessionEntry);
}
}
}

View File

@@ -5072,6 +5072,7 @@ static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg
psessionEntry->ssId.ssId,
psessionEntry->currentOperChannel);
lim_send_beacon_ind(pMac, psessionEntry);
lim_enable_obss_detection_config(pMac, psessionEntry);
} else {
pe_err("Invalid Beacon Start Indication");
return;

View File

@@ -1323,6 +1323,8 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
}
lim_obss_send_detection_cfg(mac_ctx, pe_session, false);
if (assoc_req != NULL) {
addn_ie_len = pe_session->addIeParams.assocRespDataLen;

View File

@@ -2492,6 +2492,8 @@ lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
pe_debug("Failed to Transmit Beacons on channel: %d after AP channel change response",
psessionEntry->bcnLen);
}
lim_obss_send_detection_cfg(pMac, psessionEntry, true);
}
return;
}

View File

@@ -515,18 +515,20 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
if (eSIR_INFRA_AP_MODE == bssType) {
session_ptr->old_protection_state = 0;
session_ptr->is_session_obss_offload_enabled = false;
session_ptr->is_obss_reset_timer_initialized = false;
session_ptr->mac_ctx = (void *)pMac;
status = qdf_mc_timer_init(
&session_ptr->protection_fields_reset_timer,
QDF_TIMER_TYPE_SW, pe_reset_protection_callback,
(void *)&pMac->lim.gpSession[i]);
if (status == QDF_STATUS_SUCCESS) {
status = qdf_mc_timer_start(
&session_ptr->protection_fields_reset_timer,
SCH_PROTECTION_RESET_TIME);
}
if (status != QDF_STATUS_SUCCESS)
pe_err("cannot create or start protectionFieldsResetTimer");
status = qdf_mc_timer_init(&session_ptr->
protection_fields_reset_timer,
QDF_TIMER_TYPE_SW,
pe_reset_protection_callback,
(void *)&pMac->lim.gpSession[i]);
if (QDF_IS_STATUS_ERROR(status))
pe_err("cannot create protection fields reset timer");
else
session_ptr->is_obss_reset_timer_initialized = true;
}
pe_init_fils_info(session_ptr);
pe_init_pmf_comeback_timer(pMac, session_ptr, *sessionId);

View File

@@ -1041,6 +1041,10 @@ void lim_handle_update_olbc_cache(tpAniSirGlobal mac_ctx)
return;
}
if (psessionEntry->is_session_obss_offload_enabled) {
pe_debug("protection offloaded");
return;
}
qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
beaconParams.bssIdx = psessionEntry->bssIdx;

View File

@@ -71,6 +71,43 @@ typedef enum {
#define MGMT_RX_PACKETS_THRESHOLD 200
/* 11B AP detection bit position */
#define OBSS_DETECTION_11B_AP_BIT_MASK 0x0001
/* 11B STA detection bit position */
#define OBSS_DETECTION_11B_STA_BIT_MASK 0x0002
/* 11G AP detection bit position */
#define OBSS_DETECTION_11G_AP_BIT_MASK 0x0004
/* 11A AP detection bit position */
#define OBSS_DETECTION_11A_BIT_MASK 0x0008
/* HT legacy detection bit position */
#define OBSS_DETECTION_HT_LEGACY_BIT_MASK 0x0010
/* HT mixed detection bit position */
#define OBSS_DETECTION_HT_MIXED_BIT_MASK 0x0020
/* HT 20mhz detection bit position */
#define OBSS_DETECTION_HT_20MHZ_BIT_MASK 0x0040
/**
* OBSS detection period in ms, used by firmware to decide
* absent detection and also gap between same detection ind.
*/
#define OBSS_DETECTION_PERIOD_MS 4000
/* To check if 11B AP detection bit set */
#define OBSS_DETECTION_IS_11B_AP(_m) ((_m) & OBSS_DETECTION_11B_AP_BIT_MASK)
/* To check if 11B STA detection bit set */
#define OBSS_DETECTION_IS_11B_STA(_m) ((_m) & OBSS_DETECTION_11B_STA_BIT_MASK)
/* To check if 11G AP detection bit set */
#define OBSS_DETECTION_IS_11G_AP(_m) ((_m) & OBSS_DETECTION_11G_AP_BIT_MASK)
/* To check if 11A AP detection bit set */
#define OBSS_DETECTION_IS_11A(_m) ((_m) & OBSS_DETECTION_11A_BIT_MASK)
/* To check if HT legacy detection bit set */
#define OBSS_DETECTION_IS_HT_LEGACY(_m) \
((_m) & OBSS_DETECTION_HT_LEGACY_BIT_MASK)
/* To check if HT mixed detection bit set */
#define OBSS_DETECTION_IS_HT_MIXED(_m) ((_m) & OBSS_DETECTION_HT_MIXED_BIT_MASK)
/* To check if HT 20mhz detection bit set */
#define OBSS_DETECTION_IS_HT_20MHZ(_m) ((_m) & OBSS_DETECTION_HT_20MHZ_BIT_MASK)
#ifdef WLAN_FEATURE_11W
typedef union uPmfSaQueryTimerId {
struct {
@@ -1235,4 +1272,60 @@ void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
uint8_t ch_bandwidth,
tpPESession session_entry);
/**
* lim_process_obss_detection_ind() - Process obss detection indication
* @mac_ctx: Pointer to Global MAC structure.
* @obss_detection: obss detection info.
*
* Process obss detection indication and apply necessary protection for
* the given AP session.
*
* Return: QDF_STATUS
*/
QDF_STATUS lim_process_obss_detection_ind(tpAniSirGlobal mac_ctx,
struct wmi_obss_detect_info
*obss_detection);
/**
* lim_obss_send_detection_cfg() - Send obss detection configuration to firmware
* @mac_ctx: Pointer to Global MAC structure
* @session: Pointer to session
* @force: Force to send new configuration even if new cfg same as old
*
* Generate new cfg based on current protection status and send new cfg to
* firmware.
*
* Return: QDF_STATUS
*/
QDF_STATUS lim_obss_send_detection_cfg(tpAniSirGlobal mac_ctx,
tpPESession session,
bool force);
/**
* lim_obss_generate_detection_config() - get new obss offload detection cfg
* @mac_ctx: Pointer to Global MAC structure
* @session: Pointer to session
* @cfg: Obss detection cfg buffer pointer
*
* Generate new cfg based on current protection status.
*
* Return: QDF_STATUS
*/
QDF_STATUS lim_obss_generate_detection_config(tpAniSirGlobal mac_ctx,
tpPESession session,
struct obss_detection_cfg *cfg);
/**
* lim_enable_obss_detection_config() - Enable obss detection
* @mac_ctx: Pointer to Global MAC structure
* @session: Pointer to session
*
* This function will enable legacy obss detection (by starting timer)
* or also offload based detection based on support.
*
* Return: None
*/
void lim_enable_obss_detection_config(tpAniSirGlobal mac_ctx,
tpPESession session);
#endif /* __LIM_UTILS_H */

View File

@@ -1057,8 +1057,9 @@ sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
sch_check_bss_color_ie(mac_ctx, ap_session, &bcn, &bcn_prm);
if (ap_session->gLimProtectionControl !=
WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
if ((ap_session->gLimProtectionControl !=
WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) &&
!ap_session->is_session_obss_offload_enabled)
ap_beacon_process(mac_ctx, rx_pkt_info,
&bcn, &bcn_prm, ap_session);
@@ -1187,3 +1188,428 @@ sch_beacon_edca_process(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca,
}
return eSIR_SUCCESS;
}
void lim_enable_obss_detection_config(tpAniSirGlobal mac_ctx,
tpPESession session)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!session) {
pe_err("Invalid session, protection not enabled");
return;
}
if (session->gLimProtectionControl ==
WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) {
pe_err("protectiond disabled, force policy, session %d",
session->smeSessionId);
return;
}
if (mac_ctx->lim.global_obss_offload_enabled) {
status = lim_obss_send_detection_cfg(mac_ctx, session, true);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("vdev %d: offload enable failed, trying legacy",
session->smeSessionId);
session->is_session_obss_offload_enabled = false;
} else {
pe_debug("vdev %d: offload detection enabled",
session->smeSessionId);
session->is_session_obss_offload_enabled = true;
lim_obss_send_detection_cfg(mac_ctx, session, true);
}
}
if (!mac_ctx->lim.global_obss_offload_enabled ||
QDF_IS_STATUS_ERROR(status)) {
status = qdf_mc_timer_start(&session->
protection_fields_reset_timer,
SCH_PROTECTION_RESET_TIME);
if (QDF_IS_STATUS_ERROR(status))
pe_err("vdev %d: start timer failed",
session->smeSessionId);
else
pe_debug("vdev %d: legacy detection enabled",
session->smeSessionId);
}
}
QDF_STATUS lim_obss_generate_detection_config(tpAniSirGlobal mac_ctx,
tpPESession session,
struct obss_detection_cfg *cfg)
{
uint32_t phy_mode;
enum band_info rf_band = BAND_UNKNOWN;
uint32_t detect_masks;
if (!mac_ctx || !session || !cfg) {
pe_err("Invalid params mac_ctx %pK, session %pK, cfg %pK",
mac_ctx, session, cfg);
return QDF_STATUS_E_INVAL;
}
lim_get_phy_mode(mac_ctx, &phy_mode, session);
rf_band = session->limRFBand;
qdf_mem_zero(cfg, sizeof(*cfg));
detect_masks = session->obss_offload_cfg.obss_current_detection_masks;
pe_debug("band:%d, phy_mode:%d, ht_cap:%d, ht_oper_mode:%d",
rf_band, phy_mode, session->htCapability,
mac_ctx->lim.gHTOperMode);
pe_debug("assoc_sta: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
session->gLim11bParams.protectionEnabled,
session->gLim11gParams.protectionEnabled,
session->gLim11aParams.protectionEnabled,
session->gLimHt20Params.protectionEnabled);
pe_debug("obss: 11b:%d, 11g:%d, 11a:%d, ht20:%d, masks:0x%0x",
session->gLimOlbcParams.protectionEnabled,
session->gLimOverlap11gParams.protectionEnabled,
session->gLimOverlap11aParams.protectionEnabled,
session->gLimOverlapHt20Params.protectionEnabled,
detect_masks);
if ((rf_band == BAND_2G)) {
if ((phy_mode == WNI_CFG_PHY_MODE_11G ||
session->htCapability) &&
!session->gLim11bParams.protectionEnabled) {
if (!session->gLimOlbcParams.protectionEnabled &&
!session->gLimOverlap11gParams.protectionEnabled) {
cfg->obss_11b_ap_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
cfg->obss_11b_sta_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
} else {
if (OBSS_DETECTION_IS_11B_AP(detect_masks))
cfg->obss_11b_ap_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
if (OBSS_DETECTION_IS_11B_STA(detect_masks))
cfg->obss_11b_sta_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
}
} else if (session->gLim11bParams.protectionEnabled) {
session->gLimOlbcParams.protectionEnabled = false;
}
if (session->htCapability &&
session->cfgProtection.overlapFromllg &&
!session->gLim11gParams.protectionEnabled) {
if (!session->gLimOverlap11gParams.protectionEnabled) {
cfg->obss_11g_ap_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
cfg->obss_ht_legacy_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
cfg->obss_ht_mixed_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
} else {
if (OBSS_DETECTION_IS_11G_AP(detect_masks))
cfg->obss_11g_ap_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks))
cfg->obss_ht_legacy_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
if (OBSS_DETECTION_IS_HT_MIXED(detect_masks))
cfg->obss_ht_mixed_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
}
} else if (session->gLim11gParams.protectionEnabled) {
session->gLimOverlap11gParams.protectionEnabled = false;
}
/* INI related settings */
if (mac_ctx->roam.configParam.ignore_peer_erp_info)
cfg->obss_11b_sta_detect_mode =
OBSS_OFFLOAD_DETECTION_DISABLED;
if (mac_ctx->roam.configParam.ignore_peer_ht_opmode)
cfg->obss_ht_legacy_detect_mode =
OBSS_OFFLOAD_DETECTION_DISABLED;
}
if ((rf_band == BAND_5G) && session->htCapability) {
if (!session->gLim11aParams.protectionEnabled) {
if (!session->gLimOverlap11aParams.protectionEnabled)
cfg->obss_11a_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
else if (OBSS_DETECTION_IS_11A(detect_masks))
cfg->obss_11a_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
} else {
session->gLimOverlap11aParams.protectionEnabled = false;
}
}
if (((rf_band == BAND_2G) || (rf_band == BAND_5G)) &&
session->htCapability) {
if (!session->gLimHt20Params.protectionEnabled) {
if (!session->gLimOverlapHt20Params.protectionEnabled) {
cfg->obss_ht_20mhz_detect_mode =
OBSS_OFFLOAD_DETECTION_PRESENT;
} else if (OBSS_DETECTION_IS_HT_20MHZ(detect_masks)) {
cfg->obss_ht_20mhz_detect_mode =
OBSS_OFFLOAD_DETECTION_ABSENT;
}
} else {
session->gLimOverlapHt20Params.protectionEnabled =
false;
}
}
pe_debug("b_ap:%d, b_s:%d, g:%d, a:%d, ht_le:%d, ht_m:%d, ht_20:%d",
cfg->obss_11b_ap_detect_mode,
cfg->obss_11b_sta_detect_mode,
cfg->obss_11g_ap_detect_mode,
cfg->obss_11a_detect_mode,
cfg->obss_ht_legacy_detect_mode,
cfg->obss_ht_mixed_detect_mode,
cfg->obss_ht_20mhz_detect_mode);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS lim_obss_send_detection_cfg(tpAniSirGlobal mac_ctx,
tpPESession session, bool force)
{
QDF_STATUS status;
struct obss_detection_cfg obss_cfg;
struct wmi_obss_detection_cfg_param *req_param;
if (!session) {
pe_err("Invalid session");
return QDF_STATUS_E_INVAL;
}
if (!session->is_session_obss_offload_enabled) {
pe_debug("obss offload protectiond disabled, session %d",
session->smeSessionId);
/* Send success */
return QDF_STATUS_SUCCESS;
}
if (session->gLimProtectionControl ==
WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) {
pe_debug("protectiond disabled, force from policy, session %d",
session->smeSessionId);
/* Send success */
return QDF_STATUS_SUCCESS;
}
status = lim_obss_generate_detection_config(mac_ctx,
session,
&obss_cfg);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("Failed to generate obss detection cfg, session %d",
session->smeSessionId);
return status;
}
if (qdf_mem_cmp(&session->obss_offload_cfg, &obss_cfg, sizeof(obss_cfg))
|| force) {
struct scheduler_msg msg = {0};
req_param = qdf_mem_malloc(sizeof(*req_param));
if (!req_param) {
pe_err("Failed to allocate memory");
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(&session->obss_offload_cfg, &obss_cfg,
sizeof(obss_cfg));
req_param->vdev_id = session->smeSessionId;
req_param->obss_detect_period_ms = OBSS_DETECTION_PERIOD_MS;
req_param->obss_11b_ap_detect_mode =
obss_cfg.obss_11b_ap_detect_mode;
req_param->obss_11b_sta_detect_mode =
obss_cfg.obss_11b_sta_detect_mode;
req_param->obss_11g_ap_detect_mode =
obss_cfg.obss_11g_ap_detect_mode;
req_param->obss_11a_detect_mode =
obss_cfg.obss_11a_detect_mode;
req_param->obss_ht_legacy_detect_mode =
obss_cfg.obss_ht_legacy_detect_mode;
req_param->obss_ht_20mhz_detect_mode =
obss_cfg.obss_ht_20mhz_detect_mode;
req_param->obss_ht_mixed_detect_mode =
obss_cfg.obss_ht_mixed_detect_mode;
msg.type = WMA_OBSS_DETECTION_REQ;
msg.bodyptr = req_param;
msg.reserved = 0;
status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("Failed to post WMA_OBSS_DETECTION_REQ to WMA");
qdf_mem_free(req_param);
return status;
}
} else {
pe_debug("Skiping WMA_OBSS_DETECTION_REQ, force = %d", force);
}
return status;
}
QDF_STATUS lim_process_obss_detection_ind(tpAniSirGlobal mac_ctx,
struct wmi_obss_detect_info
*obss_detection)
{
QDF_STATUS status;
uint32_t detect_masks;
uint32_t reason;
struct obss_detection_cfg *obss_cfg;
bool enable;
tpPESession session;
tUpdateBeaconParams bcn_prm;
enum band_info rf_band = BAND_UNKNOWN;
pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " MAC_ADDRESS_STR,
obss_detection->vdev_id, obss_detection->reason,
obss_detection->matched_detection_masks,
MAC_ADDR_ARRAY(obss_detection->matched_bssid_addr));
session = pe_find_session_by_sme_session_id(mac_ctx,
obss_detection->vdev_id);
if (!session) {
pe_err("Failed to get session for id %d",
obss_detection->vdev_id);
return QDF_STATUS_E_INVAL;
}
if (!LIM_IS_AP_ROLE(session)) {
pe_err("session %d is not AP", obss_detection->vdev_id);
return QDF_STATUS_E_INVAL;
}
if (!session->is_session_obss_offload_enabled) {
pe_err("Offload already disabled for session %d",
obss_detection->vdev_id);
return QDF_STATUS_SUCCESS;
}
reason = obss_detection->reason;
detect_masks = obss_detection->matched_detection_masks;
if (reason == OBSS_OFFLOAD_DETECTION_PRESENT) {
enable = true;
} else if (reason == OBSS_OFFLOAD_DETECTION_ABSENT) {
enable = false;
} else if (reason == OBSS_OFFLOAD_DETECTION_DISABLED) {
/*
* Most common reason for this event-type from firmware
* is insufficient memory.
* Disable offload OBSS detection and enable legacy-way
* of detecting OBSS by parsing beacons.
**/
session->is_session_obss_offload_enabled = false;
pe_err("FW indicated obss offload disabled");
pe_err("Enabling host based detection, session %d",
obss_detection->vdev_id);
status = qdf_mc_timer_start(&session->
protection_fields_reset_timer,
SCH_PROTECTION_RESET_TIME);
if (QDF_IS_STATUS_ERROR(status))
pe_err("cannot start protection reset timer");
return QDF_STATUS_SUCCESS;
} else {
pe_err("Invalid reason %d, session %d",
obss_detection->reason,
obss_detection->vdev_id);
return QDF_STATUS_E_INVAL;
}
rf_band = session->limRFBand;
qdf_mem_zero(&bcn_prm, sizeof(bcn_prm));
obss_cfg = &session->obss_offload_cfg;
if (OBSS_DETECTION_IS_11B_AP(detect_masks)) {
if (reason != obss_cfg->obss_11b_ap_detect_mode ||
rf_band != BAND_2G)
goto wrong_detection;
lim_enable11g_protection(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_11B_STA(detect_masks)) {
if (reason != obss_cfg->obss_11b_sta_detect_mode ||
rf_band != BAND_2G)
goto wrong_detection;
lim_enable11g_protection(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_11G_AP(detect_masks)) {
if (reason != obss_cfg->obss_11g_ap_detect_mode ||
rf_band != BAND_2G)
goto wrong_detection;
lim_enable_ht_protection_from11g(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_11A(detect_masks)) {
if (reason != obss_cfg->obss_11a_detect_mode ||
rf_band != BAND_5G)
goto wrong_detection;
lim_update_11a_protection(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks)) {
/* for 5GHz, we have only 11a detection, which covers legacy */
if (reason != obss_cfg->obss_ht_legacy_detect_mode ||
rf_band != BAND_2G)
goto wrong_detection;
lim_enable_ht_protection_from11g(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_HT_MIXED(detect_masks)) {
/* for 5GHz, we have only 11a detection, which covers ht mix */
if (reason != obss_cfg->obss_ht_mixed_detect_mode ||
rf_band != BAND_2G)
goto wrong_detection;
lim_enable_ht_protection_from11g(mac_ctx, enable, true,
&bcn_prm, session);
}
if (OBSS_DETECTION_IS_HT_20MHZ(detect_masks)) {
if (reason != obss_cfg->obss_ht_20mhz_detect_mode)
goto wrong_detection;
lim_enable_ht20_protection(mac_ctx, enable, true,
&bcn_prm, session);
}
/* save current detection */
session->obss_offload_cfg.obss_current_detection_masks = detect_masks;
if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) &&
bcn_prm.paramChangeBitmap) {
/* Update the bcn and apply the new settings to HAL */
sch_set_fixed_beacon_fields(mac_ctx, session);
pe_debug("Beacon for PE session: %d got changed: 0x%x",
session->smeSessionId, bcn_prm.paramChangeBitmap);
if (!IS_SIR_STATUS_SUCCESS(lim_send_beacon_params(
mac_ctx, &bcn_prm, session))) {
pe_err("Failed to send beacon param, session %d",
obss_detection->vdev_id);
return QDF_STATUS_E_FAULT;
}
}
status = lim_obss_send_detection_cfg(mac_ctx, session, true);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("Failed to send obss detection cfg, session %d",
obss_detection->vdev_id);
return status;
}
return QDF_STATUS_SUCCESS;
wrong_detection:
/*
* We may get this wrong detection before FW can update latest cfg,
* So keeping log level debug
**/
pe_debug("Wrong detection, session %d", obss_detection->vdev_id);
return QDF_STATUS_E_INVAL;
}