mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
wifi: mac80211: update UHR capabilities field order
Since 802.11bn D1.4 the DBE capabilities are after the PHY capabilities, not between MAC and PHY, adjust the code accordingly. Also add a struct for DBE capabilities and use it for checking the correct length instead of hard-coding the lengths. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260428103657.b40af50f182d.I75306a092dc2c8a9eb7276160f0b7144b4846d18@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -372,6 +372,12 @@ ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper)
|
||||
#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES 0x08
|
||||
#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES 0x10
|
||||
|
||||
struct ieee80211_uhr_cap_dbe {
|
||||
u8 cap;
|
||||
/* present 0, 1 or 2 times depending on _PRES bits */
|
||||
struct ieee80211_eht_mcs_nss_supp_bw eht_mcs_map[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum ieee80211_uhr_dbe_max_supported_bw - DBE Maximum Supported Bandwidth
|
||||
*
|
||||
@@ -394,12 +400,6 @@ struct ieee80211_uhr_cap_mac {
|
||||
u8 mac_cap[5];
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_uhr_cap {
|
||||
struct ieee80211_uhr_cap_mac mac;
|
||||
/* DBE, PHY capabilities */
|
||||
u8 variable[];
|
||||
} __packed;
|
||||
|
||||
#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x01
|
||||
#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x02
|
||||
#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x04
|
||||
@@ -413,11 +413,18 @@ struct ieee80211_uhr_cap_phy {
|
||||
u8 cap;
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_uhr_cap {
|
||||
struct ieee80211_uhr_cap_mac mac;
|
||||
struct ieee80211_uhr_cap_phy phy;
|
||||
/* optional DBE capabilities */
|
||||
u8 variable[];
|
||||
} __packed;
|
||||
|
||||
static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len,
|
||||
bool from_ap)
|
||||
{
|
||||
const struct ieee80211_uhr_cap *cap = (const void *)data;
|
||||
size_t needed = sizeof(*cap) + sizeof(struct ieee80211_uhr_cap_phy);
|
||||
size_t needed = sizeof(*cap);
|
||||
|
||||
if (len < needed)
|
||||
return false;
|
||||
@@ -427,44 +434,24 @@ static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len,
|
||||
* in the UHR MAC Capabilities Information field.
|
||||
*/
|
||||
if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) {
|
||||
u8 dbe;
|
||||
const struct ieee80211_uhr_cap_dbe *dbe;
|
||||
|
||||
needed += 1;
|
||||
needed += sizeof(struct ieee80211_uhr_cap_dbe);
|
||||
if (len < needed)
|
||||
return false;
|
||||
|
||||
dbe = cap->variable[0];
|
||||
dbe = (const void *)cap->variable;
|
||||
|
||||
if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES)
|
||||
needed += 3;
|
||||
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES)
|
||||
needed += sizeof(dbe->eht_mcs_map[0]);
|
||||
|
||||
if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES)
|
||||
needed += 3;
|
||||
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES)
|
||||
needed += sizeof(dbe->eht_mcs_map[0]);
|
||||
}
|
||||
|
||||
return len >= needed;
|
||||
}
|
||||
|
||||
static inline const struct ieee80211_uhr_cap_phy *
|
||||
ieee80211_uhr_phy_cap(const struct ieee80211_uhr_cap *cap, bool from_ap)
|
||||
{
|
||||
u8 offs = 0;
|
||||
|
||||
if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) {
|
||||
u8 dbe = cap->variable[0];
|
||||
|
||||
offs += 1;
|
||||
|
||||
if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES)
|
||||
offs += 3;
|
||||
|
||||
if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES)
|
||||
offs += 3;
|
||||
}
|
||||
|
||||
return (const void *)&cap->variable[offs];
|
||||
}
|
||||
|
||||
#define IEEE80211_SMD_INFO_CAPA_DL_DATA_FWD 0x01
|
||||
#define IEEE80211_SMD_INFO_CAPA_MAX_NUM_PREP 0x0E
|
||||
#define IEEE80211_SMD_INFO_CAPA_TYPE 0x10
|
||||
|
||||
+1
-2
@@ -1463,8 +1463,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
|
||||
if (supp_uhr)
|
||||
local->scan_ies_len +=
|
||||
3 + sizeof(struct ieee80211_uhr_cap) +
|
||||
sizeof(struct ieee80211_uhr_cap_phy);
|
||||
3 + sizeof(struct ieee80211_uhr_cap);
|
||||
|
||||
if (!local->ops->hw_scan) {
|
||||
/* For hw_scan, driver needs to set these up. */
|
||||
|
||||
+1
-2
@@ -2225,8 +2225,7 @@ ieee80211_link_common_elems_size(struct ieee80211_sub_if_data *sdata,
|
||||
sizeof(struct ieee80211_eht_mcs_nss_supp) +
|
||||
IEEE80211_EHT_PPE_THRES_MAX_LEN;
|
||||
|
||||
size += 2 + 1 + sizeof(struct ieee80211_uhr_cap) +
|
||||
sizeof(struct ieee80211_uhr_cap_phy);
|
||||
size += 2 + 1 + sizeof(struct ieee80211_uhr_cap);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
+1
-4
@@ -15,7 +15,6 @@ ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata,
|
||||
struct link_sta_info *link_sta)
|
||||
{
|
||||
struct ieee80211_sta_uhr_cap *sta_uhr_cap = &link_sta->pub->uhr_cap;
|
||||
bool from_ap;
|
||||
|
||||
memset(sta_uhr_cap, 0, sizeof(*sta_uhr_cap));
|
||||
|
||||
@@ -23,8 +22,6 @@ ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
|
||||
sta_uhr_cap->has_uhr = true;
|
||||
|
||||
sta_uhr_cap->mac = uhr_cap->mac;
|
||||
from_ap = sdata->vif.type == NL80211_IFTYPE_STATION;
|
||||
sta_uhr_cap->phy = *ieee80211_uhr_phy_cap(uhr_cap, from_ap);
|
||||
sta_uhr_cap->phy = uhr_cap->phy;
|
||||
}
|
||||
|
||||
+1
-2
@@ -4641,8 +4641,7 @@ int ieee80211_put_uhr_cap(struct sk_buff *skb,
|
||||
if (!uhr_cap)
|
||||
return 0;
|
||||
|
||||
len = 2 + 1 + sizeof(struct ieee80211_uhr_cap) +
|
||||
sizeof(struct ieee80211_uhr_cap_phy);
|
||||
len = 2 + 1 + sizeof(struct ieee80211_uhr_cap);
|
||||
|
||||
if (skb_tailroom(skb) < len)
|
||||
return -ENOBUFS;
|
||||
|
||||
Reference in New Issue
Block a user