diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 660460ad484d..ca8fa4773a45 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -821,6 +821,15 @@ struct hdd_netif_queue_history { uint32_t pause_map; }; +/** + * struct hdd_chan_change_params - channel related information + * @chan: operating channel + * @chan_params: channel parameters + */ +struct hdd_chan_change_params { + uint8_t chan; + struct ch_params_s chan_params; +}; #define WLAN_HDD_ADAPTER_MAGIC 0x574c414e /* ASCII "WLAN" */ @@ -1635,8 +1644,8 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, void hdd_update_config(hdd_context_t *hdd_ctx); QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, - struct net_device *dev, uint8_t oper_chan); - + struct net_device *dev, + struct hdd_chan_change_params chan_change); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void); #else diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 5c601674c842..a7d4cf5d04b5 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3973,6 +3973,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, hdd_station_ctx_t *pHddStaCtx = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; hdd_context_t *pHddCtx = NULL; + struct hdd_chan_change_params chan_change; hddLog(LOG2, "CSR Callback: status= %d result= %d roamID=%d", @@ -4313,8 +4314,18 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, hdd_info("channel switch for session:%d to channel:%d", pAdapter->sessionId, pRoamInfo->chan_info.chan_id); + chan_change.chan = pRoamInfo->chan_info.chan_id; + chan_change.chan_params.ch_width = + pRoamInfo->chan_info.ch_width; + chan_change.chan_params.sec_ch_offset = + pRoamInfo->chan_info.sec_ch_offset; + chan_change.chan_params.center_freq_seg0 = + pRoamInfo->chan_info.band_center_freq1; + chan_change.chan_params.center_freq_seg1 = + pRoamInfo->chan_info.band_center_freq2; + status = hdd_chan_change_notify(pAdapter, pAdapter->dev, - pRoamInfo->chan_info.chan_id); + chan_change); if (QDF_IS_STATUS_ERROR(status)) hdd_err("channel change notification failed"); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index dda9f5adf0e1..97a747decb27 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -625,97 +625,11 @@ static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter, } } -#ifdef WLAN_FEATURE_MBSSID -static eCsrPhyMode -hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter) -{ - return wlansap_get_phymode(WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter)); -} -#else -static eCsrPhyMode -hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter) -{ - return wlansap_get_phymode( - (WLAN_HDD_GET_CTX(hostapd_adapter))->pcds_context); -} -#endif - -/** - * hdd_update_chandef() - Function to update channel width and center freq - * @hostapd_adapter: hostapd adapter - * @chandef: cfg80211 chan def - * @cb_mode: chan offset - * - * This function will be called to update channel width and center freq - * - * Return: None - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) || defined(WITH_BACKPORTS) -static inline void -hdd_update_chandef(hdd_adapter_t *hostapd_adapter, - struct cfg80211_chan_def *chandef, - ePhyChanBondState cb_mode) -{ - uint16_t ch_width; - hdd_ap_ctx_t *phdd_ap_ctx; - uint8_t center_chan, chan; - - phdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter); - ch_width = phdd_ap_ctx->sapConfig.acs_cfg.ch_width; - - switch (ch_width) { - case eHT_CHANNEL_WIDTH_20MHZ: - case eHT_CHANNEL_WIDTH_40MHZ: - hdd_info("ch_width %d, won't update", ch_width); - break; - case eHT_CHANNEL_WIDTH_80MHZ: - chan = cds_freq_to_chan(chandef->chan->center_freq); - chandef->width = NL80211_CHAN_WIDTH_80; - - switch (cb_mode) { - case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: - case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: - center_chan = chan + 2; - break; - case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: - center_chan = chan + 6; - break; - case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: - case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: - center_chan = chan - 2; - break; - case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: - center_chan = chan - 6; - break; - default: - center_chan = chan; - break; - } - - chandef->center_freq1 = cds_chan_to_freq(center_chan); - break; - case eHT_CHANNEL_WIDTH_160MHZ: - default: - /* Todo, please add related codes if support 160MHZ or others */ - hdd_err("unsupport ch_width %d", ch_width); - break; - } - -} -#else -static inline void -hdd_update_chandef(hdd_adapter_t *hostapd_adapter, - struct cfg80211_chan_def *chandef, - ePhyChanBondState cb_mode) -{ -} -#endif - /** * hdd_chan_change_notify() - Function to notify hostapd about channel change * @hostapd_adapter hostapd adapter * @dev: Net device structure - * @oper_chan: New operating channel + * @chan_change: New channel change parameters * * This function is used to notify hostapd about the channel change * @@ -724,13 +638,11 @@ hdd_update_chandef(hdd_adapter_t *hostapd_adapter, */ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, struct net_device *dev, - uint8_t oper_chan) + struct hdd_chan_change_params chan_change) { struct ieee80211_channel *chan; struct cfg80211_chan_def chandef; enum nl80211_channel_type channel_type; - eCsrPhyMode phy_mode; - ePhyChanBondState cb_mode; uint32_t freq; tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); @@ -739,7 +651,13 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, return QDF_STATUS_E_FAILURE; } - freq = cds_chan_to_freq(oper_chan); + hdd_info("chan:%d width:%d sec_ch_offset:%d seg0:%d seg1:%d", + chan_change.chan, chan_change.chan_params.ch_width, + chan_change.chan_params.sec_ch_offset, + chan_change.chan_params.center_freq_seg0, + chan_change.chan_params.center_freq_seg1); + + freq = cds_chan_to_freq(chan_change.chan); chan = __ieee80211_get_channel(adapter->wdev.wiphy, freq); @@ -748,46 +666,49 @@ QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter, return QDF_STATUS_E_FAILURE; } - if (adapter->device_mode == QDF_SAP_MODE || - adapter->device_mode == QDF_P2P_GO_MODE) - phy_mode = hdd_sap_get_phymode(adapter); - else - phy_mode = sme_get_phy_mode(hal); - - if (oper_chan <= 14) - cb_mode = sme_get_cb_phy_state_from_cb_ini_value( - sme_get_channel_bonding_mode24_g(hal)); - else - cb_mode = sme_get_cb_phy_state_from_cb_ini_value( - sme_get_channel_bonding_mode5_g(hal)); - - switch (phy_mode) { - case eCSR_DOT11_MODE_11n: - case eCSR_DOT11_MODE_11n_ONLY: - case eCSR_DOT11_MODE_11ac: - case eCSR_DOT11_MODE_11ac_ONLY: - if (cb_mode == PHY_SINGLE_CHANNEL_CENTERED) - channel_type = NL80211_CHAN_HT20; - else if (cb_mode == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - channel_type = NL80211_CHAN_HT40MINUS; - else if (cb_mode == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - channel_type = NL80211_CHAN_HT40PLUS; - else - channel_type = NL80211_CHAN_HT40PLUS; + switch (chan_change.chan_params.sec_ch_offset) { + case PHY_SINGLE_CHANNEL_CENTERED: + channel_type = NL80211_CHAN_HT20; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + channel_type = NL80211_CHAN_HT40MINUS; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + channel_type = NL80211_CHAN_HT40PLUS; break; default: channel_type = NL80211_CHAN_NO_HT; break; } - hdd_info("%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d", - __func__, phy_mode, cb_mode, channel_type, oper_chan); - cfg80211_chandef_create(&chandef, chan, channel_type); - if ((phy_mode == eCSR_DOT11_MODE_11ac) || - (phy_mode == eCSR_DOT11_MODE_11ac_ONLY)) - hdd_update_chandef(adapter, &chandef, cb_mode); + /* cfg80211_chandef_create() does update of width and center_freq1 + * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS + * and NL80211_CHAN_HT40MINUS. + */ + if (chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) + chandef.width = NL80211_CHAN_WIDTH_80; + else if (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) + chandef.width = NL80211_CHAN_WIDTH_80P80; + else if (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ) + chandef.width = NL80211_CHAN_WIDTH_160; + + if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) || + (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) || + (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) { + if (chan_change.chan_params.center_freq_seg0) + chandef.center_freq1 = cds_chan_to_freq( + chan_change.chan_params.center_freq_seg0); + + if (chan_change.chan_params.center_freq_seg1) + chandef.center_freq2 = cds_chan_to_freq( + chan_change.chan_params.center_freq_seg1); + } + + hdd_info("notify: chan:%d width:%d freq1:%d freq2:%d", + chandef.chan->center_freq, chandef.width, chandef.center_freq1, + chandef.center_freq2); cfg80211_ch_switch_notify(dev, &chandef); @@ -898,6 +819,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN; hdd_adapter_t *con_sap_adapter; QDF_STATUS status = QDF_STATUS_SUCCESS; + struct hdd_chan_change_params chan_change; int ret = 0; dev = (struct net_device *)usrDataForCallback; @@ -1750,11 +1672,23 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, * only for non driver override acs */ if (pHostapdAdapter->device_mode == QDF_SAP_MODE && - pHddCtx->config->force_sap_acs) + pHddCtx->config->force_sap_acs) { return QDF_STATUS_SUCCESS; - else + } else { + chan_change.chan = + pSapEvent->sapevt.sap_ch_selected.pri_ch; + chan_change.chan_params.ch_width = + pSapEvent->sapevt.sap_ch_selected.ch_width; + chan_change.chan_params.sec_ch_offset = + pSapEvent->sapevt.sap_ch_selected.ht_sec_ch; + chan_change.chan_params.center_freq_seg0 = + pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch; + chan_change.chan_params.center_freq_seg1 = + pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch; + return hdd_chan_change_notify(pHostapdAdapter, dev, - pSapEvent->sapevt.sap_ch_selected.pri_ch); + chan_change); + } #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE case eSAP_ACS_SCAN_SUCCESS_EVENT: diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 34e4ac7d364a..c36d69873465 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1170,6 +1170,8 @@ typedef struct sSirSmeChanInfo { uint32_t reg_info_2; uint8_t nss; uint32_t rate_flags; + uint8_t sec_ch_offset; + enum phy_ch_width ch_width; } tSirSmeChanInfo, *tpSirSmeChanInfo; /* / Definition for Association indication from peer */ @@ -1536,6 +1538,7 @@ typedef struct sSirSmeSwitchChannelInd { uint16_t length; uint8_t sessionId; uint16_t newChannelId; + struct ch_params_s chan_params; struct qdf_mac_addr bssid; /* BSSID */ } tSirSmeSwitchChannelInd, *tpSirSmeSwitchChannelInd; diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 350bffc604d4..403f19de4a79 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -2650,6 +2650,24 @@ void lim_switch_channel_cback(tpAniSirGlobal pMac, QDF_STATUS status, pSirSmeSwitchChInd->newChannelId = psessionEntry->gLimChannelSwitch.primaryChannel; pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId; + pSirSmeSwitchChInd->chan_params.ch_width = + psessionEntry->gLimChannelSwitch.ch_width; + pSirSmeSwitchChInd->chan_params.sec_ch_offset = + psessionEntry->gLimChannelSwitch.sec_ch_offset; + pSirSmeSwitchChInd->chan_params.center_freq_seg0 = + psessionEntry->gLimChannelSwitch.ch_center_freq_seg0; + pSirSmeSwitchChInd->chan_params.center_freq_seg1 = + psessionEntry->gLimChannelSwitch.ch_center_freq_seg1; + + lim_log(pMac, LOG1, + FL("session:%d chan:%d width:%d sec offset:%d seg0:%d seg1:%d"), + pSirSmeSwitchChInd->sessionId, + pSirSmeSwitchChInd->newChannelId, + pSirSmeSwitchChInd->chan_params.ch_width, + pSirSmeSwitchChInd->chan_params.sec_ch_offset, + pSirSmeSwitchChInd->chan_params.center_freq_seg0, + pSirSmeSwitchChInd->chan_params.center_freq_seg1); + qdf_mem_copy(pSirSmeSwitchChInd->bssid.bytes, psessionEntry->bssId, QDF_MAC_ADDR_SIZE); mmhMsg.bodyptr = pSirSmeSwitchChInd; diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 51751d6bddb9..b2ebe12ecef1 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -907,7 +907,6 @@ QDF_STATUS wlansap_acs_chselect(void *pvos_gctx, tpWLAN_SAPEventCB pacs_event_callback, tsap_Config_t *pconfig, void *pusr_context); -eCsrPhyMode wlansap_get_phymode(void *pctx); #ifdef __cplusplus } #endif diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index faea47e5d849..99d634691299 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -2871,19 +2871,23 @@ QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, * follows pri AP */ sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; - sap_ctx->acs_cfg->ch_width = sap_ctx->ch_params.ch_width; - sap_config_acs_result(hal, sap_ctx, sap_ctx->secondary_ch); + sap_ctx->acs_cfg->ch_width = + sap_ctx->csr_roamProfile.ch_params.ch_width; + sap_config_acs_result(hal, sap_ctx, + sap_ctx->csr_roamProfile.ch_params.sec_ch_offset); sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; acs_selected = &sap_ap_event.sapevt.sap_ch_selected; acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; - acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; - acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; + acs_selected->ht_sec_ch = + sap_ctx->csr_roamProfile.ch_params.sec_ch_offset; + acs_selected->ch_width = + sap_ctx->csr_roamProfile.ch_params.ch_width; acs_selected->vht_seg0_center_ch = - sap_ctx->acs_cfg->vht_seg0_center_ch; + sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; acs_selected->vht_seg1_center_ch = - sap_ctx->acs_cfg->vht_seg1_center_ch; + sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; break; case eSAP_DFS_NOL_GET: diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index a08c12c76c3f..89a59df2510c 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -2310,9 +2310,22 @@ wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel) */ sapContext->channel = target_channel; sapContext->csr_roamProfile.ch_params.ch_width = ch_params->ch_width; + sapContext->csr_roamProfile.ch_params.sec_ch_offset = + ch_params->sec_ch_offset; + sapContext->csr_roamProfile.ch_params.center_freq_seg0 = + ch_params->center_freq_seg0; + sapContext->csr_roamProfile.ch_params.center_freq_seg1 = + ch_params->center_freq_seg1; + qdf_ret_status = sme_roam_channel_change_req(hHal, sapContext->bssid, ch_params, &sapContext->csr_roamProfile); + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + "%s: chan:%d width:%d offset:%d seg0:%d seg1:%d", + __func__, sapContext->channel, ch_params->ch_width, + ch_params->sec_ch_offset, ch_params->center_freq_seg0, + ch_params->center_freq_seg1); + if (qdf_ret_status == QDF_STATUS_SUCCESS) { sap_signal_hdd_event(sapContext, NULL, eSAP_CHANNEL_CHANGE_EVENT, @@ -3295,26 +3308,3 @@ void wlan_sap_enable_phy_error_logs(tHalHandle hal, bool enable_log) tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); mac_ctx->sap.enable_dfs_phy_error_logs = enable_log; } -/** -* wlansap_get_phymode() - get SAP phymode. -* @pctx: Pointer to the global vos context; a handle to SAP's control block -* can be extracted from its context. When MBSSID feature is enabled, -* SAP context is directly passed to SAP APIs. -* -* This function provides current phymode of SAP interface. -* -* Return: phymode with eCsrPhyMode type. -*/ -eCsrPhyMode -wlansap_get_phymode(void *pctx) -{ - ptSapContext sap_context = NULL; - - sap_context = CDS_GET_SAP_CB(pctx); - if (NULL == sap_context) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid SAP pointer from pctx", __func__); - return eCSR_DOT11_MODE_AUTO; - } - return sap_context->csr_roamProfile.phyMode; -} diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 09a8a2e9ff11..2ebf78eed9aa 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -10341,6 +10341,14 @@ csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) qdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); roamInfo.chan_info.chan_id = pSwitchChnInd->newChannelId; + roamInfo.chan_info.ch_width = + pSwitchChnInd->chan_params.ch_width; + roamInfo.chan_info.sec_ch_offset = + pSwitchChnInd->chan_params.sec_ch_offset; + roamInfo.chan_info.band_center_freq1 = + pSwitchChnInd->chan_params.center_freq_seg0; + roamInfo.chan_info.band_center_freq2 = + pSwitchChnInd->chan_params.center_freq_seg1; status = csr_roam_call_callback(mac_ctx, sessionId, &roamInfo, 0, eCSR_ROAM_STA_CHANNEL_SWITCH, eCSR_ROAM_RESULT_NONE);