qcacld-3.0: Channel hopping for 2_4G and 5G band
qcacld-2.0 to qcacld-3.0 propagation
Allow device switch to a different channel if the current channel is
congested, using the 11h channel switch announcement.
Change-Id: I1766785017e43f17cc800039b383ee5dabcd6ea5
CRs-Fixed: 2082632
diff --git a/Kbuild b/Kbuild
index b890a39..19c71b8 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2029,6 +2029,10 @@
CDEFINES += -DCONFIG_TUFELLO_DUAL_FW_SUPPORT
endif
+ifeq ($(CONFIG_ARCH_MSM8996), y)
+CDEFINES += -DCHANNEL_HOPPING_ALL_BANDS
+endif
+
#Enable Signed firmware support for split binary format
ifeq ($(CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT), 1)
CDEFINES += -DQCA_SIGNED_SPLIT_BINARY_SUPPORT
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 33ccd19..27b1cf3 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -11053,6 +11053,26 @@
/*
* <ini>
+ * g_sap_chanswitch_mode - channel switch mode
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to configure channel switch mode
+ *
+ * Related: none
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SAP_CH_SWITCH_MODE "g_sap_chanswitch_mode"
+#define CFG_SAP_CH_SWITCH_MODE_MIN (0)
+#define CFG_SAP_CH_SWITCH_MODE_MAX (1)
+#define CFG_SAP_CH_SWITCH_MODE_DEFAULT (1)
+
+/*
+ * <ini>
* g_fils_max_chan_guard_time - Set maximum channel guard time(ms)
* @Min: 0
* @Max: 10
@@ -12170,6 +12190,7 @@
bool fw_timeout_crash;
/* beacon count before channel switch */
uint8_t sap_chanswitch_beacon_cnt;
+ uint8_t sap_chanswitch_mode;
uint32_t rx_wakelock_timeout;
uint32_t max_sched_scan_plan_interval;
uint32_t max_sched_scan_plan_iterations;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index abf780d..5f532ca 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4255,6 +4255,12 @@
CFG_SAP_CH_SWITCH_BEACON_CNT_DEFAULT,
CFG_SAP_CH_SWITCH_BEACON_CNT_MIN,
CFG_SAP_CH_SWITCH_BEACON_CNT_MAX),
+ REG_VARIABLE(CFG_SAP_CH_SWITCH_MODE, WLAN_PARAM_Integer,
+ struct hdd_config, sap_chanswitch_mode,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_SAP_CH_SWITCH_MODE_DEFAULT,
+ CFG_SAP_CH_SWITCH_MODE_MIN,
+ CFG_SAP_CH_SWITCH_MODE_MAX),
REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_INT_NAME, WLAN_PARAM_Integer,
struct hdd_config, max_sched_scan_plan_interval,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 2d29dfc..4ec97cc 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -5137,22 +5137,28 @@
for (i = 0; i <= maxSta; i++) {
hdd_station_info_t *sta_info_ptr = &pAdapter->aStaInfo[i];
- if (sta_info_ptr->isUsed) {
- len = scnprintf(pBuf, buf_len,
- "%d %x:%x:%x:%x:%x:%x \t ecsa=%d\n",
- sta_info_ptr->ucSTAId,
- sta_info_ptr->macAddrSTA.bytes[0],
- sta_info_ptr->macAddrSTA.bytes[1],
- sta_info_ptr->macAddrSTA.bytes[2],
- sta_info_ptr->macAddrSTA.bytes[3],
- sta_info_ptr->macAddrSTA.bytes[4],
- sta_info_ptr->macAddrSTA.bytes[5],
- sta_info_ptr->ecsa_capable);
- pBuf += len;
- buf_len -= len;
- }
+ if (!sta_info_ptr->isUsed)
+ continue;
+
+ if (CHAN_HOP_ALL_BANDS_ENABLE &&
+ (i == (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId))
+ continue;
+
if (WE_GET_STA_INFO_SIZE > buf_len)
break;
+
+ len = scnprintf(pBuf, buf_len,
+ "%5d %02x:%02x:%02x:%02x:%02x:%02x ecsa=%d\n",
+ sta_info_ptr->ucSTAId,
+ sta_info_ptr->macAddrSTA.bytes[0],
+ sta_info_ptr->macAddrSTA.bytes[1],
+ sta_info_ptr->macAddrSTA.bytes[2],
+ sta_info_ptr->macAddrSTA.bytes[3],
+ sta_info_ptr->macAddrSTA.bytes[4],
+ sta_info_ptr->macAddrSTA.bytes[5],
+ sta_info_ptr->ecsa_capable);
+ pBuf += len;
+ buf_len -= len;
}
EXIT();
@@ -7528,6 +7534,7 @@
pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
pConfig->sap_chanswitch_beacon_cnt =
iniConfig->sap_chanswitch_beacon_cnt;
+ pConfig->sap_chanswitch_mode = iniConfig->sap_chanswitch_mode;
/* channel is already set in the set_channel Call back */
/* pConfig->channel = pCommitConfig->channel; */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index dbcd36b..e22adfa 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -3986,6 +3986,8 @@
uint8_t bssid[QDF_MAC_ADDR_SIZE];
struct ch_params ch_params;
uint8_t ch_switch_beacon_cnt;
+ uint8_t ch_switch_mode;
+ uint8_t dfs_ch_switch_disable;
} tSirDfsCsaIeRequest, *tpSirDfsCsaIeRequest;
/* Indication from lower layer indicating the completion of first beacon send
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
index 2958b58..fe98ac7 100644
--- a/core/mac/src/pe/include/lim_global.h
+++ b/core/mac/src/pe/include/lim_global.h
@@ -67,6 +67,11 @@
((LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) > LIM_MIN_TIM_WAIT_COUNT ? \
(LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) : LIM_MIN_TIM_WAIT_COUNT)
+#ifdef CHANNEL_HOPPING_ALL_BANDS
+#define CHAN_HOP_ALL_BANDS_ENABLE 1
+#else
+#define CHAN_HOP_ALL_BANDS_ENABLE 0
+#endif
/* enums exported by LIM are as follows */
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 1d7cd4f..b74f7c3 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -1078,8 +1078,9 @@
/* Initialize 11h Enable Flag */
session->lim11hEnable = 0;
- if ((mlm_start_req->bssType != eSIR_IBSS_MODE) &&
- (SIR_BAND_5_GHZ == session->limRFBand)) {
+ if (mlm_start_req->bssType != eSIR_IBSS_MODE &&
+ (CHAN_HOP_ALL_BANDS_ENABLE ||
+ SIR_BAND_5_GHZ == session->limRFBand)) {
if (wlan_cfg_get_int(mac_ctx,
WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
pe_err("Fail to get WNI_CFG_11H_ENABLED");
@@ -5387,7 +5388,8 @@
session_entry->limRFBand =
lim_get_rf_band(session_entry->currentOperChannel);
/* Initialize 11h Enable Flag */
- if (SIR_BAND_5_GHZ == session_entry->limRFBand) {
+ if (CHAN_HOP_ALL_BANDS_ENABLE ||
+ SIR_BAND_5_GHZ == session_entry->limRFBand) {
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val) !=
eSIR_SUCCESS)
pe_err("Fail to get WNI_CFG_11H_ENABLED");
@@ -5813,7 +5815,7 @@
if (LIM_IS_AP_ROLE(session_entry) &&
(mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false))
- switch_mode = 1;
+ switch_mode = session_entry->gLimChannelSwitch.switchMode;
switch_count = session_entry->gLimChannelSwitch.switchCount;
@@ -5838,6 +5840,65 @@
}
/**
+ * lim_send_chan_switch_action_frame()- Send an action frame
+ * containing CSA IE or ECSA IE depending on the connected
+ * sta capability.
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @new_channel: new channel to switch to.
+ * @ch_bandwidth: BW of channel to calculate op_class
+ * @session_entry: pe session
+ *
+ * Return: void
+ */
+static
+void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
+ uint16_t new_channel,
+ uint8_t ch_bandwidth,
+ tpPESession session_entry)
+{
+ uint16_t op_class;
+ uint8_t switch_mode = 0, i;
+ uint8_t switch_count;
+ tpDphHashNode psta;
+ tpDphHashNode dph_node_array_ptr;
+
+ dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray;
+
+ op_class = wlan_reg_dmn_get_opclass_from_channel(
+ mac_ctx->scan.countryCodeCurrent,
+ new_channel, ch_bandwidth);
+
+ if (LIM_IS_AP_ROLE(session_entry) &&
+ (false == mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch))
+ switch_mode = session_entry->gLimChannelSwitch.switchMode;
+
+ switch_count = session_entry->gLimChannelSwitch.switchCount;
+
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ for (i = 0; i < mac_ctx->lim.maxStation; i++) {
+ psta = dph_node_array_ptr + i;
+ if (!(psta && psta->added))
+ continue;
+ if (session_entry->lim_non_ecsa_cap_num == 0)
+ lim_send_extended_chan_switch_action_frame
+ (mac_ctx, psta->staAddr, switch_mode,
+ op_class, new_channel, switch_count,
+ session_entry);
+ else
+ lim_send_channel_switch_mgmt_frame
+ (mac_ctx, psta->staAddr, switch_mode,
+ new_channel, switch_count,
+ session_entry);
+ }
+ } else if (LIM_IS_STA_ROLE(session_entry)) {
+ lim_send_extended_chan_switch_action_frame
+ (mac_ctx, session_entry->bssId, switch_mode, op_class,
+ new_channel, switch_count, session_entry);
+ }
+}
+
+/**
* lim_process_sme_dfs_csa_ie_request() - process sme dfs csa ie req
*
* @mac_ctx: Pointer to Global MAC structure
@@ -5890,7 +5951,8 @@
session_entry->gLimChannelSwitch.sec_ch_offset =
dfs_csa_ie_req->ch_params.sec_ch_offset;
if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)
- session_entry->gLimChannelSwitch.switchMode = 1;
+ session_entry->gLimChannelSwitch.switchMode =
+ dfs_csa_ie_req->ch_switch_mode;
/*
* Validate if SAP is operating HT or VHT mode and set the Channel
@@ -5980,10 +6042,15 @@
session_entry->dfsIncludeChanWrapperIe,
ch_offset);
- /* Send ECSA Action frame after updating the beacon */
- send_extended_chan_switch_action_frame(mac_ctx,
- session_entry->gLimChannelSwitch.primaryChannel,
- ch_offset, session_entry);
+ /* Send ECSA/CSA Action frame after updating the beacon */
+ if (CHAN_HOP_ALL_BANDS_ENABLE)
+ lim_send_chan_switch_action_frame(mac_ctx,
+ session_entry->gLimChannelSwitch.primaryChannel,
+ ch_offset, session_entry);
+ else
+ send_extended_chan_switch_action_frame(mac_ctx,
+ session_entry->gLimChannelSwitch.primaryChannel,
+ ch_offset, session_entry);
session_entry->gLimChannelSwitch.switchCount--;
}
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
index 7f668dd..d7f9872 100644
--- a/core/mac/src/pe/sch/sch_beacon_gen.c
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -277,14 +277,17 @@
if ((session->limSystemRole == eLIM_AP_ROLE) &&
session->dfsIncludeChanSwIe == true) {
- populate_dot_11_f_ext_chann_switch_ann(mac_ctx,
+ if (!CHAN_HOP_ALL_BANDS_ENABLE ||
+ session->lim_non_ecsa_cap_num == 0) {
+ populate_dot_11_f_ext_chann_switch_ann(mac_ctx,
&bcn_2->ext_chan_switch_ann,
session);
- pe_info("ecsa: mode:%d reg:%d chan:%d count:%d",
- bcn_2->ext_chan_switch_ann.switch_mode,
- bcn_2->ext_chan_switch_ann.new_reg_class,
- bcn_2->ext_chan_switch_ann.new_channel,
- bcn_2->ext_chan_switch_ann.switch_count);
+ pe_info("ecsa: mode:%d reg:%d chan:%d count:%d",
+ bcn_2->ext_chan_switch_ann.switch_mode,
+ bcn_2->ext_chan_switch_ann.new_reg_class,
+ bcn_2->ext_chan_switch_ann.new_channel,
+ bcn_2->ext_chan_switch_ann.switch_count);
+ }
}
populate_dot11_supp_operating_classes(mac_ctx,
@@ -307,13 +310,15 @@
* and SAP has instructed to announce channel switch IEs
* in beacon and probe responses
*/
- populate_dot11f_chan_switch_ann(mac_ctx,
+ if (!CHAN_HOP_ALL_BANDS_ENABLE ||
+ session->lim_non_ecsa_cap_num > 0) {
+ populate_dot11f_chan_switch_ann(mac_ctx,
&bcn_2->ChanSwitchAnn, session);
- pe_debug("csa: mode:%d chan:%d count:%d",
- bcn_2->ChanSwitchAnn.switchMode,
- bcn_2->ChanSwitchAnn.newChannel,
- bcn_2->ChanSwitchAnn.switchCount);
-
+ pe_debug("csa: mode:%d chan:%d count:%d",
+ bcn_2->ChanSwitchAnn.switchMode,
+ bcn_2->ChanSwitchAnn.newChannel,
+ bcn_2->ChanSwitchAnn.switchCount);
+ }
/*
* TODO: depending the CB mode, extended channel switch
* announcement need to be called
diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h
index 9e93f18..a4cec67 100644
--- a/core/sap/inc/sap_api.h
+++ b/core/sap/inc/sap_api.h
@@ -630,6 +630,7 @@
bool dfs_cac_offload;
/* beacon count before channel switch */
uint8_t sap_chanswitch_beacon_cnt;
+ uint8_t sap_chanswitch_mode;
} tsap_Config_t;
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
@@ -738,6 +739,7 @@
uint16_t tx_leakage_threshold;
/* beacon count before channel switch */
uint8_t sap_ch_switch_beacon_cnt;
+ uint8_t sap_ch_switch_mode;
} tSapDfsInfo;
typedef struct tagSapCtxList {
diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c
index 84baa76..bd15e3a 100644
--- a/core/sap/src/sap_module.c
+++ b/core/sap/src/sap_module.c
@@ -949,6 +949,8 @@
pConfig->disableDFSChSwitch;
pmac->sap.SapDfsInfo.sap_ch_switch_beacon_cnt =
pConfig->sap_chanswitch_beacon_cnt;
+ pmac->sap.SapDfsInfo.sap_ch_switch_mode =
+ pConfig->sap_chanswitch_mode;
pmac->sap.sapCtxList[pSapCtx->sessionId].pSapContext = pSapCtx;
pmac->sap.sapCtxList[pSapCtx->sessionId].sapPersona =
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 8db2b64..ab78f4f 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -19191,6 +19191,9 @@
msg->csaIeRequired = csa_ie_reqd;
msg->ch_switch_beacon_cnt =
mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt;
+ msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode;
+ msg->dfs_ch_switch_disable =
+ mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch;
qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params));