diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c index 605184f31f9d..efb4b375b6f7 100644 --- a/core/mac/src/pe/lim/lim_send_messages.c +++ b/core/mac/src/pe/lim/lim_send_messages.c @@ -35,6 +35,7 @@ #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #include "lim_utils.h" #include "wma.h" +#include "../../core/src/vdev_mgr_ops.h" /** * lim_send_beacon_params() - updates bcn params to WMA @@ -119,8 +120,14 @@ QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac, uint32_t cac_duration_ms, uint32_t dfs_regdomain) { - struct wma_vdev_start_req req = {0}; struct pe_session *pe_session; + struct vdev_mlme_obj *mlme_obj; + struct wlan_channel *des_chan; + struct wlan_objmgr_vdev *vdev; + uint8_t vdev_id; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct vdev_start_response rsp = {0}; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); pe_session = pe_find_session_by_session_id(mac, peSessionId); if (!pe_session) { @@ -129,60 +136,61 @@ QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } - req.vdev_id = pe_session->vdev_id; - req.op_chan_freq = wlan_reg_chan_to_freq(mac->pdev, chnlNumber); - req.chan_width = ch_width; - if (cds_is_5_mhz_enabled()) - req.is_quarter_rate = 1; - else if (cds_is_10_mhz_enabled()) - req.is_half_rate = 1; - req.chan_freq_seg0 = - wlan_reg_chan_to_freq(mac->pdev, ch_center_freq_seg0); - req.chan_freq_seg1 = - wlan_reg_chan_to_freq(mac->pdev, ch_center_freq_seg1); - req.dot11_mode = pe_session->dot11mode; - req.cac_duration_ms = cac_duration_ms; - /*Set DFS flag for DFS channel */ - if (ch_width == CH_WIDTH_160MHZ) { - req.is_dfs = true; - } else if (ch_width == CH_WIDTH_80P80MHZ) { - req.is_dfs = false; - if (wlan_reg_get_channel_state(mac->pdev, chnlNumber) == - CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac->pdev, - ch_center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS) - req.is_dfs = true; - } else { - if (wlan_reg_get_channel_state(mac->pdev, chnlNumber) == - CHANNEL_STATE_DFS) - req.is_dfs = true; - else - req.is_dfs = false; + vdev_id = pe_session->vdev_id; + vdev = pe_session->vdev; + if (!vdev) { + pe_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; } - req.beacon_intval = 100; - req.dtim_period = 1; - req.max_txpow = maxTxPower; - req.ssid = pe_session->ssId; - req.hidden_ssid = pe_session->ssidHidden; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + des_chan = vdev->vdev_mlme.des_chan; + des_chan->ch_ieee = chnlNumber; + des_chan->ch_freq = wlan_reg_chan_to_freq(mac->pdev, chnlNumber); + if (des_chan->ch_freq == 0) { + pe_err("Invalid operating frequency: %d", des_chan->ch_freq); + QDF_ASSERT(0); + return QDF_STATUS_E_INVAL; + } + des_chan->ch_width = ch_width; + if (cds_is_5_mhz_enabled()) + mlme_obj->mgmt.rate_info.quarter_rate = 1; + else if (cds_is_10_mhz_enabled()) + mlme_obj->mgmt.rate_info.half_rate = 1; + des_chan->ch_freq_seg1 = ch_center_freq_seg0; + des_chan->ch_freq_seg2 = ch_center_freq_seg1; + pe_debug("ch_freq_seg1: %d, ch_freq_seg2: %d", + des_chan->ch_freq_seg1, des_chan->ch_freq_seg2); + + mlme_obj->mgmt.generic.phy_mode = pe_session->dot11mode; + mlme_obj->mgmt.ap.cac_duration_ms = cac_duration_ms; + + mlme_obj->proto.generic.beacon_interval = 100; + mlme_obj->proto.generic.dtim_period = 1; + mlme_obj->mgmt.generic.maxregpower = maxTxPower; + wlan_vdev_mlme_set_ssid(vdev, pe_session->ssId.ssId, + pe_session->ssId.length); + mlme_obj->mgmt.ap.hidden_ssid = pe_session->ssidHidden; if (pe_session->nss == 2) { - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; + mlme_obj->mgmt.chainmask_info.num_rx_chain = 2; + mlme_obj->mgmt.chainmask_info.num_tx_chain = 2; } else { - req.preferred_rx_streams = 1; - req.preferred_tx_streams = 1; + mlme_obj->mgmt.chainmask_info.num_rx_chain = 1; + mlme_obj->mgmt.chainmask_info.num_tx_chain = 1; } if (lim_is_session_he_capable(pe_session)) - req.he_capable = true; - req.vht_capable = pe_session->vhtCapability; + mlme_obj->proto.he_ops_info.he_ops = true; - pe_debug("dot11mode: %d, vht_capable: %d nss value: %d", - req.dot11_mode, req.vht_capable, + pe_debug("dot11mode: %d, he_capable: %d nss value: %d", + pe_session->dot11mode, mlme_obj->proto.he_ops_info.he_ops, pe_session->nss); - pe_debug("ch width %d, freq %d, maxTxPower %d", - req.chan_width, req.op_chan_freq, req.max_txpow); + pe_debug("ch width %d, ch id %d, maxTxPower %d", + ch_width, chnlNumber, maxTxPower); pe_session->ch_switch_in_progress = true; @@ -190,7 +198,27 @@ QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac, * get the response back from WMA */ SET_LIM_PROCESS_DEFD_MESGS(mac, false); - wma_set_channel(&req); + + status = wma_pre_chan_switch_setup(vdev_id); + if (status != QDF_STATUS_SUCCESS) { + pe_err("failed status = %d", status); + goto send_resp; + } + status = vdev_mgr_start_send(mlme_obj, + mlme_is_chan_switch_in_progress(vdev)); + if (status != QDF_STATUS_SUCCESS) { + pe_err("failed status = %d", status); + goto send_resp; + } + wma_post_chan_switch_setup(vdev_id); + + return QDF_STATUS_SUCCESS; +send_resp: + pe_err("switch channel rsp, status = 0x%x", status); + rsp.status = status; + rsp.vdev_id = vdev_id; + + wma_handle_channel_switch_resp(wma, &rsp); return QDF_STATUS_SUCCESS; } diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 1521ca1b9c34..60793c9c5807 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2600,4 +2600,39 @@ QDF_STATUS wma_get_rx_chainmask(uint8_t pdev_id, uint32_t *chainmask_2g, * Return: None */ void wma_set_channel(struct wma_vdev_start_req *req); + +/** + * wma_handle_channel_switch_resp() - handle channel switch resp + * @wma: wma handle + * @rsp: response for channel switch + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, + struct vdev_start_response *rsp); + +/** + * wma_pre_chan_switch_setup() - handler before channel switch vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_pre_chan_switch_setup(uint8_t vdev_id); + +/** + * wma_pre_chan_switch_setup() - handler after channel switch vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_post_chan_switch_setup(uint8_t vdev_id); + +/** + * wma_pre_chan_switch_setup() - handler vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart); + #endif diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index b6ee6c346504..eb848752680d 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1675,16 +1675,6 @@ void wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *req); int wma_cold_boot_cal_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len); -/** - * wma_handle_channel_switch_resp() - handle channel switch resp - * @wma: wma handle - * @rsp: response for channel switch - * - * Return: QDF_STATUS - */ -QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, - struct vdev_start_response *rsp); - /** * wma_set_roam_triggers() - Send roam trigger bitmap to WMI * @wma_handle: wma handle diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 298740b0e43d..b5053a55d9b0 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -81,7 +81,9 @@ #include "wlan_mlme_public_struct.h" #include "wlan_mlme_api.h" #include "wlan_mlme_main.h" +#include #include "../../core/src/vdev_mgr_ops.h" +#include "wlan_utility.h" /** * wma_find_vdev_by_addr() - find vdev_id from mac address @@ -3052,6 +3054,149 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, return vdev_mgr_start_send(mlme_obj, isRestart); } +QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart) +{ + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *intr = wma->interfaces; + struct mac_context *mac_ctx = NULL; + uint16_t bw_val; + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + uint32_t chan_mode; + enum phy_ch_width ch_width; + struct wlan_mlme_nss_chains *ini_cfg; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev = intr[vdev_id].vdev; + struct wlan_channel *des_chan; + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + des_chan = vdev->vdev_mlme.des_chan; + + ini_cfg = mlme_get_ini_vdev_config(iface->vdev); + if (!ini_cfg) { + wma_err("nss chain ini config NULL"); + return QDF_STATUS_E_FAILURE; + } + + mac_ctx = cds_get_context(QDF_MODULE_ID_PE); + if (!mac_ctx) { + WMA_LOGE("%s: vdev start failed as mac_ctx is NULL", __func__); + return QDF_STATUS_E_FAILURE; + } + + des_chan->ch_cfreq1 = des_chan->ch_freq; + ch_width = des_chan->ch_width; + bw_val = wlan_reg_get_bw_value(ch_width); + if (bw_val > 20) { + if (des_chan->ch_freq_seg1) { + des_chan->ch_cfreq1 = + wlan_chan_to_freq(des_chan->ch_freq_seg1); + } else { + wma_err("Invalid cntr_freq for bw %d, drop to 20", + bw_val); + ch_width = CH_WIDTH_20MHZ; + bw_val = 20; + } + } + if (bw_val > 80) { + if (des_chan->ch_freq_seg2) { + des_chan->ch_cfreq2 = + wlan_chan_to_freq(des_chan->ch_freq_seg2); + } else { + wma_err("Invalid cntr_freq for bw %d, drop to 80", + bw_val); + des_chan->ch_cfreq2 = 0; + ch_width = CH_WIDTH_80MHZ; + } + } else { + des_chan->ch_cfreq2 = 0; + } + chan_mode = wma_chan_phy_mode(des_chan->ch_freq, ch_width, + mlme_obj->mgmt.generic.phy_mode); + + if (chan_mode == MODE_UNKNOWN) { + WMA_LOGE("%s: invalid phy mode!", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!des_chan->ch_cfreq1) { + WMA_LOGE("%s: invalid center freq1", __func__); + return QDF_STATUS_E_FAILURE; + } + + if ((ch_width == CH_WIDTH_160MHZ || + ch_width == CH_WIDTH_80P80MHZ) && !des_chan->ch_cfreq2) { + WMA_LOGE("%s: invalid center freq2 for 160MHz", __func__); + return QDF_STATUS_E_FAILURE; + } + mlme_obj->mgmt.generic.phy_mode = chan_mode; + + intr[vdev_id].chanmode = chan_mode; + intr[vdev_id].config.gtx_info.gtxRTMask[0] = + CFG_TGT_DEFAULT_GTX_HT_MASK; + intr[vdev_id].config.gtx_info.gtxRTMask[1] = + CFG_TGT_DEFAULT_GTX_VHT_MASK; + + intr[vdev_id].config.gtx_info.gtxUsrcfg = + mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg; + + intr[vdev_id].config.gtx_info.gtxPERThreshold = + CFG_TGT_DEFAULT_GTX_PER_THRESHOLD; + intr[vdev_id].config.gtx_info.gtxPERMargin = + CFG_TGT_DEFAULT_GTX_PER_MARGIN; + intr[vdev_id].config.gtx_info.gtxTPCstep = + CFG_TGT_DEFAULT_GTX_TPC_STEP; + intr[vdev_id].config.gtx_info.gtxTPCMin = + CFG_TGT_DEFAULT_GTX_TPC_MIN; + intr[vdev_id].config.gtx_info.gtxBWMask = + CFG_TGT_DEFAULT_GTX_BW_MASK; + intr[vdev_id].mhz = des_chan->ch_freq; + intr[vdev_id].chan_width = ch_width; + intr[vdev_id].ch_freq = des_chan->ch_freq; + + /* + * If the channel has DFS set, flip on radar reporting. + * + * It may be that this should only be done for IBSS/hostap operation + * as this flag may be interpreted (at some point in the future) + * by the firmware as "oh, and please do radar DETECTION." + * + * If that is ever the case we would insert the decision whether to + * enable the firmware flag here. + */ + if (QDF_GLOBAL_MONITOR_MODE != cds_get_conparam() && + utils_is_dfs_ch(wma->pdev, des_chan->ch_ieee)) + mlme_obj->mgmt.generic.disable_hw_ack = true; + + if (mlme_obj->mgmt.rate_info.bcn_tx_rate) { + wma_debug("beacon tx rate [%u * 100 Kbps]", + mlme_obj->mgmt.rate_info.bcn_tx_rate); + /* + * beacon_tx_rate is in multiples of 100 Kbps. + * Convert the data rate to hw rate code. + */ + mlme_obj->mgmt.rate_info.bcn_tx_rate = + wma_get_bcn_rate_code(mlme_obj->mgmt.rate_info.bcn_tx_rate); + } + + if (!restart) { + WMA_LOGD("%s, vdev_id: %d, unpausing tx_ll_queue at VDEV_START", + __func__, vdev_id); + cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), + wma->interfaces[vdev_id].handle, + 0xffffffff); + wma_vdev_update_pause_bitmap(vdev_id, 0); + } + + /* Send the dynamic nss chain params before vdev start to fw */ + if (wma->dynamic_nss_chains_support) + wma_vdev_nss_chain_params_send(vdev_id, ini_cfg); + + return QDF_STATUS_SUCCESS; +} + /** * wma_peer_assoc_conf_handler() - peer assoc conf handler * @handle: wma handle diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 42e691c75da9..19da795e8a0e 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -3496,24 +3496,21 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id) } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ -void wma_set_channel(struct wma_vdev_start_req *req) +QDF_STATUS wma_pre_chan_switch_setup(uint8_t vdev_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t vdev_id = req->vdev_id; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX); struct wma_txrx_node *intr = &wma->interfaces[vdev_id]; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint16_t beacon_interval_ori; - uint8_t chan; - struct vdev_start_response rsp = {0}; bool restart; uint16_t reduced_beacon_interval; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev = intr->vdev; - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - status = QDF_STATUS_E_FAILURE; - goto send_resp; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; } restart = @@ -3539,8 +3536,9 @@ void wma_set_channel(struct wma_vdev_start_req *req) __func__, reduced_beacon_interval); /* Add a timer to reset the beacon interval back*/ - beacon_interval_ori = req->beacon_intval; - req->beacon_intval = reduced_beacon_interval; + beacon_interval_ori = mlme_obj->proto.generic.beacon_interval; + mlme_obj->proto.generic.beacon_interval = + reduced_beacon_interval; if (wma_fill_beacon_interval_reset_req(wma, vdev_id, beacon_interval_ori, @@ -3551,30 +3549,28 @@ void wma_set_channel(struct wma_vdev_start_req *req) } } - status = wma_vdev_start(wma, req, restart); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGP("%s: vdev start failed status = %d", __func__, - status); - goto send_resp; - } + status = wma_vdev_pre_start(vdev_id, restart); + + return status; +} + +QDF_STATUS wma_post_chan_switch_setup(uint8_t vdev_id) +{ + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct wma_txrx_node *intr = &wma->interfaces[vdev_id]; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_channel *des_chan; /* * Record monitor mode channel here in case HW * indicate RX PPDU TLV with invalid channel number. */ if (intr->type == WMI_VDEV_TYPE_MONITOR) { - chan = wlan_reg_freq_to_chan(wma->pdev, req->op_chan_freq); - cdp_record_monitor_chan_num(soc, pdev, chan); + des_chan = intr->vdev->vdev_mlme.des_chan; + cdp_record_monitor_chan_num(soc, pdev, des_chan->ch_ieee); } - - return; -send_resp: - WMA_LOGI("%s: wma switch channel rsp, status = 0x%x", - __func__, status); - rsp.status = status; - rsp.vdev_id = vdev_id; - - wma_handle_channel_switch_resp(wma, &rsp); + return QDF_STATUS_SUCCESS; } #ifdef FEATURE_WLAN_ESE