From cde33d77d673f0770d77b4926e0a9897e7cca95d Mon Sep 17 00:00:00 2001 From: Chandrasekaran Manishekar Date: Thu, 14 Apr 2016 19:03:39 +0530 Subject: [PATCH] qcacld-3.0: Send channel switch request instead of doing SAP restart Send channel switch request instead of performing SAP restart when doing a MCC to SCC switch. This is controlled using the existing INI item 'gWlanMccToSccSwitchMode'. The new value of '3' will perform this channel change by sending (E)/CSA whereas the old value of '2' can still be used to do a channel change by doing SAP restart Change-Id: I79e7317219503de0a9957940f3cf7a4e91c7a521 CRs-Fixed: 986202 --- core/cds/inc/cds_concurrency.h | 4 +++ core/cds/inc/cds_sched.h | 4 ++- core/cds/src/cds_concurrency.c | 47 ++++++++++++++++++++++++++++++++- core/hdd/inc/wlan_hdd_cfg.h | 2 +- core/hdd/inc/wlan_hdd_main.h | 9 +++++++ core/hdd/src/wlan_hdd_hostapd.c | 33 +++++++++++++++++++++++ core/hdd/src/wlan_hdd_hostapd.h | 6 +++++ core/hdd/src/wlan_hdd_main.c | 28 ++++++++++++++++++++ core/hdd/src/wlan_hdd_power.c | 6 +++++ core/sme/src/csr/csr_util.c | 4 ++- 10 files changed, 139 insertions(+), 4 deletions(-) diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index d8dc3b338182..14394162ea29 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -681,4 +681,8 @@ QDF_STATUS cds_stop_start_opportunistic_timer(void); QDF_STATUS cds_handle_hw_mode_change_on_csa(uint16_t session_id, uint8_t channel, uint8_t *bssid, void *dst, void *src, uint32_t numbytes); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +QDF_STATUS cds_register_sap_restart_channel_switch_cb( + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)); +#endif #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index e07f15143455..7325b6155e26 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -288,7 +288,9 @@ typedef struct _cds_context_type { qdf_event_t connection_update_done_evt; qdf_mutex_t qdf_conc_list_lock; qdf_mc_timer_t dbs_opportunistic_timer; - +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t); +#endif } cds_context_type, *p_cds_contextType; /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index fff2820af871..1d735a6d113f 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -6604,6 +6604,13 @@ static void cds_check_sta_ap_concurrent_ch_intf(void *data) tHalHandle *hal_handle; hdd_ap_ctx_t *hdd_ap_ctx; uint16_t intf_ch = 0; + p_cds_contextType cds_ctx; + + cds_ctx = cds_get_global_context(); + if (!cds_ctx) { + cds_err("Invalid CDS context"); + return; + } cds_info("cds_concurrent_open_sessions_running: %d", cds_concurrent_open_sessions_running()); @@ -6642,7 +6649,18 @@ static void cds_check_sta_ap_concurrent_ch_intf(void *data) hdd_ap_ctx->sapConfig.channel, hdd_ap_ctx->sapConfig.sec_ch, &hdd_ap_ctx->sapConfig.ch_params); - cds_restart_sap(ap_adapter); + + if ((hdd_ctx->config->WlanMccToSccSwitchMode == + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) && + (cds_ctx->sap_restart_chan_switch_cb)) { + cds_info("SAP chan change without restart"); + cds_ctx->sap_restart_chan_switch_cb(ap_adapter, + hdd_ap_ctx->sapConfig.channel, + hdd_ap_ctx->sapConfig.ch_params.ch_width); + } else { + cds_restart_sap(ap_adapter); + } + } /** * cds_check_concurrent_intf_and_restart_sap() - Check concurrent change intf @@ -7989,3 +8007,30 @@ QDF_STATUS cds_handle_hw_mode_change_on_csa(uint16_t session_id, } return status; } + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * cds_register_sap_restart_channel_switch_cb() - Register callback for SAP + * channel switch without restart + * @sap_restart_chan_switch_cb: Callback to perform channel switch + * + * Registers callback to perform channel switch without having to actually + * restart the beaconing entity + * + * Return: QDF_STATUS + */ +QDF_STATUS cds_register_sap_restart_channel_switch_cb( + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)) +{ + p_cds_contextType cds_ctx; + + cds_ctx = cds_get_global_context(); + if (!cds_ctx) { + cds_err("Invalid CDS context"); + return QDF_STATUS_E_FAILURE; + } + + cds_ctx->sap_restart_chan_switch_cb = sap_restart_chan_switch_cb; + return QDF_STATUS_SUCCESS; +} +#endif diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 4c1e182e3df5..93ceda3bb05b 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -343,7 +343,7 @@ typedef enum { #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH #define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE "gWlanMccToSccSwitchMode" #define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MIN (QDF_MCC_TO_SCC_SWITCH_DISABLE) -#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MAX (QDF_MCC_TO_SCC_SWITCH_FORCE) +#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MAX (QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) #define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_DEFAULT (QDF_MCC_TO_SCC_SWITCH_DISABLE) #endif diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 1075ec566ab6..520c5440ebc0 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1631,6 +1631,15 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset); void hdd_update_config(hdd_context_t *hdd_ctx); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void); +#else +static inline QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void) +{ + return CDF_STATUS_SUCCESS; +} +#endif + #ifdef FEATURE_TSO /** * hdd_set_tso_flags() - enable TSO flags in the network device diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index c93c55c2954d..28ef83867844 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2098,6 +2098,39 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, return ret; } +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA + * @ap_adapter: HDD adapter + * @target_channel: Channel to which switch must happen + * @target_bw: Bandwidth of the target channel + * + * Invokes the necessary API to perform channel switch for the SAP or GO + * + * Return: None + */ +void hdd_sap_restart_with_channel_switch(hdd_adapter_t *ap_adapter, + uint32_t target_channel, + uint32_t target_bw) +{ + struct net_device *dev = ap_adapter->dev; + int ret; + + ENTER(); + + if (!dev) { + hdd_err("Invalid dev pointer"); + return; + } + + ret = hdd_softap_set_channel_change(dev, target_channel, target_bw); + if (ret) { + hdd_err("channel switch failed"); + return; + } +} +#endif + int static __iw_softap_set_ini_cfg(struct net_device *dev, struct iw_request_info *info, diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index 4cd70afd5f18..795a9d74a2ef 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -63,6 +63,12 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, enum ch_width target_bw); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void hdd_sap_restart_with_channel_switch(hdd_adapter_t *adapter, + uint32_t target_channel, + uint32_t target_bw); +#endif + eCsrEncryptionType hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index b6174c29d470..0fae759c29ae 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5542,6 +5542,29 @@ static inline bool hdd_hold_rtnl_lock(void) { return false; } static inline void hdd_release_rtnl_lock(void) { } #endif +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * hdd_register_for_sap_restart_with_channel_switch() - Register for SAP channel + * switch without restart + * + * Registers callback function to change the operating channel of SAP by using + * channel switch announcements instead of restarting SAP. + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void) +{ + QDF_STATUS status; + + status = cds_register_sap_restart_channel_switch_cb( + (void *)hdd_sap_restart_with_channel_switch); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("restart cb registration failed"); + + return status; +} +#endif + /** * hdd_wlan_startup() - HDD init function * @dev: Pointer to the underlying device @@ -5852,6 +5875,11 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) sme_ext_scan_register_callback(hdd_ctx->hHal, wlan_hdd_cfg80211_extscan_callback); + status = hdd_register_for_sap_restart_with_channel_switch(); + if (!QDF_IS_STATUS_SUCCESS(status)) + /* Error already logged */ + goto err_unreg_netdev_notifier; + sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal, hdd_rssi_threshold_breached); diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 66ebc57a9749..4a9870aabda3 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1594,6 +1594,12 @@ QDF_STATUS hdd_wlan_re_init(void *hif_sc) sme_ext_scan_register_callback(pHddCtx->hHal, wlan_hdd_cfg80211_extscan_callback); + + qdf_status = hdd_register_for_sap_restart_with_channel_switch(); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + /* Error already logged */ + goto err_cds_disable; + sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached); #ifdef WLAN_FEATURE_LPSS diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 865bbb494cff..56786f996c38 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -765,7 +765,9 @@ uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx, intf_ch, sap_ch, intf_ch); if (intf_ch && sap_ch != intf_ch && - cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE) { + cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE && + cc_switch_mode != + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) { sap_lfreq = sap_cfreq - sap_hbw; sap_hfreq = sap_cfreq + sap_hbw; intf_lfreq = intf_cfreq - intf_hbw;