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
This commit is contained in:
gaolez 2017-03-21 19:23:58 +08:00 • committed by Gerrit - the friendly Code Review server
commit 76d2a16f03
11 changed files with 159 additions and 35 deletions

4
Kbuild
View file

@ -2029,6 +2029,10 @@ ifeq ($(CONFIG_ARCH_MDM9607), y)
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

View file

@ -11051,6 +11051,26 @@ enum l1ss_sleep_allowed {
#define CFG_SAP_CH_SWITCH_BEACON_CNT_MAX (5)
#define CFG_SAP_CH_SWITCH_BEACON_CNT_DEFAULT (5)
/*
* <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)
@ -12170,6 +12190,7 @@ struct hdd_config {
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;

View file

@ -4255,6 +4255,12 @@ struct reg_table_entry g_registry_table[] = {
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,

View file

@ -5137,22 +5137,28 @@ QDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
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 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
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; */

View file

@ -3986,6 +3986,8 @@ typedef struct sSirDfsCsaIeRequest {
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

View file

@ -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 */

View file

@ -1078,8 +1078,9 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
/* 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 @@ static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx,
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 @@ static void send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
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;
@ -5837,6 +5839,65 @@ static void send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
}
/**
* 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
*
@ -5890,7 +5951,8 @@ static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx,
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 @@ skip_vht:
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--;
}

View file

@ -277,14 +277,17 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
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 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
* 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

View file

@ -630,6 +630,7 @@ typedef struct sap_Config {
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 @@ typedef struct sSapDfsInfo {
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 {

View file

@ -949,6 +949,8 @@ QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */
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 =

View file

@ -19191,6 +19191,9 @@ QDF_STATUS csr_roam_send_chan_sw_ie_request(tpAniSirGlobal mac_ctx,
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));