1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright(c) 2021-2024 Intel Corporation
8 #include "ieee80211_i.h"
11 ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data
*sdata
,
12 struct ieee80211_supported_band
*sband
,
13 const u8
*he_cap_ie
, u8 he_cap_len
,
14 const struct ieee80211_eht_cap_elem
*eht_cap_ie_elem
,
16 struct link_sta_info
*link_sta
)
18 struct ieee80211_sta_eht_cap
*eht_cap
= &link_sta
->pub
->eht_cap
;
19 struct ieee80211_he_cap_elem
*he_cap_ie_elem
= (void *)he_cap_ie
;
22 u8 eht_total_size
= sizeof(eht_cap
->eht_cap_elem
);
23 u8
*pos
= (u8
*)eht_cap_ie_elem
;
25 memset(eht_cap
, 0, sizeof(*eht_cap
));
27 if (!eht_cap_ie_elem
||
28 !ieee80211_get_eht_iftype_cap_vif(sband
, &sdata
->vif
))
31 mcs_nss_size
= ieee80211_eht_mcs_nss_size(he_cap_ie_elem
,
32 &eht_cap_ie_elem
->fixed
,
34 NL80211_IFTYPE_STATION
);
36 eht_total_size
+= mcs_nss_size
;
38 /* Calculate the PPE thresholds length only if the header is present */
39 if (eht_cap_ie_elem
->fixed
.phy_cap_info
[5] &
40 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT
) {
43 if (eht_cap_len
< eht_total_size
+ sizeof(u16
))
46 eht_ppe_hdr
= get_unaligned_le16(eht_cap_ie_elem
->optional
+ mcs_nss_size
);
48 ieee80211_eht_ppe_size(eht_ppe_hdr
,
49 eht_cap_ie_elem
->fixed
.phy_cap_info
);
50 eht_total_size
+= eht_ppe_size
;
52 /* we calculate as if NSS > 8 are valid, but don't handle that */
53 if (eht_ppe_size
> sizeof(eht_cap
->eht_ppe_thres
))
57 if (eht_cap_len
< eht_total_size
)
60 /* Copy the static portion of the EHT capabilities */
61 memcpy(&eht_cap
->eht_cap_elem
, pos
, sizeof(eht_cap
->eht_cap_elem
));
62 pos
+= sizeof(eht_cap
->eht_cap_elem
);
64 /* Copy MCS/NSS which depends on the peer capabilities */
65 memset(&eht_cap
->eht_mcs_nss_supp
, 0,
66 sizeof(eht_cap
->eht_mcs_nss_supp
));
67 memcpy(&eht_cap
->eht_mcs_nss_supp
, pos
, mcs_nss_size
);
70 memcpy(eht_cap
->eht_ppe_thres
,
71 &eht_cap_ie_elem
->optional
[mcs_nss_size
],
74 eht_cap
->has_eht
= true;
76 link_sta
->cur_max_bandwidth
= ieee80211_sta_cap_rx_bw(link_sta
);
77 link_sta
->pub
->bandwidth
= ieee80211_sta_cur_vht_bw(link_sta
);
79 switch (u8_get_bits(eht_cap
->eht_cap_elem
.mac_cap_info
[0],
80 IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK
)) {
81 case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454
:
82 link_sta
->pub
->agg
.max_amsdu_len
=
83 IEEE80211_MAX_MPDU_LEN_VHT_11454
;
85 case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991
:
86 link_sta
->pub
->agg
.max_amsdu_len
=
87 IEEE80211_MAX_MPDU_LEN_VHT_7991
;
89 case IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895
:
91 link_sta
->pub
->agg
.max_amsdu_len
=
92 IEEE80211_MAX_MPDU_LEN_VHT_3895
;
96 ieee80211_sta_recalc_aggregates(&link_sta
->sta
->sta
);