qcacld-3.0: Enable obss detection offload
Enable firmware based obss detection. Change-Id: I218337092e553bca0737864214c16b0dacbfa3be CRs-Fixed: 2171944
This commit is contained in:
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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",
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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,
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user