diff --git a/Kbuild b/Kbuild index b890a394ee60..19c71b8b0bda 100644 --- a/Kbuild +++ b/Kbuild @@ -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 diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 33ccd1943f2c..27b1cf366f2f 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -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) +/* + * + * 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 + * + * + */ +#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) + /* * * 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; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index abf780d5e988..5f532ca2724f 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -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, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 2d29dfcc2167..4ec97ccb0295 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -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; */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index dbcd36b6a73f..e22adfafc94a 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -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 diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h index 2958b583f1a5..fe98ac7ce1a6 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 1d7cd4f880b0..b74f7c3ef9d6 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 @@ __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--; } diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c index 7f668ddce7a2..d7f9872d6259 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 @@ 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 diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 9e93f1854036..a4cec6725557 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -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 { diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 84baa76ddcbe..bd15e3ac9597 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -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 = diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 8db2b649a151..ab78f4f33f4f 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -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));