mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
wifi: ath12k: Add EHT MCS/NSS rates to Peer Assoc
Add EHT MCS/NSS rate functionality to peer association. As part of ath12k_peer_assoc_h_eht() add the calculation of EHT MCS/NSS using intersection of link_sta and phy capability. ath12k_mac_max_eht_mcs_nss() function is utilized when comparing the max NSS of link STA and phy capability since in split phy case, phy supports max NSS of 2 for 5G band. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Vishal Kumar <quic_visk@quicinc.com> Signed-off-by: Vishal Kumar <quic_visk@quicinc.com> Co-developed-by: Aloka Dixit <aloka.dixit@oss.qualcomm.com> Signed-off-by: Aloka Dixit <aloka.dixit@oss.qualcomm.com> Signed-off-by: Muna Sinada <muna.sinada@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20251024001928.257356-4-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
ec1d9b79be
commit
6c95151e2e
|
|
@ -545,6 +545,18 @@ ath12k_mac_max_eht_nss(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32
|
||||||
|
ath12k_mac_max_eht_mcs_nss(const u8 *eht_mcs, int eht_mcs_set_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u8 nss = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < eht_mcs_set_size; i++)
|
||||||
|
nss = max(nss, u8_get_bits(eht_mcs[i], IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
|
||||||
|
return nss;
|
||||||
|
}
|
||||||
|
|
||||||
static u8 ath12k_parse_mpdudensity(u8 mpdudensity)
|
static u8 ath12k_parse_mpdudensity(u8 mpdudensity)
|
||||||
{
|
{
|
||||||
/* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing":
|
/* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing":
|
||||||
|
|
@ -3016,6 +3028,18 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_eht(struct ath12k *ar,
|
||||||
return MODE_UNKNOWN;
|
return MODE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ath12k_peer_assoc_h_eht_masked(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX])
|
||||||
|
{
|
||||||
|
int nss;
|
||||||
|
|
||||||
|
for (nss = 0; nss < NL80211_EHT_NSS_MAX; nss++)
|
||||||
|
if (eht_mcs_mask[nss])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
||||||
struct ath12k_link_vif *arvif,
|
struct ath12k_link_vif *arvif,
|
||||||
struct ath12k_link_sta *arsta,
|
struct ath12k_link_sta *arsta,
|
||||||
|
|
@ -3027,6 +3051,7 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
||||||
const u8 *ht_mcs_mask;
|
const u8 *ht_mcs_mask;
|
||||||
const u16 *vht_mcs_mask;
|
const u16 *vht_mcs_mask;
|
||||||
const u16 *he_mcs_mask;
|
const u16 *he_mcs_mask;
|
||||||
|
const u16 *eht_mcs_mask;
|
||||||
enum wmi_phy_mode phymode = MODE_UNKNOWN;
|
enum wmi_phy_mode phymode = MODE_UNKNOWN;
|
||||||
|
|
||||||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||||
|
|
@ -3041,6 +3066,7 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
||||||
ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
|
ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
|
||||||
vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
|
vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
|
||||||
he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
|
he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
|
||||||
|
eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs;
|
||||||
|
|
||||||
link_sta = ath12k_mac_get_link_sta(arsta);
|
link_sta = ath12k_mac_get_link_sta(arsta);
|
||||||
if (!link_sta) {
|
if (!link_sta) {
|
||||||
|
|
@ -3051,7 +3077,8 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
||||||
|
|
||||||
switch (band) {
|
switch (band) {
|
||||||
case NL80211_BAND_2GHZ:
|
case NL80211_BAND_2GHZ:
|
||||||
if (link_sta->eht_cap.has_eht) {
|
if (link_sta->eht_cap.has_eht &&
|
||||||
|
!ath12k_peer_assoc_h_eht_masked(eht_mcs_mask)) {
|
||||||
if (link_sta->bandwidth == IEEE80211_STA_RX_BW_40)
|
if (link_sta->bandwidth == IEEE80211_STA_RX_BW_40)
|
||||||
phymode = MODE_11BE_EHT40_2G;
|
phymode = MODE_11BE_EHT40_2G;
|
||||||
else
|
else
|
||||||
|
|
@ -3197,16 +3224,21 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||||
{
|
{
|
||||||
struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
|
struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
|
||||||
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
|
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
|
||||||
|
const struct ieee80211_eht_mcs_nss_supp *own_eht_mcs_nss_supp;
|
||||||
const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20;
|
const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20;
|
||||||
|
const struct ieee80211_sta_eht_cap *eht_cap, *own_eht_cap;
|
||||||
|
const struct ieee80211_sband_iftype_data *iftd;
|
||||||
const struct ieee80211_eht_mcs_nss_supp_bw *bw;
|
const struct ieee80211_eht_mcs_nss_supp_bw *bw;
|
||||||
const struct ieee80211_sta_eht_cap *eht_cap;
|
|
||||||
const struct ieee80211_sta_he_cap *he_cap;
|
const struct ieee80211_sta_he_cap *he_cap;
|
||||||
struct ieee80211_link_sta *link_sta;
|
struct ieee80211_link_sta *link_sta;
|
||||||
struct ieee80211_bss_conf *link_conf;
|
struct ieee80211_bss_conf *link_conf;
|
||||||
struct cfg80211_chan_def def;
|
struct cfg80211_chan_def def;
|
||||||
|
bool user_rate_valid = true;
|
||||||
enum nl80211_band band;
|
enum nl80211_band band;
|
||||||
|
int eht_nss, nss_idx;
|
||||||
u32 *rx_mcs, *tx_mcs;
|
u32 *rx_mcs, *tx_mcs;
|
||||||
u16 *eht_mcs_mask;
|
u16 *eht_mcs_mask;
|
||||||
|
u8 max_nss = 0;
|
||||||
|
|
||||||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||||
|
|
||||||
|
|
@ -3234,6 +3266,16 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||||
band = def.chan->band;
|
band = def.chan->band;
|
||||||
eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs;
|
eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs;
|
||||||
|
|
||||||
|
iftd = ieee80211_get_sband_iftype_data(&ar->mac.sbands[band], vif->type);
|
||||||
|
if (!iftd) {
|
||||||
|
ath12k_warn(ar->ab,
|
||||||
|
"unable to access iftype_data in struct ieee80211_supported_band\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
own_eht_cap = &iftd->eht_cap;
|
||||||
|
own_eht_mcs_nss_supp = &own_eht_cap->eht_mcs_nss_supp;
|
||||||
|
|
||||||
arg->eht_flag = true;
|
arg->eht_flag = true;
|
||||||
|
|
||||||
if ((eht_cap->eht_cap_elem.phy_cap_info[5] &
|
if ((eht_cap->eht_cap_elem.phy_cap_info[5] &
|
||||||
|
|
@ -3250,6 +3292,28 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||||
rx_mcs = arg->peer_eht_rx_mcs_set;
|
rx_mcs = arg->peer_eht_rx_mcs_set;
|
||||||
tx_mcs = arg->peer_eht_tx_mcs_set;
|
tx_mcs = arg->peer_eht_tx_mcs_set;
|
||||||
|
|
||||||
|
eht_nss = ath12k_mac_max_eht_mcs_nss((void *)own_eht_mcs_nss_supp,
|
||||||
|
sizeof(*own_eht_mcs_nss_supp));
|
||||||
|
if (eht_nss > link_sta->rx_nss) {
|
||||||
|
user_rate_valid = false;
|
||||||
|
for (nss_idx = (link_sta->rx_nss - 1); nss_idx >= 0; nss_idx--) {
|
||||||
|
if (eht_mcs_mask[nss_idx]) {
|
||||||
|
user_rate_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user_rate_valid) {
|
||||||
|
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||||
|
"Setting eht range MCS value to peer supported nss %d for peer %pM\n",
|
||||||
|
link_sta->rx_nss, arsta->addr);
|
||||||
|
eht_mcs_mask[link_sta->rx_nss - 1] = eht_mcs_mask[eht_nss - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz;
|
||||||
|
bw = &eht_cap->eht_mcs_nss_supp.bw._80;
|
||||||
|
|
||||||
switch (link_sta->bandwidth) {
|
switch (link_sta->bandwidth) {
|
||||||
case IEEE80211_STA_RX_BW_320:
|
case IEEE80211_STA_RX_BW_320:
|
||||||
bw = &eht_cap->eht_mcs_nss_supp.bw._320;
|
bw = &eht_cap->eht_mcs_nss_supp.bw._320;
|
||||||
|
|
@ -3274,11 +3338,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||||
arg->peer_eht_mcs_count++;
|
arg->peer_eht_mcs_count++;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
if ((he_cap->he_cap_elem.phy_cap_info[0] &
|
if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] &
|
||||||
(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
|
||||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
|
||||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
|
||||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0) {
|
|
||||||
bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz;
|
bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz;
|
||||||
|
|
||||||
ath12k_mac_set_eht_mcs(bw_20->rx_tx_mcs7_max_nss,
|
ath12k_mac_set_eht_mcs(bw_20->rx_tx_mcs7_max_nss,
|
||||||
|
|
@ -3305,6 +3366,41 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||||
|
|
||||||
arg->punct_bitmap = ~arvif->punct_bitmap;
|
arg->punct_bitmap = ~arvif->punct_bitmap;
|
||||||
arg->eht_disable_mcs15 = link_conf->eht_disable_mcs15;
|
arg->eht_disable_mcs15 = link_conf->eht_disable_mcs15;
|
||||||
|
|
||||||
|
if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] &
|
||||||
|
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
|
||||||
|
if (bw_20->rx_tx_mcs13_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs13_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
if (bw_20->rx_tx_mcs11_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs11_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
if (bw_20->rx_tx_mcs9_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs9_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
if (bw_20->rx_tx_mcs7_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs7_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
} else {
|
||||||
|
if (bw->rx_tx_mcs13_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs13_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
if (bw->rx_tx_mcs11_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs11_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
if (bw->rx_tx_mcs9_max_nss)
|
||||||
|
max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs9_max_nss,
|
||||||
|
IEEE80211_EHT_MCS_NSS_RX));
|
||||||
|
}
|
||||||
|
|
||||||
|
max_nss = min(max_nss, (uint8_t)eht_nss);
|
||||||
|
|
||||||
|
arg->peer_nss = min(link_sta->rx_nss, max_nss);
|
||||||
|
|
||||||
|
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||||
|
"mac eht peer %pM nss %d mcs cnt %d ru_punct_bitmap 0x%x\n",
|
||||||
|
arsta->addr, arg->peer_nss, arg->peer_eht_mcs_count,
|
||||||
|
arg->punct_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
|
static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user