qcacld-3.0: Update the ini params according to the BDF setting

Currently the driver just start the vdev according to the ini
params, without consdering the tx, rx chainmask supported by the
FW per band, per mac, which can lead to connection in 2x2, even
though FW is not capable of 2 antennas on a particular band.

Fix is to intersect both the tx, rx chainmask for both bands,
and change the ini to minimum of the nss supported by ini, and
the BDF setting of the chains.

Change-Id: Ib0e9bac19959bbcf9bade7dbd78674be4099a23d
CRs-Fixed: 2414103
This commit is contained in:
gaurank kathpalia 2019-03-12 19:17:56 +05:30 committed by nshrivas
parent d8546bb3eb
commit fa7ad0a453
8 changed files with 253 additions and 26 deletions

View File

@ -834,6 +834,20 @@ struct wlan_mlme_he_caps {
};
#endif
/**
* struct wlan_mlme_chain_cfg - Chain info related structure
* @max_tx_chains_2g: max tx chains supported in 2.4ghz band
* @max_rx_chains_2g: max rx chains supported in 2.4ghz band
* @max_tx_chains_5g: max tx chains supported in 5ghz band
* @max_rx_chains_5g: max rx chains supported in 5ghz band
*/
struct wlan_mlme_chain_cfg {
uint8_t max_tx_chains_2g;
uint8_t max_rx_chains_2g;
uint8_t max_tx_chains_5g;
uint8_t max_rx_chains_5g;
};
/**
* struct wlan_mlme_rates - RATES related config items
* @cfpPeriod: cfp period info

View File

@ -1848,7 +1848,6 @@ struct hdd_context {
enum sar_version sar_version;
struct hdd_dynamic_mac dynamic_mac_list[QDF_MAX_CONCURRENCY_PERSONA];
bool dynamic_nss_chains_support;
struct qdf_mac_addr hw_macaddr;
struct qdf_mac_addr provisioned_mac_addr[QDF_MAX_CONCURRENCY_PERSONA];
struct qdf_mac_addr derived_mac_addr[QDF_MAX_CONCURRENCY_PERSONA];

View File

@ -1511,6 +1511,7 @@ hdd_set_nss_params(struct hdd_adapter *adapter,
return QDF_STATUS_SUCCESS;
}
/**
* hdd_update_nss() - Update the number of spatial streams supported.
* Ensure that nss is either 1 or 2 before calling this.
@ -1585,8 +1586,8 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX;
band++) {
/* This API will change the global ini in mlme cfg */
sme_update_vdev_nss(mac_handle, rx_nss, tx_nss,
adapter->device_mode, band);
sme_update_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
adapter->device_mode, band);
/*
* This API will change the vdev nss params in mac
* context

View File

@ -1801,6 +1801,7 @@ void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
bool bval = false;
uint8_t value = 0;
uint32_t fine_time_meas_cap = 0;
enum nss_chains_band_info band;
if (!hdd_ctx) {
hdd_err("HDD context is NULL");
@ -1944,6 +1945,22 @@ void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
}
hdd_update_tgt_twt_cap(hdd_ctx, cfg);
for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_STA_MODE, band);
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_SAP_MODE, band);
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_TDLS_MODE, band);
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_P2P_DEVICE_MODE,
band);
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_OCB_MODE, band);
sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
QDF_TDLS_MODE, band);
}
hdd_update_vdev_nss(hdd_ctx);
hdd_ctx->dynamic_nss_chains_support =

View File

@ -755,7 +755,7 @@ struct mgmt_beacon_probe_filter {
*/
struct mac_context {
enum qdf_driver_type gDriverType;
struct wlan_mlme_chain_cfg fw_chain_cfg;
tAniSirCfg cfg;
struct wlan_mlme_cfg *mlme_cfg;
tAniSirLim lim;

View File

@ -360,7 +360,25 @@ sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev *vdev,
struct wlan_mlme_nss_chains *vdev_ini_cfg);
/**
* sme_update_vdev_nss() - Change the nss in ini(rx_nss_(band)) for
* sme_modify_nss_chains_tgt_cfg() - Change the nss in ini for
* particular opmode, and band, according to the chain config supported by FW.
* @mac_handle: The handle returned by mac_open.
* @vdev_op_mode: vdev operation mode.
* @band:- band for which user wants to change nss.
*
* This API will change the nss in ini (for eg. rx_nss_2g) in the mlme cfg i.e
* the global config structure kept in mac context, according to the max
* supported chains per band which is got as part of ext service ready event.
*
* Return: none
*/
void
sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band);
/**
* sme_update_nss_in_mlme_cfg() - Change the nss in ini(rx_nss_(band)) for
* particular opmode, and band.
* @mac_handle: The handle returned by mac_open.
* @rx_nss: new value of rx nss that user wants to change.
@ -374,10 +392,10 @@ sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev *vdev,
* Return: none
*/
void
sme_update_vdev_nss(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band);
sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band);
/**
* sme_nss_chains_update() - validate and send the user params to fw

View File

@ -4321,11 +4321,36 @@ sme_validate_nss_chains_config(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_SUCCESS;
}
static void
sme_change_vdev_nss_ini(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
static bool
sme_is_nss_update_allowed(struct wlan_mlme_chain_cfg chain_cfg,
uint8_t rx_nss, uint8_t tx_nss,
enum nss_chains_band_info band)
{
switch (band) {
case NSS_CHAINS_BAND_2GHZ:
if (rx_nss > chain_cfg.max_rx_chains_2g)
return false;
if (tx_nss > chain_cfg.max_tx_chains_2g)
return false;
break;
case NSS_CHAINS_BAND_5GHZ:
if (rx_nss > chain_cfg.max_rx_chains_5g)
return false;
if (tx_nss > chain_cfg.max_tx_chains_5g)
return false;
break;
default:
sme_err("Unknown Band nss change not allowed");
return false;
}
return true;
}
static void sme_modify_chains_in_mlme_cfg(mac_handle_t mac_handle,
uint8_t rx_chains,
uint8_t tx_chains,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
{
uint8_t nss_shift;
uint32_t nss_mask = 0x7;
@ -4333,6 +4358,37 @@ sme_change_vdev_nss_ini(mac_handle_t mac_handle,
nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] &=
~(nss_mask << nss_shift);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] |=
(rx_chains << nss_shift);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] &=
~(nss_mask << nss_shift);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] |=
(tx_chains << nss_shift);
sme_debug("rx chains %d tx chains %d changed for vdev mode %d for band %d",
rx_chains, tx_chains, vdev_op_mode, band);
}
static void
sme_modify_nss_in_mlme_cfg(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
{
uint8_t nss_shift;
uint32_t nss_mask = 0x7;
struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
if (!sme_is_nss_update_allowed(mac_ctx->fw_chain_cfg, rx_nss, tx_nss,
band)) {
sme_debug("Nss modification failed, fw doesn't support this nss %d",
rx_nss);
return;
}
nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] &=
~(nss_mask << nss_shift);
mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] |=
@ -4346,10 +4402,73 @@ sme_change_vdev_nss_ini(mac_handle_t mac_handle,
}
void
sme_update_vdev_nss(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
{
uint8_t ini_rx_nss;
uint8_t ini_tx_nss;
uint8_t max_supported_rx_nss = MAX_VDEV_NSS;
uint8_t max_supported_tx_nss = MAX_VDEV_NSS;
uint8_t ini_rx_chains;
uint8_t ini_tx_chains;
uint8_t max_supported_rx_chains = MAX_VDEV_CHAINS;
uint8_t max_supported_tx_chains = MAX_VDEV_CHAINS;
struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
struct wlan_mlme_nss_chains *nss_chains_ini_cfg =
&mac_ctx->mlme_cfg->nss_chains_ini_cfg;
uint8_t nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
struct wlan_mlme_chain_cfg chain_cfg = mac_ctx->fw_chain_cfg;
ini_rx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->rx_nss[band],
nss_shift);
ini_tx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->tx_nss[band],
nss_shift);
if (band == NSS_CHAINS_BAND_2GHZ) {
max_supported_rx_nss = chain_cfg.max_rx_chains_2g;
max_supported_tx_nss = chain_cfg.max_tx_chains_2g;
} else if (band == NSS_CHAINS_BAND_5GHZ) {
max_supported_rx_nss = chain_cfg.max_rx_chains_5g;
max_supported_tx_nss = chain_cfg.max_tx_chains_5g;
}
max_supported_rx_nss = QDF_MIN(ini_rx_nss, max_supported_rx_nss);
max_supported_tx_nss = QDF_MIN(ini_tx_nss, max_supported_tx_nss);
ini_rx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->
num_rx_chains[band],
nss_shift);
ini_tx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->
num_tx_chains[band],
nss_shift);
if (band == NSS_CHAINS_BAND_2GHZ) {
max_supported_rx_chains = chain_cfg.max_rx_chains_2g;
max_supported_tx_chains = chain_cfg.max_tx_chains_2g;
} else if (band == NSS_CHAINS_BAND_5GHZ) {
max_supported_rx_chains = chain_cfg.max_rx_chains_5g;
max_supported_tx_chains = chain_cfg.max_tx_chains_5g;
}
max_supported_rx_chains = QDF_MIN(ini_rx_chains,
max_supported_rx_chains);
max_supported_tx_chains = QDF_MIN(ini_tx_chains,
max_supported_tx_chains);
sme_modify_chains_in_mlme_cfg(mac_handle, max_supported_rx_chains,
max_supported_tx_chains, vdev_op_mode,
band);
sme_modify_nss_in_mlme_cfg(mac_handle, max_supported_rx_nss,
max_supported_tx_nss, vdev_op_mode, band);
}
void
sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle,
uint8_t rx_nss, uint8_t tx_nss,
enum QDF_OPMODE vdev_op_mode,
enum nss_chains_band_info band)
{
/*
* If device mode is P2P-DEVICE, then we want P2P to come in that
@ -4361,15 +4480,15 @@ sme_update_vdev_nss(mac_handle_t mac_handle,
if (vdev_op_mode == QDF_P2P_DEVICE_MODE ||
vdev_op_mode == QDF_P2P_CLIENT_MODE ||
vdev_op_mode == QDF_P2P_GO_MODE) {
sme_change_vdev_nss_ini(mac_handle, rx_nss, tx_nss,
QDF_P2P_CLIENT_MODE, band);
sme_change_vdev_nss_ini(mac_handle, rx_nss, tx_nss,
QDF_P2P_GO_MODE, band);
sme_change_vdev_nss_ini(mac_handle, rx_nss, tx_nss,
QDF_P2P_DEVICE_MODE, band);
sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
QDF_P2P_CLIENT_MODE, band);
sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
QDF_P2P_GO_MODE, band);
sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
QDF_P2P_DEVICE_MODE, band);
} else
sme_change_vdev_nss_ini(mac_handle, rx_nss, tx_nss,
vdev_op_mode, band);
sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
vdev_op_mode, band);
}
QDF_STATUS

View File

@ -5555,6 +5555,59 @@ static void wma_update_nan_target_caps(tp_wma_handle wma_handle,
}
#endif
static uint8_t
wma_convert_chainmask_to_chain(uint8_t chainmask)
{
uint8_t num_chains = 0;
while (chainmask) {
chainmask &= (chainmask - 1);
num_chains++;
}
return num_chains;
}
static void
wma_fill_chain_cfg(struct target_psoc_info *tgt_hdl,
uint8_t phy)
{
struct mac_context *mac_ctx;
uint8_t num_chain;
struct wlan_psoc_host_mac_phy_caps *mac_phy_cap =
tgt_hdl->info.mac_phy_cap;
mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
if (!mac_ctx) {
WMA_LOGE("fill chain cfg failed as mac_ctx is NULL");
return;
}
num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
tx_chain_mask_2G);
if (num_chain > mac_ctx->fw_chain_cfg.max_tx_chains_2g)
mac_ctx->fw_chain_cfg.max_tx_chains_2g = num_chain;
num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
tx_chain_mask_5G);
if (num_chain > mac_ctx->fw_chain_cfg.max_tx_chains_5g)
mac_ctx->fw_chain_cfg.max_tx_chains_5g = num_chain;
num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
rx_chain_mask_2G);
if (num_chain > mac_ctx->fw_chain_cfg.max_rx_chains_2g)
mac_ctx->fw_chain_cfg.max_rx_chains_2g = num_chain;
num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
rx_chain_mask_5G);
if (num_chain > mac_ctx->fw_chain_cfg.max_rx_chains_5g)
mac_ctx->fw_chain_cfg.max_rx_chains_5g = num_chain;
}
/**
* wma_update_hdd_cfg() - update HDD config
* @wma_handle: wma handle
@ -5569,6 +5622,7 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
struct wlan_psoc_host_service_ext_param *service_ext_param;
struct target_psoc_info *tgt_hdl;
struct wmi_unified *wmi_handle;
uint8_t i;
WMA_LOGD("%s: Enter", __func__);
@ -5648,6 +5702,11 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
wma_update_obss_color_collision_support(wma_handle, &tgt_cfg);
wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg);
wma_update_nan_target_caps(wma_handle, &tgt_cfg);
/* Take the max of chains supported by FW, which will limit nss */
for (i = 0; i < tgt_hdl->info.total_mac_phy_cnt; i++)
wma_fill_chain_cfg(tgt_hdl, i);
wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg);
target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle);
target_pdev_set_wmi_handle(wma_handle->pdev->tgt_if_handle,