From: Allen Ye The maximum power value may exist in data or backoff field. To reponse the correct value of txpower, mt76 should also consider these values in sku table. Fixes: b05ab4be9fd7 (wifi: mt76: mt7915: add bf backoff limit table support) Signed-off-by: Allen Ye Signed-off-by: Ryder Lee --- drivers/net/wireless/mediatek/mt76/eeprom.c | 171 +++++++++++++------- drivers/net/wireless/mediatek/mt76/mt76.h | 1 - 2 files changed, 113 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index 573400d57..3e182c8e0 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -9,6 +9,13 @@ #include #include #include "mt76.h" +#include "mt76_connac.h" + +enum mt76_sku_type { + MT76_SKU_RATE, + MT76_SKU_BACKOFF, + MT76_SKU_BACKOFF_BF_OFFSET, +}; static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len) { @@ -292,7 +299,6 @@ mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan) } EXPORT_SYMBOL_GPL(mt76_find_channel_node); - static s8 mt76_get_txs_delta(struct device_node *np, u8 nss) { @@ -306,9 +312,24 @@ mt76_get_txs_delta(struct device_node *np, u8 nss) return be32_to_cpu(val[nss - 1]); } +static inline u8 mt76_backoff_n_chains(struct mt76_dev *dev, u8 idx) +{ + /* 0:1T1S, 1:2T1S, ..., 14:5T5S */ + static const u8 connac3_table[] = + {1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5}; + static const u8 connac2_table[] = + {1, 2, 3, 4, 2, 3, 4, 3, 4, 4, 0, 0, 0, 0, 0}; + + if (idx < 0 || idx >= ARRAY_SIZE(connac3_table)) + return 0; + + return is_mt799x(dev) ? connac3_table[idx] : connac2_table[idx]; +} + static void -mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data, - s8 target_power, s8 nss_delta, s8 *max_power) +mt76_apply_array_limit(struct mt76_dev *dev, s8 *pwr, size_t pwr_len, + const s8 *data, s8 target_power, s8 nss_delta, + s8 *max_power, int n_chains, enum mt76_sku_type type) { int i; @@ -316,18 +337,50 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data, return; for (i = 0; i < pwr_len; i++) { - pwr[i] = min_t(s8, target_power, data[i] + nss_delta); + s8 backoff_delta, delta = mt76_tx_power_path_delta(n_chains); + int backoff_n_chains = 0; + + switch (type) { + case MT76_SKU_RATE: + pwr[i] = min_t(s8, target_power, data[i] + nss_delta); + break; + case MT76_SKU_BACKOFF: + backoff_n_chains = mt76_backoff_n_chains(dev, i); + backoff_delta = mt76_tx_power_path_delta(backoff_n_chains); + pwr[i] = min_t(s8, target_power + delta - backoff_delta, + data[i] + nss_delta); + break; + case MT76_SKU_BACKOFF_BF_OFFSET: + backoff_n_chains = mt76_backoff_n_chains(dev, i + 1); + backoff_delta = mt76_tx_power_path_delta(backoff_n_chains); + pwr[i] = min_t(s8, target_power + delta - backoff_delta, + data[i] + nss_delta); + break; + default: + return; + } + + /* used for padding, doesn't need to be considered */ + if (data[i] >= S8_MAX - 1) + continue; + + /* only consider backoff value for the configured chain number */ + if (type != MT76_SKU_RATE && n_chains != backoff_n_chains) + continue; + *max_power = max(*max_power, pwr[i]); } } static void -mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, - const s8 *data, size_t len, s8 target_power, - s8 nss_delta) +mt76_apply_multi_array_limit(struct mt76_dev *dev, s8 *pwr, size_t pwr_len, + s8 pwr_num, const s8 *data, size_t len, + s8 target_power, s8 nss_delta, s8 *max_power, + int n_chains, enum mt76_sku_type type) { int i, cur; - s8 max_power = -128; + +#define connac2_backoff_ru_idx 2 if (!data) return; @@ -337,8 +390,13 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, if (len < pwr_len + 1) break; - mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1, - target_power, nss_delta, &max_power); + if (!is_mt799x(dev) && type == MT76_SKU_BACKOFF && + i > connac2_backoff_ru_idx) + type = MT76_SKU_BACKOFF_BF_OFFSET; + + mt76_apply_array_limit(dev, pwr + pwr_len * i, pwr_len, data + 1, + target_power, nss_delta, max_power, + n_chains, type); if (--cur > 0) continue; @@ -360,18 +418,11 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, struct device_node *np; const s8 *val; char name[16]; - u32 mcs_rates = dev->drv->mcs_rates; - u32 ru_rates = ARRAY_SIZE(dest->ru[0]); char band; size_t len; - s8 max_power = 0; - s8 max_power_backoff = -127; + s8 max_power = -127; s8 txs_delta; int n_chains = hweight16(phy->chainmask); - s8 target_power_combine = target_power + mt76_tx_power_path_delta(n_chains); - - if (!mcs_rates) - mcs_rates = 10; memset(dest, target_power, sizeof(*dest) - sizeof(dest->path)); memset(&dest->path, 0, sizeof(dest->path)); @@ -408,47 +459,51 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask)); +#define __apply_array_limit(arr, type) \ + mt76_apply_array_limit(dev, (arr), ARRAY_SIZE(arr), val, target_power, \ + txs_delta, &max_power, n_chains, type) + +#define __apply_multi_array_limit(arr, type) \ + mt76_apply_multi_array_limit(dev, (arr)[0], ARRAY_SIZE((arr)[0]), \ + ARRAY_SIZE(arr), val, len, target_power, \ + txs_delta, &max_power, n_chains, type) + val = mt76_get_of_array_s8(np, "rates-cck", &len, ARRAY_SIZE(dest->cck)); - mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val, - target_power, txs_delta, &max_power); - - val = mt76_get_of_array_s8(np, "rates-ofdm", - &len, ARRAY_SIZE(dest->ofdm)); - mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val, - target_power, txs_delta, &max_power); - - val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1); - mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]), - ARRAY_SIZE(dest->mcs), val, len, - target_power, txs_delta); - - val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1); - mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]), - ARRAY_SIZE(dest->ru), val, len, - target_power, txs_delta); - - max_power_backoff = max_power; - val = mt76_get_of_array_s8(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck)); - mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val, - target_power_combine, txs_delta, &max_power_backoff); - - val = mt76_get_of_array_s8(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm)); - mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val, - target_power_combine, txs_delta, &max_power_backoff); - - val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf)); - mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val, - target_power_combine, txs_delta, &max_power_backoff); - - val = mt76_get_of_array_s8(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1); - mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]), - ARRAY_SIZE(dest->path.ru), val, len, - target_power_combine, txs_delta); - - val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1); - mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]), - ARRAY_SIZE(dest->path.ru_bf), val, len, - target_power_combine, txs_delta); + __apply_array_limit(dest->cck, MT76_SKU_RATE); + + val = mt76_get_of_array_s8(np, "rates-ofdm", &len, ARRAY_SIZE(dest->ofdm)); + __apply_array_limit(dest->ofdm, MT76_SKU_RATE); + + val = mt76_get_of_array_s8(np, "rates-mcs", &len, + ARRAY_SIZE(dest->mcs[0]) + 1); + __apply_multi_array_limit(dest->mcs, MT76_SKU_RATE); + + val = mt76_get_of_array_s8(np, "rates-ru", &len, + ARRAY_SIZE(dest->ru[0]) + 1); + __apply_multi_array_limit(dest->ru, MT76_SKU_RATE); + + val = mt76_get_of_array_s8(np, "paths-cck", &len, + ARRAY_SIZE(dest->path.cck)); + __apply_array_limit(dest->path.cck, MT76_SKU_BACKOFF); + + val = mt76_get_of_array_s8(np, "paths-ofdm", &len, + ARRAY_SIZE(dest->path.ofdm)); + __apply_array_limit(dest->path.ofdm, MT76_SKU_BACKOFF); + + val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, + ARRAY_SIZE(dest->path.ofdm_bf)); + __apply_array_limit(dest->path.ofdm_bf, MT76_SKU_BACKOFF_BF_OFFSET); + + val = mt76_get_of_array_s8(np, "paths-ru", &len, + ARRAY_SIZE(dest->path.ru[0]) + 1); + __apply_multi_array_limit(dest->path.ru, MT76_SKU_BACKOFF); + + val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, + ARRAY_SIZE(dest->path.ru_bf[0]) + 1); + __apply_multi_array_limit(dest->path.ru_bf, MT76_SKU_BACKOFF); + +#undef __apply_array_limit +#undef __apply_multi_array_limit return max_power; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index d05e83ea1..32876eab2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -540,7 +540,6 @@ struct mt76_driver_ops { u32 survey_flags; u16 txwi_size; u16 token_size; - u8 mcs_rates; unsigned int link_data_size; -- 2.45.2