qcacld-3.0: Set TX & RX NSS separately using vendor_attr
The vendor command QCA_WLAN_VENDOR_ATTR_CONFIG_NSS can only be used to symmetricly set NSS configuration such as 1x1 or 2x2. So, use QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes to configure the asymmetric NSS configuration (such as 1X2). These attributes are used to dynamically configure the number of spatial streams used for transmitting and receiving the data. When configured in the disconnected state, the configured value will be considered for the following connection attempt. If the NSS is updated after the connection, the updated NSS value is notified to the peer using the Operating Mode Notification/Spatial Multiplexing Power Save frame. The value configured after the connection shall not be greater than the value negotiated during the connection. Any such higher value configuration shall be treated as invalid configuration by the driver. These attribute shall be configured together to define the symmetric configuration (such as 2X2 or 1X1) or the asymmetric configuration (such as 1X2). If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along with these attributes then the driver will update the TX and RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS. Change-Id: I85adb1fcfb2df5cf42eabd4f18b403b698767f42 CRs-Fixed: 2831416
This commit is contained in:

committato da
snandini

parent
92b7ee1b34
commit
7118d2fbb1
@@ -318,7 +318,8 @@ void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx);
|
||||
* hdd_update_nss() - Update the number of spatial streams supported.
|
||||
*
|
||||
* @adapter: the pointer to adapter
|
||||
* @nss: the number of spatial streams to be updated
|
||||
* @tx_nss: the number of Tx spatial streams to be updated
|
||||
* @rx_nss: the number of Rx spatial streams to be updated
|
||||
*
|
||||
* This function is used to modify the number of spatial streams
|
||||
* supported when not in connected state.
|
||||
@@ -326,7 +327,8 @@ void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx);
|
||||
* Return: QDF_STATUS_SUCCESS if nss is correctly updated,
|
||||
* otherwise QDF_STATUS_E_FAILURE would be returned
|
||||
*/
|
||||
QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss);
|
||||
QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t tx_nss,
|
||||
uint8_t rx_nss);
|
||||
|
||||
/**
|
||||
* hdd_get_nss() - Get the number of spatial streams supported by the adapter
|
||||
|
@@ -1063,7 +1063,8 @@ hdd_set_nss_params(struct hdd_adapter *adapter,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
|
||||
QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t tx_nss,
|
||||
uint8_t rx_nss)
|
||||
{
|
||||
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
uint32_t rx_supp_data_rate, tx_supp_data_rate;
|
||||
@@ -1076,16 +1077,16 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
|
||||
uint8_t enable2x2;
|
||||
mac_handle_t mac_handle;
|
||||
bool bval = 0;
|
||||
uint8_t tx_nss, rx_nss;
|
||||
uint8_t band, max_supp_nss;
|
||||
|
||||
if ((nss == 2) && (hdd_ctx->num_rf_chains != 2)) {
|
||||
if ((tx_nss == 2 || rx_nss == 2) && (hdd_ctx->num_rf_chains != 2)) {
|
||||
hdd_err("No support for 2 spatial streams");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (nss > MAX_VDEV_NSS) {
|
||||
hdd_debug("Cannot support %d nss streams", nss);
|
||||
if (tx_nss > MAX_VDEV_NSS || rx_nss > MAX_VDEV_NSS) {
|
||||
hdd_debug("Cannot support tx_nss: %d rx_nss: %d", tx_nss,
|
||||
rx_nss);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
@@ -1102,10 +1103,6 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
|
||||
}
|
||||
max_supp_nss = MAX_VDEV_NSS;
|
||||
|
||||
/* Till now we dont have support for different rx, tx nss values */
|
||||
tx_nss = nss;
|
||||
rx_nss = nss;
|
||||
|
||||
/*
|
||||
* If FW is supporting the dynamic nss update, this command is meant to
|
||||
* be per vdev, so update only the ini params of that particular vdev
|
||||
@@ -1147,7 +1144,7 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
|
||||
* update of nss and chains per vdev feature, for the upcoming
|
||||
* connection
|
||||
*/
|
||||
enable2x2 = (nss == 1) ? 0 : 1;
|
||||
enable2x2 = (rx_nss == 2) ? 1 : 0;
|
||||
|
||||
if (bval == enable2x2) {
|
||||
hdd_debug("NSS same as requested");
|
||||
@@ -1165,14 +1162,18 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!enable2x2) {
|
||||
/* 1x1 */
|
||||
rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
|
||||
if (tx_nss == 1 && rx_nss == 2) {
|
||||
/* 1x2 */
|
||||
rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
|
||||
tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
|
||||
} else {
|
||||
} else if (enable2x2) {
|
||||
/* 2x2 */
|
||||
rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
|
||||
tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
|
||||
} else {
|
||||
/* 1x1 */
|
||||
rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
|
||||
tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
|
||||
}
|
||||
|
||||
/* Update Rx Highest Long GI data Rate */
|
||||
@@ -1228,7 +1229,7 @@ skip_ht_cap_update:
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
mcs_set[0] = mcs_set_temp[0];
|
||||
if (enable2x2)
|
||||
for (val_len = 0; val_len < nss; val_len++)
|
||||
for (val_len = 0; val_len < rx_nss; val_len++)
|
||||
mcs_set[val_len] =
|
||||
WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
|
||||
if (ucfg_mlme_set_supported_mcs_set(
|
||||
@@ -1242,10 +1243,10 @@ skip_ht_cap_update:
|
||||
status = false;
|
||||
hdd_err("Could not get MCS SET from CFG");
|
||||
}
|
||||
sme_update_he_cap_nss(mac_handle, adapter->vdev_id, nss);
|
||||
sme_update_he_cap_nss(mac_handle, adapter->vdev_id, rx_nss);
|
||||
#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
|
||||
|
||||
if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, nss))
|
||||
if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, rx_nss))
|
||||
status = false;
|
||||
|
||||
hdd_set_policy_mgr_user_cfg(hdd_ctx);
|
||||
|
@@ -6979,6 +6979,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_SETTING] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL] = {.type = NLA_S32 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 },
|
||||
|
||||
};
|
||||
|
||||
@@ -7697,6 +7699,37 @@ static int hdd_config_vdev_chains(struct hdd_adapter *adapter,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdd_config_tx_rx_nss(struct hdd_adapter *adapter,
|
||||
struct nlattr *tb[])
|
||||
{
|
||||
uint8_t tx_nss, rx_nss;
|
||||
QDF_STATUS status;
|
||||
|
||||
struct nlattr *tx_attr =
|
||||
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS];
|
||||
struct nlattr *rx_attr =
|
||||
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS];
|
||||
|
||||
if (!tx_attr && !rx_attr)
|
||||
return 0;
|
||||
|
||||
tx_nss = nla_get_u8(tx_attr);
|
||||
rx_nss = nla_get_u8(rx_attr);
|
||||
hdd_debug("tx_nss %d rx_nss %d", tx_nss, rx_nss);
|
||||
/* Only allow NSS for tx_rx_nss for 1x1, 1x2, 2x2 */
|
||||
if (!((tx_nss == 1 && rx_nss == 2) || (tx_nss == 1 && rx_nss == 1) ||
|
||||
(tx_nss == 2 && rx_nss == 2))) {
|
||||
hdd_err("Setting tx_nss %d rx_nss %d not allowed", tx_nss,
|
||||
rx_nss);
|
||||
return 0;
|
||||
}
|
||||
status = hdd_update_nss(adapter, tx_nss, rx_nss);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
hdd_debug("Can't set tx_nss %d rx_nss %d", tx_nss, rx_nss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdd_config_ani(struct hdd_adapter *adapter,
|
||||
struct nlattr *tb[])
|
||||
{
|
||||
@@ -8740,7 +8773,7 @@ static int hdd_set_nss(struct hdd_adapter *adapter,
|
||||
|
||||
nss = nla_get_u8(attr);
|
||||
|
||||
status = hdd_update_nss(adapter, nss);
|
||||
status = hdd_update_nss(adapter, nss, nss);
|
||||
ret = qdf_status_to_os_return(status);
|
||||
|
||||
if (ret == 0 && adapter->device_mode == QDF_SAP_MODE)
|
||||
@@ -9458,6 +9491,7 @@ static const interdependent_setter_fn interdependent_setters[] = {
|
||||
hdd_config_msdu_aggregation,
|
||||
hdd_config_vdev_chains,
|
||||
hdd_config_ani,
|
||||
hdd_config_tx_rx_nss,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -899,7 +899,7 @@ static __iw_softap_setparam(struct net_device *dev,
|
||||
case QCASAP_NSS_CMD:
|
||||
{
|
||||
hdd_debug("QCASAP_NSS_CMD val %d", set_value);
|
||||
hdd_update_nss(adapter, set_value);
|
||||
hdd_update_nss(adapter, set_value, set_value);
|
||||
ret = wma_cli_set_command(adapter->vdev_id,
|
||||
WMI_VDEV_PARAM_NSS,
|
||||
set_value, VDEV_CMD);
|
||||
|
@@ -3918,7 +3918,7 @@ static int hdd_we_set_nss(struct hdd_adapter *adapter, int nss)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = hdd_update_nss(adapter, nss);
|
||||
status = hdd_update_nss(adapter, nss, nss);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("cfg set failed, value %d status %d", nss, status);
|
||||
|
||||
|
@@ -11270,7 +11270,8 @@ void sme_update_he_cap_nss(mac_handle_t mac_handle, uint8_t session_id,
|
||||
uint32_t mcs_map = 0;
|
||||
|
||||
if (!nss || (nss > 2)) {
|
||||
sme_err("invalid Nss value %d", nss);
|
||||
sme_err("invalid Nss value nss %d", nss);
|
||||
return;
|
||||
}
|
||||
csr_session = CSR_GET_SESSION(mac_ctx, session_id);
|
||||
if (!csr_session) {
|
||||
|
Fai riferimento in un nuovo problema
Block a user