qcacld-3.0: config 11ax linkspeed rate

This change is to support 11ax linkspeed rate
on UI.

It supports different config for gReportMaxLinkSpeed.

Current 11ax rate support to max 80 nss2 mcs11.

Change-Id: Iff8cbafe1354ab50c4b3a90ef8ab698a3350a21d
CRs-Fixed: 2529291
This commit is contained in:
Jingxiang Ge 2019-10-20 12:03:22 +08:00 • committed by nshrivas
commit f1d8159208
16 changed files with 639 additions and 257 deletions

View file

@ -815,7 +815,7 @@ struct hdd_rate_info {
uint8_t mode;
uint8_t nss;
uint8_t mcs;
uint8_t rate_flags;
enum tx_rate_info rate_flags;
};
/**

View file

@ -372,7 +372,8 @@ static void hdd_get_max_tx_bitrate(struct hdd_context *hdd_ctx,
struct hdd_adapter *adapter)
{
struct station_info sinfo;
uint8_t tx_rate_flags, tx_mcs_index, tx_nss = 1;
enum tx_rate_info tx_rate_flags;
uint8_t tx_mcs_index, tx_nss = 1;
uint16_t my_tx_rate;
struct hdd_station_ctx *hdd_sta_ctx;

View file

@ -162,15 +162,14 @@ static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
{9, {7800, 8667}, {3600, 4000}, {1730, 1920} }
};
/*array index ponints to MCS and array value points respective rssi*/
static int rssi_mcs_tbl[][10] = {
/*MCS 0 1 2 3 4 5 6 7 8 9*/
{-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, /* 20 */
{-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, /* 40 */
{-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} /* 80 */
/*array index points to MCS and array value points respective rssi*/
static int rssi_mcs_tbl[][12] = {
/* MCS 0 1 2 3 4 5 6 7 8 9 10 11*/
{-82, -79, -77, -74, -70, -66, -65, -64, -59, -57, -52, -48}, /* 20 */
{-79, -76, -74, -71, -67, -63, -62, -61, -56, -54, -49, -45}, /* 40 */
{-76, -73, -71, -68, -64, -60, -59, -58, -53, -51, -46, -42} /* 80 */
};
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
/**
@ -3346,7 +3345,7 @@ static void hdd_get_max_rate_vht(struct hdd_station_info *stainfo,
* Return: None
*/
static void hdd_fill_bw_mcs(struct station_info *sinfo,
uint8_t rate_flags,
enum tx_rate_info rate_flags,
uint8_t mcsidx,
uint8_t nss,
bool vht)
@ -3383,7 +3382,7 @@ static void hdd_fill_bw_mcs(struct station_info *sinfo,
* Return: None
*/
static void hdd_fill_bw_mcs(struct station_info *sinfo,
uint8_t rate_flags,
enum tx_rate_info rate_flags,
uint8_t mcsidx,
uint8_t nss,
bool vht)
@ -3420,7 +3419,7 @@ static void hdd_fill_bw_mcs(struct station_info *sinfo,
* Return: None
*/
static void hdd_fill_bw_mcs_vht(struct station_info *sinfo,
uint8_t rate_flags,
enum tx_rate_info rate_flags,
uint8_t mcsidx,
uint8_t nss)
{
@ -3513,7 +3512,7 @@ static void hdd_fill_rate_info(struct wlan_objmgr_psoc *psoc,
struct hdd_station_info *stainfo,
struct hdd_fw_txrx_stats *stats)
{
uint8_t rate_flags;
enum tx_rate_info rate_flags;
uint8_t mcsidx = 0xff;
uint32_t myrate, maxrate, tmprate;
int rssidx;
@ -3943,10 +3942,121 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
return status;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \
defined(WLAN_FEATURE_11AX)
/**
* hdd_map_he_gi_to_os() - map txrate_gi to os guard interval
* @guard_interval: guard interval get from fw rate
*
* Return: os guard interval value
*/
static inline uint8_t hdd_map_he_gi_to_os(enum txrate_gi guard_interval)
{
switch (guard_interval) {
case TXRATE_GI_0_8_US:
return NL80211_RATE_INFO_HE_GI_0_8;
case TXRATE_GI_1_6_US:
return NL80211_RATE_INFO_HE_GI_1_6;
case TXRATE_GI_3_2_US:
return NL80211_RATE_INFO_HE_GI_3_2;
default:
return NL80211_RATE_INFO_HE_GI_0_8;
}
}
/**
* wlan_hdd_fill_os_he_rateflags() - Fill HE related rate_info
* @os_rate: rate info for os
* @rate_flags: rate flags
* @dcm: dcm from rate
* @guard_interval: guard interval from rate
*
* Return: none
*/
static void wlan_hdd_fill_os_he_rateflags(struct rate_info *os_rate,
enum tx_rate_info rate_flags,
uint8_t dcm,
enum txrate_gi guard_interval)
{
/* as fw not yet report ofdma to host, so we doesn't
* fill RATE_INFO_BW_HE_RU.
*/
if (rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 |
TX_RATE_HE20)) {
if (rate_flags & TX_RATE_HE80)
hdd_set_rate_bw(os_rate, HDD_RATE_BW_80);
else if (rate_flags & TX_RATE_HE40)
hdd_set_rate_bw(os_rate, HDD_RATE_BW_40);
os_rate->flags |= RATE_INFO_FLAGS_HE_MCS;
os_rate->he_gi = hdd_map_he_gi_to_os(guard_interval);
os_rate->he_dcm = dcm;
}
}
#else
static void wlan_hdd_fill_os_he_rateflags(struct rate_info *os_rate,
enum tx_rate_info rate_flags,
uint8_t dcm,
enum txrate_gi guard_interval)
{}
#endif
/**
* wlan_hdd_fill_os_rate_info() - Fill os related rate_info
* @rate_flags: rate flags
* @legacy_rate: 802.11abg rate
* @os_rate: rate info for os
* @mcs_index: mcs
* @dcm: dcm from rate
* @guard_interval: guard interval from rate
*
* Return: none
*/
static void wlan_hdd_fill_os_rate_info(enum tx_rate_info rate_flags,
uint16_t legacy_rate,
struct rate_info *os_rate,
uint8_t mcs_index, uint8_t nss,
uint8_t dcm,
enum txrate_gi guard_interval)
{
if (rate_flags & TX_RATE_LEGACY) {
os_rate->legacy = legacy_rate;
hdd_debug("Reporting legacy rate %d", os_rate->legacy);
return;
}
/* assume basic BW. anything else will override this later */
hdd_set_rate_bw(os_rate, HDD_RATE_BW_20);
os_rate->mcs = mcs_index;
os_rate->nss = nss;
wlan_hdd_fill_os_he_rateflags(os_rate, rate_flags, dcm, guard_interval);
if (rate_flags & (TX_RATE_VHT80 | TX_RATE_VHT40 |
TX_RATE_VHT20)) {
if (rate_flags & TX_RATE_VHT80)
hdd_set_rate_bw(os_rate, HDD_RATE_BW_80);
else if (rate_flags & TX_RATE_VHT40)
hdd_set_rate_bw(os_rate, HDD_RATE_BW_40);
os_rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
}
if (rate_flags & (TX_RATE_HT20 | TX_RATE_HT40)) {
if (rate_flags & TX_RATE_HT40)
hdd_set_rate_bw(os_rate,
HDD_RATE_BW_40);
os_rate->flags |= RATE_INFO_FLAGS_MCS;
}
if (rate_flags & TX_RATE_SGI)
os_rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
bool hdd_report_max_rate(mac_handle_t mac_handle,
struct rate_info *rate,
int8_t signal,
uint8_t rate_flags,
enum tx_rate_info rate_flags,
uint8_t mcs_index,
uint16_t fw_rate, uint8_t nss)
{
@ -3961,10 +4071,8 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
qdf_size_t er_leng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
uint8_t mcs_rates[SIZE_OF_BASIC_MCS_SET];
qdf_size_t mcs_leng = SIZE_OF_BASIC_MCS_SET;
struct index_vht_data_rate_type *supported_vht_mcs_rate;
struct index_data_rate_type *supported_mcs_rate;
enum data_rate_11ac_max_mcs vht_max_mcs;
uint8_t max_speed_mcs = 0;
uint8_t max_mcs_idx = 0;
uint8_t rate_flag = 1;
int mode = 0, max_ht_idx;
@ -4065,7 +4173,6 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
* Only if we are connected in non legacy mode and not reporting
* actual speed
*/
if ((3 != rssidx) && !(rate_flags & TX_RATE_LEGACY)) {
if (0 != ucfg_mlme_get_current_mcs_set(hdd_ctx->psoc,
mcs_rates,
@ -4075,22 +4182,18 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
return false;
}
rate_flag = 0;
supported_vht_mcs_rate = (struct index_vht_data_rate_type *)
((nss == 1) ?
&supported_vht_mcs_rate_nss1 :
&supported_vht_mcs_rate_nss2);
if (rate_flags & TX_RATE_VHT80)
if (rate_flags & (TX_RATE_VHT80 | TX_RATE_HE80))
mode = 2;
else if ((rate_flags & TX_RATE_VHT40) ||
(rate_flags & TX_RATE_HT40))
else if (rate_flags & (TX_RATE_HT40 |
TX_RATE_VHT40 | TX_RATE_HE40))
mode = 1;
else
mode = 0;
/* VHT80 rate has separate rate table */
if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 |
TX_RATE_VHT80)) {
TX_RATE_VHT80 | TX_RATE_HE20 | TX_RATE_HE40 |
TX_RATE_HE80)) {
stat = ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc,
&vht_mcs_map);
if (QDF_IS_STATUS_ERROR(stat))
@ -4123,6 +4226,10 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
max_mcs_idx = 9;
}
if (rate_flags & (TX_RATE_HE20 | TX_RATE_HE40 |
TX_RATE_HE80))
max_mcs_idx = 11;
if (rssidx != 0) {
for (i = 0; i <= max_mcs_idx; i++) {
if (signal <= rssi_mcs_tbl[mode][i]) {
@ -4132,33 +4239,8 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
}
}
if (rate_flags & TX_RATE_VHT80) {
current_rate =
supported_vht_mcs_rate[mcs_index].
supported_VHT80_rate[rate_flag];
max_rate =
supported_vht_mcs_rate[max_mcs_idx].
supported_VHT80_rate[rate_flag];
} else if (rate_flags & TX_RATE_VHT40) {
current_rate =
supported_vht_mcs_rate[mcs_index].
supported_VHT40_rate[rate_flag];
max_rate =
supported_vht_mcs_rate[max_mcs_idx].
supported_VHT40_rate[rate_flag];
} else if (rate_flags & TX_RATE_VHT20) {
current_rate =
supported_vht_mcs_rate[mcs_index].
supported_VHT20_rate[rate_flag];
max_rate =
supported_vht_mcs_rate[max_mcs_idx].
supported_VHT20_rate[rate_flag];
}
max_speed_mcs = 1;
if (current_rate > max_rate)
max_rate = current_rate;
max_mcs_idx = (max_mcs_idx > mcs_index) ?
max_mcs_idx : mcs_index;
} else {
if (rate_flags & TX_RATE_HT40)
rate_flag |= 1;
@ -4197,67 +4279,28 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
}
if ((j < MAX_HT_MCS_IDX) &&
(current_rate > max_rate)) {
(current_rate > max_rate))
max_rate = current_rate;
}
max_speed_mcs = 1;
}
if (nss == 2)
max_mcs_idx += MAX_HT_MCS_IDX;
max_mcs_idx = (max_mcs_idx > mcs_index) ?
max_mcs_idx : mcs_index;
}
}
else if (!(rate_flags & TX_RATE_LEGACY)) {
max_rate = fw_rate;
max_speed_mcs = 1;
max_mcs_idx = mcs_index;
}
/* report a value at least as big as current rate */
if ((max_rate < fw_rate) || (0 == max_rate)) {
max_rate = fw_rate;
if (rate_flags & TX_RATE_LEGACY) {
max_speed_mcs = 0;
} else {
max_speed_mcs = 1;
max_mcs_idx = mcs_index;
}
}
if (rate_flags & TX_RATE_LEGACY) {
rate->legacy = max_rate;
hdd_info("Reporting legacy rate %d", rate->legacy);
} else {
rate->mcs = max_mcs_idx;
rate->nss = nss;
if (rate_flags & TX_RATE_VHT80)
hdd_set_rate_bw(rate, HDD_RATE_BW_80);
else if (rate_flags & TX_RATE_VHT40)
hdd_set_rate_bw(rate, HDD_RATE_BW_40);
else if (rate_flags & TX_RATE_VHT20)
hdd_set_rate_bw(rate, HDD_RATE_BW_20);
if (rate_flags &
(TX_RATE_HT20 | TX_RATE_HT40)) {
rate->flags |= RATE_INFO_FLAGS_MCS;
if (rate_flags & TX_RATE_HT40)
hdd_set_rate_bw(rate,
HDD_RATE_BW_40);
else if (rate_flags & TX_RATE_HT20)
hdd_set_rate_bw(rate,
HDD_RATE_BW_20);
} else {
rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
}
if (rate_flags & TX_RATE_SGI) {
if (!(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
rate->flags |= RATE_INFO_FLAGS_MCS;
rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
linkspeed_dbg("Reporting MCS rate %d flags %x\n",
rate->mcs, rate->flags);
}
wlan_hdd_fill_os_rate_info(rate_flags, max_rate, rate,
max_mcs_idx, nss, 0, 0);
return true;
}
@ -4268,48 +4311,22 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
* @rate_flags: The rate flags computed from rate
* @my_rate: The rate from fw stats
* @rate: The station_info struct member strust rate_info to be filled
* @mcs_index; The mcs index computed from rate
* @mcs_index: The mcs index computed from rate
* @nss: The NSS from fw stats
* @dcm: the dcm computed from rate
* @guard_interval: the guard interval computed from rate
*
* Return: None
*/
static void hdd_report_actual_rate(uint8_t rate_flags, uint16_t my_rate,
static void hdd_report_actual_rate(enum tx_rate_info rate_flags,
uint16_t my_rate,
struct rate_info *rate, uint8_t mcs_index,
uint8_t nss)
uint8_t nss, uint8_t dcm,
enum txrate_gi guard_interval)
{
/* report current rate instead of max rate */
if (rate_flags & TX_RATE_LEGACY) {
/* provide to the UI in units of 100kbps */
rate->legacy = my_rate;
linkspeed_dbg("Reporting actual legacy rate %d",
rate->legacy);
} else {
/* must be MCS */
rate->mcs = mcs_index;
rate->nss = nss;
if (rate_flags & TX_RATE_VHT80)
hdd_set_rate_bw(rate, HDD_RATE_BW_80);
else if (rate_flags & TX_RATE_VHT40)
hdd_set_rate_bw(rate, HDD_RATE_BW_40);
if (rate_flags &
(TX_RATE_HT20 | TX_RATE_HT40)) {
rate->flags |= RATE_INFO_FLAGS_MCS;
if (rate_flags & TX_RATE_HT40)
hdd_set_rate_bw(rate, HDD_RATE_BW_40);
} else {
rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
}
if (rate_flags & TX_RATE_SGI) {
rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
linkspeed_dbg("Reporting actual MCS rate %d flags %x\n",
rate->mcs, rate->flags);
}
wlan_hdd_fill_os_rate_info(rate_flags, my_rate, rate,
mcs_index, nss, dcm, guard_interval);
}
/**
@ -4395,13 +4412,14 @@ static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
struct station_info *sinfo)
{
struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
uint8_t rate_flags, tx_rate_flags, rx_rate_flags;
enum tx_rate_info rate_flags, tx_rate_flags, rx_rate_flags;
uint8_t tx_mcs_index, rx_mcs_index;
struct hdd_context *hdd_ctx = (struct hdd_context *) wiphy_priv(wiphy);
mac_handle_t mac_handle;
int8_t snr = 0;
uint16_t my_tx_rate, my_rx_rate;
uint8_t tx_nss = 1, rx_nss = 1;
uint8_t tx_nss = 1, rx_nss = 1, tx_dcm, rx_dcm;
enum txrate_gi tx_gi, rx_gi;
int32_t rcpi_value;
int link_speed_rssi_high = 0;
int link_speed_rssi_mid = 0;
@ -4482,6 +4500,11 @@ static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
my_tx_rate = adapter->hdd_stats.class_a_stat.tx_rate;
my_rx_rate = adapter->hdd_stats.class_a_stat.rx_rate;
tx_dcm = adapter->hdd_stats.class_a_stat.tx_dcm;
rx_dcm = adapter->hdd_stats.class_a_stat.rx_dcm;
tx_gi = adapter->hdd_stats.class_a_stat.tx_gi;
rx_gi = adapter->hdd_stats.class_a_stat.rx_gi;
if (!(rate_flags & TX_RATE_LEGACY)) {
tx_nss = adapter->hdd_stats.class_a_stat.tx_nss;
rx_nss = adapter->hdd_stats.class_a_stat.rx_nss;
@ -4535,9 +4558,8 @@ static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
hdd_debug("MCS Index: TX: %d, RX: %d", (int)tx_mcs_index,
(int)rx_mcs_index);
hdd_debug("NSS: TX: %d, RX: %d", (int)tx_nss, (int)rx_nss);
/* assume basic BW. anything else will override this later */
hdd_set_rate_bw(&sinfo->txrate, HDD_RATE_BW_20);
hdd_debug("dcm: TX: %d, RX: %d", (int)tx_dcm, (int)rx_dcm);
hdd_debug("guard interval: TX: %d, RX: %d", (int)tx_gi, (int)rx_gi);
if (!ucfg_mlme_stats_is_link_speed_report_actual(hdd_ctx->psoc)) {
bool tx_rate_calc;
@ -4566,11 +4588,14 @@ static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
/* Fill TX stats */
hdd_report_actual_rate(tx_rate_flags, my_tx_rate,
&sinfo->txrate, tx_mcs_index, tx_nss);
&sinfo->txrate, tx_mcs_index,
tx_nss, tx_dcm, tx_gi);
/* Fill RX stats */
hdd_report_actual_rate(rx_rate_flags, my_rx_rate,
&sinfo->rxrate, rx_mcs_index, rx_nss);
&sinfo->rxrate, rx_mcs_index,
rx_nss, rx_dcm, rx_gi);
}
wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, sinfo);
@ -4594,14 +4619,21 @@ static int wlan_hdd_get_sta_stats(struct wiphy *wiphy,
HDD_INFO_RX_BYTES |
HDD_INFO_RX_PACKETS;
if (tx_rate_flags & TX_RATE_LEGACY)
hdd_debug("Reporting legacy rate %d pkt cnt tx %d rx %d",
sinfo->txrate.legacy, sinfo->tx_packets,
sinfo->rx_packets);
else
hdd_debug("Reporting MCS rate %d flags 0x%x pkt cnt tx %d rx %d",
sinfo->txrate.mcs, sinfo->txrate.flags,
sinfo->tx_packets, sinfo->rx_packets);
if (tx_rate_flags & TX_RATE_LEGACY) {
hdd_debug("TX: Reporting legacy rate %d pkt cnt %d",
sinfo->txrate.legacy, sinfo->tx_packets);
hdd_debug("RX: Reporting legacy rate %d pkt cnt %d",
sinfo->rxrate.legacy, sinfo->rx_packets);
} else {
hdd_debug("TX: Reporting MCS rate %d, flags 0x%x pkt cnt %d, nss %d, bw %d",
sinfo->txrate.mcs, sinfo->txrate.flags,
sinfo->tx_packets, sinfo->txrate.nss,
sinfo->rxrate.bw);
hdd_debug("RX: Reporting MCS rate %d, flags 0x%x pkt cnt %d, nss %d, bw %d",
sinfo->rxrate.mcs, sinfo->rxrate.flags,
sinfo->rx_packets, sinfo->rxrate.nss,
sinfo->rxrate.bw);
}
hdd_wlan_fill_per_chain_rssi_stats(sinfo, adapter);
@ -5631,7 +5663,6 @@ int wlan_hdd_get_peer_info(struct hdd_adapter *adapter,
int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
{
int ret = 0;
uint8_t mcs_rate_flags;
struct stats_event *stats;
stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->vdev,
@ -5690,13 +5721,18 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
adapter->hdd_stats.class_a_stat.tx_mcs_index =
sme_get_mcs_idx(stats->tx_rate, stats->tx_rate_flags,
&adapter->hdd_stats.class_a_stat.tx_nss,
&mcs_rate_flags);
adapter->hdd_stats.class_a_stat.tx_mcs_rate_flags = mcs_rate_flags;
&adapter->hdd_stats.class_a_stat.tx_dcm,
&adapter->hdd_stats.class_a_stat.tx_gi,
&adapter->hdd_stats.class_a_stat.
tx_mcs_rate_flags);
adapter->hdd_stats.class_a_stat.rx_mcs_index =
sme_get_mcs_idx(stats->rx_rate, stats->tx_rate_flags,
&adapter->hdd_stats.class_a_stat.rx_nss,
&mcs_rate_flags);
adapter->hdd_stats.class_a_stat.rx_mcs_rate_flags = mcs_rate_flags;
&adapter->hdd_stats.class_a_stat.rx_dcm,
&adapter->hdd_stats.class_a_stat.rx_gi,
&adapter->hdd_stats.class_a_stat.
rx_mcs_rate_flags);
/* save per chain rssi to legacy location */
qdf_mem_copy(adapter->hdd_stats.per_chain_rssi_stats.rssi,

View file

@ -457,7 +457,7 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *hdd_ctx);
bool hdd_report_max_rate(mac_handle_t mac_handle,
struct rate_info *rate,
int8_t signal,
uint8_t rate_flags,
enum tx_rate_info rate_flags,
uint8_t mcs_index,
uint16_t fw_rate, uint8_t nss);

View file

@ -4092,8 +4092,10 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac,
}
if (lim_is_session_he_capable(pe_session) &&
pBeaconStruct->he_cap.present)
pBeaconStruct->he_cap.present) {
lim_update_bss_he_capable(mac, pAddBssParams);
lim_add_bss_he_cfg(pAddBssParams, pe_session);
}
pe_debug("vhtCapable %d ch_width %d", pAddBssParams->vhtCapable,
pAddBssParams->ch_width);
/*

View file

@ -6717,6 +6717,7 @@ void lim_add_bss_he_cap(struct bss_params *add_bss, tpSirAssocRsp assoc_rsp)
he_cap = &assoc_rsp->he_cap;
he_op = &assoc_rsp->he_op;
add_bss->he_capable = he_cap->present;
if (he_cap)
qdf_mem_copy(&add_bss->staContext.he_config,
he_cap, sizeof(*he_cap));
@ -7124,6 +7125,13 @@ void lim_update_sta_he_capable(struct mac_context *mac,
pe_debug("he_capable: %d", add_sta_params->he_capable);
}
void lim_update_bss_he_capable(struct mac_context *mac,
struct bss_params *add_bss)
{
add_bss->he_capable = true;
pe_debug("he_capable: %d", add_bss->he_capable);
}
void lim_update_stads_he_capable(tpDphHashNode sta_ds, tpSirAssocReq assoc_req)
{
sta_ds->mlmStaContext.he_capable = assoc_req->he_cap.present;

View file

@ -1137,6 +1137,16 @@ static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds)
return sta_ds->mlmStaContext.he_capable;
}
/**
* lim_update_bss_he_capable() - Update he_capable in add BSS params
* @mac: pointer to MAC context
* @add_bss: pointer to add BSS params
*
* Return: None
*/
void lim_update_bss_he_capable(struct mac_context *mac,
struct bss_params *add_bss);
/**
* lim_update_stads_he_capable() - Update he_capable in sta ds context
* @sta_ds: pointer to sta ds
@ -1290,6 +1300,11 @@ static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds)
return false;
}
static inline void lim_update_bss_he_capable(struct mac_context *mac,
struct bss_params *add_bss)
{
}
static inline void lim_update_stads_he_capable(tpDphHashNode sta_ds,
tpSirAssocReq assoc_req)
{

View file

@ -1197,10 +1197,14 @@ typedef struct tagCsrGlobalClassAStatsInfo {
/* mcs index for HT20 and HT40 rates */
uint32_t tx_mcs_index;
uint32_t rx_mcs_index;
uint32_t tx_mcs_rate_flags;
uint32_t rx_mcs_rate_flags;
enum tx_rate_info tx_mcs_rate_flags;
enum tx_rate_info rx_mcs_rate_flags;
uint8_t tx_dcm;
uint8_t rx_dcm;
enum txrate_gi tx_gi;
enum txrate_gi rx_gi;
/* to diff between HT20 & HT40 rates;short & long guard interval */
uint32_t tx_rx_rate_flags;
enum tx_rate_info tx_rx_rate_flags;
} tCsrGlobalClassAStatsInfo;

View file

@ -3377,15 +3377,19 @@ static inline void sme_reset_he_caps(mac_handle_t mac_handle, uint8_t vdev_id)
/**
* sme_get_mcs_idx() - gets mcs index
* @max_rate: max rate
* @raw_rate: raw rate from fw
* @rate_flags: rate flags
* @nss: number of nss
* @dcm: dcm will be calculated from rate
* @guard_interval: guard interval info from rate
* @mcs_rate_flags: mcs rate flag
*
* Return: return mcs index
*/
uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
uint8_t *nss, uint8_t *mcs_rate_flags);
uint8_t sme_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flags);
#ifdef WLAN_SUPPORT_TWT
/**

View file

@ -15318,10 +15318,13 @@ void sme_reset_he_caps(mac_handle_t mac_handle, uint8_t vdev_id)
}
#endif
uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
uint8_t *nss, uint8_t *mcs_rate_flags)
uint8_t sme_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flags)
{
return wma_get_mcs_idx(max_rate, rate_flags, nss, mcs_rate_flags);
return wma_get_mcs_idx(raw_rate, rate_flags,
nss, dcm, guard_interval, mcs_rate_flags);
}
bool sme_find_session_by_bssid(mac_handle_t mac_handle, uint8_t *bssid)

View file

@ -768,6 +768,7 @@ struct wma_txrx_node {
void *del_staself_req;
bool is_del_sta_defered;
qdf_atomic_t bss_status;
enum tx_rate_info rate_flags;
uint8_t nss;
uint16_t pause_bitmap;
int8_t tx_power;

View file

@ -450,15 +450,19 @@ void wma_wmi_stop(void);
/**
* wma_get_mcs_idx() - get mcs index
* @max_rate: max rate
* @raw_rate: raw rate from fw
* @rate_flags: rate flags
* @nss: nss
* @dcm: dcm
* @guard_interval: guard interval
* @mcs_rate_flag: mcs rate flags
*
* Return: mcs index
*/
uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
uint8_t *nss, uint8_t *mcs_rate_flag);
uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flag);
/**
* wma_get_hidden_ssid_restart_in_progress() - check if hidden ssid restart is

View file

@ -342,6 +342,7 @@ typedef struct sLimMlmSetKeysReq {
* @bSpectrumMgtEnabled: Spectrum Management Capability, 1:Enabled, 0:Disabled.
* @vhtCapable: VHT capablity
* @ch_width: VHT tx channel width
* @he_capable: HE Capability
* @no_ptk_4_way: Do not need 4-way handshake
*/
struct bss_params {
@ -368,6 +369,7 @@ struct bss_params {
enum phy_ch_width ch_width;
uint8_t nonRoamReassoc;
#ifdef WLAN_FEATURE_11AX
bool he_capable;
uint32_t he_sta_obsspd;
#endif
bool no_ptk_4_way;

View file

@ -57,8 +57,15 @@
#define MAX_HT_MCS_IDX 8
#define MAX_VHT_MCS_IDX 10
#ifdef WLAN_FEATURE_11AX
#define MAX_HE_MCS_IDX 12
#endif
#define INVALID_MCS_IDX 255
#define IS_MCS_HAS_DCM_RATE(val) \
((val) == 0 || (val) == 1 || \
(val) == 3 || (val) == 4)
#define LINK_STATUS_LEGACY 0
#define LINK_STATUS_VHT 0x1
#define LINK_STATUS_MIMO 0x2
@ -96,6 +103,23 @@ struct index_vht_data_rate_type {
uint16_t ht80_rate[2];
};
#ifdef WLAN_FEATURE_11AX
#define MAX_HE_DCM_INDEX 2
/**
* struct index_he_data_rate_type - he data rate type
* @beacon_rate_index: Beacon rate index
* @supported_he80_rate: he80 rate
* @supported_he40_rate: he40 rate
* @supported_he20_rate: he20 rate
*/
struct index_he_data_rate_type {
uint8_t beacon_rate_index;
uint16_t supported_he20_rate[MAX_HE_DCM_INDEX][3];
uint16_t supported_he40_rate[MAX_HE_DCM_INDEX][3];
uint16_t supported_he80_rate[MAX_HE_DCM_INDEX][3];
};
#endif
struct wifi_scan_cmd_req_params;
/*
* wma_main.c functions declarations

View file

@ -761,12 +761,48 @@ static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id)
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
}
#ifdef WLAN_FEATURE_11AX
/**
* wma_set_bss_rate_flags_he() - set rate flags based on BSS capability
* @rate_flags: rate_flags pointer
* @add_bss: add_bss params
*
* Return: QDF_STATUS
*/
static QDF_STATUS wma_set_bss_rate_flags_he(enum tx_rate_info *rate_flags,
struct bss_params *add_bss)
{
if (!add_bss->he_capable)
return QDF_STATUS_E_NOSUPPORT;
/*extend TX_RATE_HE160 in future*/
if (add_bss->ch_width == CH_WIDTH_160MHZ ||
add_bss->ch_width == CH_WIDTH_80P80MHZ ||
add_bss->ch_width == CH_WIDTH_80MHZ)
*rate_flags |= TX_RATE_HE80;
else if (add_bss->ch_width)
*rate_flags |= TX_RATE_HE40;
else
*rate_flags |= TX_RATE_HE20;
wma_debug("he_capable %d", add_bss->he_capable);
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS wma_set_bss_rate_flags_he(enum tx_rate_info *rate_flags,
struct bss_params *add_bss)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif
void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
struct bss_params *add_bss)
{
struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
struct vdev_mlme_obj *vdev_mlme;
uint32_t *rate_flags;
enum tx_rate_info *rate_flags;
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
@ -777,24 +813,28 @@ void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
}
rate_flags = &vdev_mlme->mgmt.rate_info.rate_flags;
*rate_flags = 0;
if (add_bss->vhtCapable) {
if (add_bss->ch_width == CH_WIDTH_80P80MHZ)
*rate_flags |= TX_RATE_VHT80;
if (add_bss->ch_width == CH_WIDTH_160MHZ)
*rate_flags |= TX_RATE_VHT80;
if (add_bss->ch_width == CH_WIDTH_80MHZ)
*rate_flags |= TX_RATE_VHT80;
else if (add_bss->ch_width)
*rate_flags |= TX_RATE_VHT40;
else
*rate_flags |= TX_RATE_VHT20;
}
/* avoid to conflict with htCapable flag */
else if (add_bss->htCapable) {
if (add_bss->ch_width)
*rate_flags |= TX_RATE_HT40;
else
*rate_flags |= TX_RATE_HT20;
if (QDF_STATUS_SUCCESS !=
wma_set_bss_rate_flags_he(rate_flags, add_bss)) {
if (add_bss->vhtCapable) {
if (add_bss->ch_width == CH_WIDTH_80P80MHZ)
*rate_flags |= TX_RATE_VHT80;
if (add_bss->ch_width == CH_WIDTH_160MHZ)
*rate_flags |= TX_RATE_VHT80;
if (add_bss->ch_width == CH_WIDTH_80MHZ)
*rate_flags |= TX_RATE_VHT80;
else if (add_bss->ch_width)
*rate_flags |= TX_RATE_VHT40;
else
*rate_flags |= TX_RATE_VHT20;
}
/* avoid to conflict with htCapable flag */
else if (add_bss->htCapable) {
if (add_bss->ch_width)
*rate_flags |= TX_RATE_HT40;
else
*rate_flags |= TX_RATE_HT20;
}
}
if (add_bss->staContext.fShortGI20Mhz ||
@ -804,6 +844,10 @@ void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
if (!add_bss->htCapable && !add_bss->vhtCapable)
*rate_flags = TX_RATE_LEGACY;
wma_debug("capable: vht %u, ht %u, rate_flags %x, ch_width %d",
add_bss->vhtCapable, add_bss->htCapable,
*rate_flags, add_bss->ch_width);
wma_cp_stats_set_rate_flag(wma, vdev_id);
}

View file

@ -123,6 +123,91 @@ static struct index_vht_data_rate_type vht_mcs_nss2[] = {
{9, {1730, 1920}, {3600, 4000}, {7800, 8667} }
};
#ifdef WLAN_FEATURE_11AX
/* MCS Based HE rate table */
/* MCS parameters with Nss = 1*/
static struct index_he_data_rate_type he_mcs_nss1[] = {
/* MCS, {dcm0:0.8/1.6/3.2}, {dcm1:0.8/1.6/3.2} */
{0, {{86, 81, 73 }, {43, 40, 36 } }, /* HE20 */
{{172, 163, 146 }, {86, 81, 73 } }, /* HE40 */
{{360, 340, 306 }, {180, 170, 153} } }, /* HE80 */
{1, {{172, 163, 146 }, {86, 81, 73 } },
{{344, 325, 293 }, {172, 163, 146} },
{{721, 681, 613 }, {360, 340, 306} } },
{2, {{258, 244, 219 }, {0} },
{{516, 488, 439 }, {0} },
{{1081, 1021, 919 }, {0} } },
{3, {{344, 325, 293 }, {172, 163, 146} },
{{688, 650, 585 }, {344, 325, 293} },
{{1441, 1361, 1225}, {721, 681, 613} } },
{4, {{516, 488, 439 }, {258, 244, 219} },
{{1032, 975, 878 }, {516, 488, 439} },
{{2162, 2042, 1838}, {1081, 1021, 919} } },
{5, {{688, 650, 585 }, {0} },
{{1376, 1300, 1170}, {0} },
{{2882, 2722, 2450}, {0} } },
{6, {{774, 731, 658 }, {0} },
{{1549, 1463, 1316}, {0} },
{{3243, 3063, 2756}, {0} } },
{7, {{860, 813, 731 }, {0} },
{{1721, 1625, 1463}, {0} },
{{3603, 3403, 3063}, {0} } },
{8, {{1032, 975, 878 }, {0} },
{{2065, 1950, 1755}, {0} },
{{4324, 4083, 3675}, {0} } },
{9, {{1147, 1083, 975 }, {0} },
{{2294, 2167, 1950}, {0} },
{{4804, 4537, 4083}, {0} } },
{10, {{1290, 1219, 1097}, {0} },
{{2581, 2438, 2194}, {0} },
{{5404, 5104, 4594}, {0} } },
{11, {{1434, 1354, 1219}, {0} },
{{2868, 2708, 2438}, {0} },
{{6004, 5671, 5104}, {0} } }
};
/*MCS parameters with Nss = 2*/
static struct index_he_data_rate_type he_mcs_nss2[] = {
/* MCS, {dcm0:0.8/1.6/3.2}, {dcm1:0.8/1.6/3.2} */
{0, {{172, 163, 146 }, {86, 81, 73 } }, /* HE20 */
{{344, 325, 293 }, {172, 163, 146} }, /* HE40 */
{{721, 681, 613 }, {360, 340, 306} } }, /* HE80 */
{1, {{344, 325, 293 }, {172, 163, 146} },
{{688, 650, 585 }, {344, 325, 293} },
{{1441, 1361, 1225}, {721, 681, 613} } },
{2, {{516, 488, 439 }, {0} },
{{1032, 975, 878 }, {0} },
{{2162, 2042, 1838}, {0} } },
{3, {{688, 650, 585 }, {344, 325, 293 } },
{{1376, 1300, 1170}, {688, 650, 585 } },
{{2882, 2722, 2450}, {1441, 1361, 1225} } },
{4, {{1032, 975, 878 }, {516, 488, 439 } },
{{2065, 1950, 1755}, {1032, 975, 878 } },
{{4324, 4083, 3675}, {2162, 2042, 1838} } },
{5, {{1376, 1300, 1170}, {0} },
{{2753, 2600, 2340}, {0} },
{{5765, 5444, 4900}, {0} } },
{6, {{1549, 1463, 1316}, {0} },
{{3097, 2925, 2633}, {0} },
{{6485, 6125, 5513}, {0} } },
{7, {{1721, 1625, 1463}, {0} },
{{3441, 3250, 2925}, {0} },
{{7206, 6806, 6125}, {0} } },
{8, {{2065, 1950, 1755}, {0} },
{{4129, 3900, 3510}, {0} },
{{8647, 8167, 7350}, {0} } },
{9, {{2294, 2167, 1950}, {0} },
{{4588, 4333, 3900}, {0} },
{{9607, 9074, 8166}, {0} } },
{10, {{2581, 2438, 2194}, {0} },
{{5162, 4875, 4388}, {0} },
{{10809, 10208, 9188}, {0} } },
{11, {{2868, 2708, 2438}, {0} },
{{5735, 5417, 4875}, {0} },
{{12010, 11343, 10208}, {0} } }
};
#endif
#ifdef BIG_ENDIAN_HOST
/* ############# function definitions ############ */
@ -151,90 +236,233 @@ void wma_swap_bytes(void *pv, uint32_t n)
/**
* wma_mcs_rate_match() - find the match mcs rate
* @match_rate: the rate to look up
* @is_sgi: return if the SGI rate is found
* @nss: the nss in use
* @nss1_rate: the nss1 rate
* @nss1_srate: the nss1 SGI rate
* @nss2_rate: the nss2 rate
* @nss2_srate: the nss2 SGI rate
* @raw_rate: the rate to look up
* @is_he: if it is he rate
* @nss1_rate: the nss1 rate
* @nss2_rate: the nss2 rate
* @nss: the nss in use
* @guard_interval: to get guard interval from rate
*
* This is a helper function to find the match of the tx_rate
* in terms of the nss1/nss2 rate with non-SGI/SGI.
* and return nss/guard interval.
*
* Return: the found rate or 0 otherwise
*/
static inline uint16_t wma_mcs_rate_match(uint16_t match_rate, bool *is_sgi,
uint8_t *nss, uint16_t nss1_rate,
uint16_t nss1_srate,
uint16_t nss2_rate,
uint16_t nss2_srate)
static inline uint16_t wma_mcs_rate_match(uint16_t raw_rate,
bool is_he,
uint16_t *nss1_rate,
uint16_t *nss2_rate,
uint8_t *nss,
enum txrate_gi *guard_interval)
{
WMA_LOGD("%s match_rate: %d, %d %d %d %d",
__func__, match_rate, nss1_rate, nss1_srate, nss2_rate,
nss2_srate);
uint8_t gi_index;
uint8_t gi_index_max = 2;
uint16_t ret_rate = 0;
if (match_rate == nss1_rate) {
*nss = 1;
return nss1_rate;
} else if (match_rate == nss1_srate) {
*is_sgi = true;
*nss = 1;
return nss1_srate;
} else if (*nss == 2 && match_rate == nss2_rate)
return nss2_rate;
else if (*nss == 2 && match_rate == nss2_srate) {
*is_sgi = true;
return nss2_srate;
} else
return 0;
WMA_LOGD("%s raw_rate: %u, %u %u %u %u",
__func__, raw_rate, nss1_rate[0],
nss1_rate[1], nss2_rate[0], nss2_rate[1]);
if (is_he)
WMA_LOGD("%s : is_he %u, %u, %u",
__func__, is_he, nss1_rate[2], nss2_rate[2]);
if (is_he)
gi_index_max = 3;
for (gi_index = 0; gi_index < gi_index_max; gi_index++) {
if (raw_rate == nss1_rate[gi_index]) {
*nss = 1;
ret_rate = nss1_rate[gi_index];
break;
}
if (*nss == 2 && raw_rate == nss2_rate[gi_index]) {
ret_rate = nss2_rate[gi_index];
break;
}
}
if (ret_rate) {
if (gi_index == 1)
*guard_interval =
is_he ? TXRATE_GI_1_6_US : TXRATE_GI_0_4_US;
else if (is_he && gi_index == 2)
*guard_interval = TXRATE_GI_3_2_US;
else
*guard_interval = TXRATE_GI_0_8_US;
}
WMA_LOGD("%s ret_rate: %u, guard interval %u nss %u",
__func__, ret_rate, *guard_interval, *nss);
return ret_rate;
}
uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
uint8_t *nss, uint8_t *mcs_rate_flag)
#ifdef WLAN_FEATURE_11AX
/**
* wma_get_mcs_idx() - get mcs index
* @raw_rate: raw rate from fw
* @rate_flags: rate flags
* @nss: nss
* @dcm: dcm
* @guard_interval: guard interval
* @mcs_rate_flag: mcs rate flags
* @p_index: index for matched rate
*
* Return: return match rate if found, else 0
*/
static uint16_t wma_match_he_rate(uint16_t raw_rate,
enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flag,
uint8_t *p_index)
{
uint8_t index = 0;
uint8_t dcm_index_max = 1;
uint8_t dcm_index = 0;
uint16_t match_rate = 0;
uint16_t *nss1_rate;
uint16_t *nss2_rate;
*p_index = 0;
if (!(rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 |
TX_RATE_HE20)))
return 0;
for (index = 0; index < MAX_HE_MCS_IDX; index++) {
dcm_index_max = IS_MCS_HAS_DCM_RATE(index) ? 2 : 1;
for (dcm_index = 0; dcm_index < dcm_index_max;
dcm_index++) {
if (rate_flags & TX_RATE_HE80) {
nss1_rate = &he_mcs_nss1[index].
supported_he80_rate[dcm_index][0];
nss2_rate = &he_mcs_nss2[index].
supported_he80_rate[dcm_index][0];
/* check for he80 nss1/2 rate set */
match_rate = wma_mcs_rate_match(raw_rate, 1,
nss1_rate,
nss2_rate,
nss,
guard_interval);
if (match_rate)
goto rate_found;
}
if (rate_flags & (TX_RATE_HE40 | TX_RATE_HE80)) {
nss1_rate = &he_mcs_nss1[index].
supported_he40_rate[dcm_index][0];
nss2_rate = &he_mcs_nss2[index].
supported_he40_rate[dcm_index][0];
/* check for he40 nss1/2 rate set */
match_rate = wma_mcs_rate_match(raw_rate, 1,
nss1_rate,
nss2_rate,
nss,
guard_interval);
if (match_rate) {
*mcs_rate_flag &= ~TX_RATE_HE80;
goto rate_found;
}
}
if (rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 |
TX_RATE_HE20)) {
nss1_rate = &he_mcs_nss1[index].
supported_he20_rate[dcm_index][0];
nss2_rate = &he_mcs_nss2[index].
supported_he20_rate[dcm_index][0];
/* check for he20 nss1/2 rate set */
match_rate = wma_mcs_rate_match(raw_rate, 1,
nss1_rate,
nss2_rate,
nss,
guard_interval);
if (match_rate) {
*mcs_rate_flag &= TX_RATE_HE20;
goto rate_found;
}
}
}
}
rate_found:
if (match_rate) {
if (dcm_index == 1)
*dcm = 1;
*p_index = index;
}
return match_rate;
}
#else
static uint16_t wma_match_he_rate(uint16_t raw_rate,
enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flag,
uint8_t *p_index)
{
return 0;
}
#endif
uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
uint8_t *nss, uint8_t *dcm,
enum txrate_gi *guard_interval,
enum tx_rate_info *mcs_rate_flag)
{
uint8_t index = 0;
uint16_t match_rate = 0;
bool is_sgi = false;
uint16_t *nss1_rate;
uint16_t *nss2_rate;
WMA_LOGD("%s rate:%d rate_flgs: 0x%x, nss: %d",
__func__, max_rate, rate_flags, *nss);
WMA_LOGD("%s enter: raw_rate:%d rate_flgs: 0x%x, nss: %d",
__func__, raw_rate, rate_flags, *nss);
*mcs_rate_flag = rate_flags;
*mcs_rate_flag &= ~TX_RATE_SGI;
match_rate = wma_match_he_rate(raw_rate, rate_flags,
nss, dcm, guard_interval,
mcs_rate_flag, &index);
if (match_rate)
goto rate_found;
for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
if (rate_flags & TX_RATE_VHT80) {
nss1_rate = &vht_mcs_nss1[index].ht80_rate[0];
nss2_rate = &vht_mcs_nss2[index].ht80_rate[0];
/* check for vht80 nss1/2 rate set */
match_rate = wma_mcs_rate_match(max_rate, &is_sgi, nss,
vht_mcs_nss1[index].ht80_rate[0],
vht_mcs_nss1[index].ht80_rate[1],
vht_mcs_nss2[index].ht80_rate[0],
vht_mcs_nss2[index].ht80_rate[1]);
match_rate = wma_mcs_rate_match(raw_rate, 0,
nss1_rate,
nss2_rate,
nss, guard_interval);
if (match_rate)
goto rate_found;
}
if ((rate_flags & TX_RATE_VHT40) |
(rate_flags & TX_RATE_VHT80)) {
if (rate_flags & (TX_RATE_VHT40 | TX_RATE_VHT80)) {
nss1_rate = &vht_mcs_nss1[index].ht40_rate[0];
nss2_rate = &vht_mcs_nss2[index].ht40_rate[0];
/* check for vht40 nss1/2 rate set */
match_rate = wma_mcs_rate_match(max_rate, &is_sgi, nss,
vht_mcs_nss1[index].ht40_rate[0],
vht_mcs_nss1[index].ht40_rate[1],
vht_mcs_nss2[index].ht40_rate[0],
vht_mcs_nss2[index].ht40_rate[1]);
match_rate = wma_mcs_rate_match(raw_rate, 0,
nss1_rate,
nss2_rate,
nss, guard_interval);
if (match_rate) {
*mcs_rate_flag &= ~TX_RATE_VHT80;
goto rate_found;
}
}
if ((rate_flags & TX_RATE_VHT20) |
(rate_flags & TX_RATE_VHT40) |
(rate_flags & TX_RATE_VHT80)) {
if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 |
TX_RATE_VHT80)) {
nss1_rate = &vht_mcs_nss1[index].ht20_rate[0];
nss2_rate = &vht_mcs_nss2[index].ht20_rate[0];
/* check for vht20 nss1/2 rate set */
match_rate = wma_mcs_rate_match(max_rate, &is_sgi, nss,
vht_mcs_nss1[index].ht20_rate[0],
vht_mcs_nss1[index].ht20_rate[1],
vht_mcs_nss2[index].ht20_rate[0],
vht_mcs_nss2[index].ht20_rate[1]);
match_rate = wma_mcs_rate_match(raw_rate, 0,
nss1_rate,
nss2_rate,
nss, guard_interval);
if (match_rate) {
*mcs_rate_flag &= ~(TX_RATE_VHT80 |
TX_RATE_VHT40);
@ -244,12 +472,13 @@ uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
}
for (index = 0; index < MAX_HT_MCS_IDX; index++) {
if (rate_flags & TX_RATE_HT40) {
nss1_rate = &mcs_nss1[index].ht40_rate[0];
nss2_rate = &mcs_nss2[index].ht40_rate[0];
/* check for ht40 nss1/2 rate set */
match_rate = wma_mcs_rate_match(max_rate, &is_sgi, nss,
mcs_nss1[index].ht40_rate[0],
mcs_nss1[index].ht40_rate[1],
mcs_nss2[index].ht40_rate[0],
mcs_nss2[index].ht40_rate[1]);
match_rate = wma_mcs_rate_match(raw_rate, 0,
nss1_rate,
nss2_rate,
nss, guard_interval);
if (match_rate) {
*mcs_rate_flag = TX_RATE_HT40;
if (*nss == 2)
@ -257,14 +486,14 @@ uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
goto rate_found;
}
}
if ((rate_flags & TX_RATE_HT20) ||
(rate_flags & TX_RATE_HT40)) {
if (rate_flags & (TX_RATE_HT20 | TX_RATE_HT40)) {
nss1_rate = &mcs_nss1[index].ht20_rate[0];
nss2_rate = &mcs_nss2[index].ht20_rate[0];
/* check for ht20 nss1/2 rate set */
match_rate = wma_mcs_rate_match(max_rate, &is_sgi, nss,
mcs_nss1[index].ht20_rate[0],
mcs_nss1[index].ht20_rate[1],
mcs_nss2[index].ht20_rate[0],
mcs_nss2[index].ht20_rate[1]);
match_rate = wma_mcs_rate_match(raw_rate, 0,
nss1_rate,
nss2_rate,
nss, guard_interval);
if (match_rate) {
*mcs_rate_flag = TX_RATE_HT20;
if (*nss == 2)
@ -275,12 +504,17 @@ uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
}
rate_found:
/* set SGI flag only if this is SGI rate */
if (match_rate && is_sgi == true)
*mcs_rate_flag |= TX_RATE_SGI;
WMA_LOGD("%s - match_rate: %d index: %d rate_flag: 0x%x is_sgi: %d",
__func__, match_rate, index, *mcs_rate_flag, is_sgi);
/* set SGI flag only if this is SGI rate */
if (match_rate && *guard_interval == TXRATE_GI_0_4_US)
*mcs_rate_flag |= TX_RATE_SGI;
else
*mcs_rate_flag &= ~TX_RATE_SGI;
WMA_LOGD("%s exit: match_rate %d index: %d"
" mcs_rate_flag: 0x%x nss %d guard interval %d",
__func__, match_rate, index, *mcs_rate_flag,
*nss, *guard_interval);
return match_rate ? index : INVALID_MCS_IDX;
}