qcacld-3.0: Remove wma_vdev_start_req from channel switch

1. Remove wma_vdev_start_req from channel switch, fill vdev mlme
directly.
2. Add channel switch pre/post handler.

lim_send_switch_chnl_params:
   1. Fill vdev mlme
   2. wma_pre_chan_switch_setup->wma_vdev_pre_start
   3. vdev_mgr_start_send
   4. wma_post_chan_switch_setup

Change-Id: I88301a39ba45b6092c4483554e1e738fac92cc94
CRs-Fixed: 2530906
This commit is contained in:
Jianmin Zhu 2019-09-18 22:02:41 +08:00 • committed by nshrivas
commit 054c27318a
5 changed files with 280 additions and 86 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -81,7 +81,9 @@
#include "wlan_mlme_public_struct.h"
#include "wlan_mlme_api.h"
#include "wlan_mlme_main.h"
#include <wlan_dfs_utils_api.h>
#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

View file

@ -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