mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-24 11:25:43 +00:00
wifi: ath12k: propagate EHT capabilities to userspace
Propagate EHT capabilities to the userspace using a new member 'eht_cap' in structure ieee80211_sband_iftype_data. MCS-NSS capabilities are copied depending on the supported bandwidths for the given band. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com> Signed-off-by: Pradeep Kumar Chitrapu<quic_pradeepc@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/20230725224034.14045-5-quic_alokad@quicinc.com
This commit is contained in:
parent
1476014fad
commit
dbe90679bf
1 changed files with 111 additions and 0 deletions
|
@ -4275,6 +4275,115 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
|
|||
ath12k_gen_ppe_thresh(&band_cap->he_ppet, he_cap->ppe_thres);
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_mac_copy_eht_mcs_nss(struct ath12k_band_cap *band_cap,
|
||||
struct ieee80211_eht_mcs_nss_supp *mcs_nss,
|
||||
const struct ieee80211_he_cap_elem *he_cap,
|
||||
const struct ieee80211_eht_cap_elem_fixed *eht_cap)
|
||||
{
|
||||
if ((he_cap->phy_cap_info[0] &
|
||||
(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
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)
|
||||
memcpy(&mcs_nss->only_20mhz, &band_cap->eht_mcs_20_only,
|
||||
sizeof(struct ieee80211_eht_mcs_nss_supp_20mhz_only));
|
||||
|
||||
if (he_cap->phy_cap_info[0] &
|
||||
(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G))
|
||||
memcpy(&mcs_nss->bw._80, &band_cap->eht_mcs_80,
|
||||
sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
|
||||
|
||||
if (he_cap->phy_cap_info[0] &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
|
||||
memcpy(&mcs_nss->bw._160, &band_cap->eht_mcs_160,
|
||||
sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
|
||||
|
||||
if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ)
|
||||
memcpy(&mcs_nss->bw._320, &band_cap->eht_mcs_320,
|
||||
sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
|
||||
}
|
||||
|
||||
static void ath12k_mac_copy_eht_ppe_thresh(struct ath12k_wmi_ppe_threshold_arg *fw_ppet,
|
||||
struct ieee80211_sta_eht_cap *cap)
|
||||
{
|
||||
u16 bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
|
||||
u8 i, nss, ru, ppet_bit_len_per_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
|
||||
|
||||
u8p_replace_bits(&cap->eht_ppe_thres[0], fw_ppet->numss_m1,
|
||||
IEEE80211_EHT_PPE_THRES_NSS_MASK);
|
||||
|
||||
u16p_replace_bits((u16 *)&cap->eht_ppe_thres[0], fw_ppet->ru_bit_mask,
|
||||
IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
|
||||
|
||||
for (nss = 0; nss <= fw_ppet->numss_m1; nss++) {
|
||||
for (ru = 0;
|
||||
ru < hweight16(IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
|
||||
ru++) {
|
||||
u32 val = 0;
|
||||
|
||||
if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0)
|
||||
continue;
|
||||
|
||||
u32p_replace_bits(&val, fw_ppet->ppet16_ppet8_ru3_ru0[nss] >>
|
||||
(ru * ppet_bit_len_per_ru),
|
||||
GENMASK(ppet_bit_len_per_ru - 1, 0));
|
||||
|
||||
for (i = 0; i < ppet_bit_len_per_ru; i++) {
|
||||
cap->eht_ppe_thres[bit / 8] |=
|
||||
(((val >> i) & 0x1) << ((bit % 8)));
|
||||
bit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_mac_copy_eht_cap(struct ath12k_band_cap *band_cap,
|
||||
struct ieee80211_he_cap_elem *he_cap_elem,
|
||||
int iftype,
|
||||
struct ieee80211_sta_eht_cap *eht_cap)
|
||||
{
|
||||
struct ieee80211_eht_cap_elem_fixed *eht_cap_elem = &eht_cap->eht_cap_elem;
|
||||
|
||||
memset(eht_cap, 0, sizeof(struct ieee80211_sta_eht_cap));
|
||||
eht_cap->has_eht = true;
|
||||
memcpy(eht_cap_elem->mac_cap_info, band_cap->eht_cap_mac_info,
|
||||
sizeof(eht_cap_elem->mac_cap_info));
|
||||
memcpy(eht_cap_elem->phy_cap_info, band_cap->eht_cap_phy_info,
|
||||
sizeof(eht_cap_elem->phy_cap_info));
|
||||
|
||||
switch (iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
eht_cap_elem->phy_cap_info[0] &=
|
||||
~IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ;
|
||||
eht_cap_elem->phy_cap_info[4] &=
|
||||
~IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO;
|
||||
eht_cap_elem->phy_cap_info[5] &=
|
||||
~IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP;
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
eht_cap_elem->phy_cap_info[7] &=
|
||||
~(IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ |
|
||||
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ |
|
||||
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ);
|
||||
eht_cap_elem->phy_cap_info[7] &=
|
||||
~(IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |
|
||||
IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ |
|
||||
IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ath12k_mac_copy_eht_mcs_nss(band_cap, &eht_cap->eht_mcs_nss_supp,
|
||||
he_cap_elem, eht_cap_elem);
|
||||
|
||||
if (eht_cap_elem->phy_cap_info[5] &
|
||||
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT)
|
||||
ath12k_mac_copy_eht_ppe_thresh(&band_cap->eht_ppet, eht_cap);
|
||||
}
|
||||
|
||||
static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
|
||||
struct ath12k_pdev_cap *cap,
|
||||
struct ieee80211_sband_iftype_data *data,
|
||||
|
@ -4303,6 +4412,8 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
|
|||
data[idx].he_6ghz_capa.capa =
|
||||
ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
|
||||
}
|
||||
ath12k_mac_copy_eht_cap(band_cap, &he_cap->he_cap_elem, i,
|
||||
&data[idx].eht_cap);
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue