mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
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:
parent
cef8a74bef
commit
f1d8159208
16 changed files with 639 additions and 257 deletions
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue