From 61d502d9661536b64dc0300c4bf183c34481957c Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Wed, 27 Nov 2019 20:01:59 +0800 Subject: [PATCH] qcacld-3.0: SAP CSA from 5G to 2G for modem N79 For SAP/P2P GO on 5G, when receive cmd to disable 5G band when modem n79 band used, will move to 2G band via CSA. 1. If no active connection on 2G, select ch by safe list, or channel 6. 2. If there is STA on 2G, force scc with it. 3. If there is SAP/GO on 2G, force scc with it. 4. Handle one race condition that if candidate is already selected & FW has gone ahead with roaming or about to go ahead when set_band comes, it will be complicated for FW to stop the current roaming. Instead, host will check roam sync to make sure the new AP is on 2G, or disconnect the AP. 5. If 2 SAP on 5G, move both to 2G and keep scc. When Set band to enable 5G band again, restored all 5G SAP/Go.. Change-Id: I9b2b1ead3b4502022aeefc08359037457bb051f9 CRs-Fixed: 2580204 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 4 +- core/hdd/src/wlan_hdd_regulatory.c | 18 +++ core/sap/inc/sap_api.h | 15 +++ core/sap/src/sap_internal.h | 3 +- core/sap/src/sap_module.c | 118 ++++++++++++++++++ core/sme/src/csr/csr_api_roam.c | 15 +++ 6 files changed, 171 insertions(+), 2 deletions(-) diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 3392006141bb..abf54efc8467 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -76,6 +76,7 @@ typedef const enum policy_mgr_conc_next_action * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel. * @CSA_REASON_LTE_COEX: LTE coex. * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency. + * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled * */ enum sap_csa_reason_code { @@ -87,7 +88,8 @@ enum sap_csa_reason_code { CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL, CSA_REASON_UNSAFE_CHANNEL, CSA_REASON_LTE_COEX, - CSA_REASON_CONCURRENT_NAN_EVENT + CSA_REASON_CONCURRENT_NAN_EVENT, + CSA_REASON_BAND_RESTRICTED }; /** diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c index 632e3392df6d..7150cf117429 100644 --- a/core/hdd/src/wlan_hdd_regulatory.c +++ b/core/hdd/src/wlan_hdd_regulatory.c @@ -1425,6 +1425,9 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc, struct hdd_context *hdd_ctx; enum country_src cc_src; uint8_t alpha2[REG_ALPHA2_LEN + 1]; + struct hdd_adapter *adapter = NULL; + struct hdd_ap_ctx *ap_ctx; + enum band_info current_band; pdev_priv = wlan_pdev_get_ospriv(pdev); wiphy = pdev_priv->wiphy; @@ -1456,6 +1459,21 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc, else sme_generic_change_country_code(hdd_ctx->mac_handle, hdd_ctx->reg.alpha2); + + if (ucfg_reg_get_curr_band(hdd_ctx->pdev, ¤t_band) != + QDF_STATUS_SUCCESS) { + hdd_err("Failed to get current band config"); + return; + } + hdd_for_each_adapter(hdd_ctx, adapter) { + ap_ctx = &adapter->session.ap; + if ((adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE)) { + wlansap_set_band_csa(ap_ctx->sap_context, + &ap_ctx->sap_config, + current_band); + } + } } int hdd_update_regulatory_config(struct hdd_context *hdd_ctx) diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index be81f5543027..1605502efb66 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1459,6 +1459,21 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, */ uint32_t wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx); + +/** + * wlansap_set_band_csa() - sap channel switch for band change + * @sap_ctx: sap context pointer + * @sap_config: sap config pointer + * + * Sap/p2p go channel switch from 5G to 2G by CSA when 5G band disabled to + * avoid conflict with modem N79. + * Sap/p2p go channel restore to 5G when 5G band enabled. + * + * Return - none + */ +void wlansap_set_band_csa(struct sap_context *sap_ctx, + struct sap_config *sap_config, + enum band_info band); #ifdef __cplusplus } #endif diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h index 3ccfc4f419a4..1b698984b764 100644 --- a/core/sap/src/sap_internal.h +++ b/core/sap/src/sap_internal.h @@ -171,7 +171,8 @@ struct sap_context { uint8_t num_of_channel; uint16_t ch_width_orig; struct ch_params ch_params; - + uint32_t chan_freq_before_switch_band; + enum phy_ch_width chan_width_before_switch_band; uint32_t auto_channel_select_weight; bool enableOverLapCh; struct sap_acs_cfg *acs_cfg; diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 2798bbd26d20..266568b7337a 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1358,6 +1358,8 @@ static char *sap_get_csa_reason_str(enum sap_csa_reason_code reason) return "LTE_COEX"; case CSA_REASON_CONCURRENT_NAN_EVENT: return "CONCURRENT_NAN_EVENT"; + case CSA_REASON_BAND_RESTRICTED: + return "BAND_RESTRICTED"; default: return "UNKNOWN"; } @@ -3090,3 +3092,119 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) */ return wlansap_get_safe_channel(sap_ctx); } + +static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx) +{ + uint32_t i; + uint32_t freq; + enum channel_state state; + struct regulatory_channel *cur_chan_list; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; + uint32_t *acs_freq_list; + uint8_t acs_list_count; + + pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev; + psoc = pdev->pdev_objmgr.wlan_psoc; + + cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * + sizeof(struct regulatory_channel)); + if (!cur_chan_list) + return TWOG_CHAN_6_IN_MHZ; + + if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) != + QDF_STATUS_SUCCESS) { + freq = TWOG_CHAN_6_IN_MHZ; + goto err; + } + + acs_freq_list = sap_ctx->acs_cfg->master_freq_list; + acs_list_count = sap_ctx->acs_cfg->master_ch_list_count; + for (i = 0; i < NUM_CHANNELS; i++) { + freq = cur_chan_list[i].center_freq; + state = wlan_reg_get_channel_state_for_freq(pdev, freq); + if (state != CHANNEL_STATE_DISABLE && + state != CHANNEL_STATE_INVALID && + wlan_reg_is_24ghz_ch_freq(freq) && + policy_mgr_is_safe_channel(psoc, freq) && + wlansap_is_channel_present_in_acs_list(freq, + acs_freq_list, + acs_list_count)) { + sap_debug("find a 2g channel: %d", freq); + goto err; + } + } + + freq = TWOG_CHAN_6_IN_MHZ; +err: + qdf_mem_free(cur_chan_list); + return freq; +} + +void wlansap_set_band_csa(struct sap_context *sap_ctx, + struct sap_config *sap_config, + enum band_info band) +{ + uint8_t restart_chan; + uint32_t restart_freq; + enum phy_ch_width restart_ch_width; + uint8_t intf_ch; + uint32_t phy_mode; + struct mac_context *mac; + uint8_t cc_mode; + uint8_t vdev_id; + enum reg_wifi_band sap_band; + + sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq); + sap_debug("SAP/Go current band: %d, pdev band capability: %d", + sap_band, band); + if (sap_band == REG_BAND_5G && band == BAND_2G) { + if (sap_ctx->chan_freq_before_switch_band == + sap_ctx->chan_freq) + return; + sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq; + sap_ctx->chan_width_before_switch_band = + sap_ctx->ch_params.ch_width; + sap_debug("Save chan info before switch: %d, width: %d", + sap_ctx->chan_freq, sap_ctx->ch_params.ch_width); + restart_freq = wlansap_get_2g_first_safe_chan_freq(sap_ctx); + restart_ch_width = sap_ctx->ch_params.ch_width; + if (restart_ch_width > CH_WIDTH_40MHZ) { + sap_debug("set 40M when switch SAP to 2G"); + restart_ch_width = CH_WIDTH_40MHZ; + } + } else if (sap_band == REG_BAND_2G && + (band == BAND_ALL || band == BAND_5G)) { + if (sap_ctx->chan_freq_before_switch_band == 0) + return; + restart_freq = sap_ctx->chan_freq_before_switch_band; + restart_ch_width = sap_ctx->chan_width_before_switch_band; + sap_debug("Restore chan freq: %d, width: %d", + restart_freq, restart_ch_width); + sap_ctx->chan_freq_before_switch_band = 0; + sap_ctx->chan_width_before_switch_band = CH_WIDTH_INVALID; + + } else { + sap_debug("No need switch SAP/Go channel"); + return; + } + + mac = cds_get_context(QDF_MODULE_ID_PE); + restart_chan = wlan_reg_freq_to_chan(mac->pdev, restart_freq); + cc_mode = sap_ctx->cc_switch_mode; + phy_mode = sap_ctx->csr_roamProfile.phyMode; + intf_ch = sme_check_concurrent_channel_overlap(MAC_HANDLE(mac), + restart_freq, + phy_mode, + cc_mode); + if (intf_ch) + restart_chan = intf_ch; + sap_ctx->csa_reason = CSA_REASON_BAND_RESTRICTED; + vdev_id = sap_ctx->vdev->vdev_objmgr.vdev_id; + restart_freq = wlan_chan_to_freq(restart_chan); + sap_debug("vdev: %d, CSA target channel: %d, width: %d", + vdev_id, restart_freq, restart_ch_width); + policy_mgr_change_sap_channel_with_csa(mac->psoc, vdev_id, + restart_freq, + restart_ch_width, true); +} diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index c957b65eff3c..5f4f0bef52b7 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21593,6 +21593,21 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, case SIR_ROAM_SYNCH_PROPAGATION: break; case SIR_ROAM_SYNCH_COMPLETE: + /* Handle one race condition that if candidate is already + *selected & FW has gone ahead with roaming or about to go + * ahead when set_band comes, it will be complicated for FW + * to stop the current roaming. Instead, host will check the + * roam sync to make sure the new AP is on 2G, or disconnect + * the AP. + */ + if (wlan_reg_is_disable_for_freq(mac_ctx->pdev, + roam_synch_data->chan_freq)) { + csr_roam_disconnect(mac_ctx, session_id, + eCSR_DISCONNECT_REASON_DEAUTH); + sme_debug("Roaming Failed for disabled channel or band"); + vdev_roam_params->roam_invoke_in_progress = false; + goto end; + } /* * Following operations need to be done once roam sync * completion is sent to FW, hence called here: