diff options
| author | Johannes Berg <johannes.berg@intel.com> | 2026-07-15 21:08:34 +0300 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-07-21 19:18:52 +0200 |
| commit | 410d70acf9ca73fdf370e1eb7e1da64e486dcbb5 (patch) | |
| tree | 481e447fa21b3d624fdb978db7ef0854e9344cfe | |
| parent | a3262f61d102eaae81048d10eb0aadcc623ea026 (diff) | |
| download | linux-next-410d70acf9ca73fdf370e1eb7e1da64e486dcbb5.tar.gz linux-next-410d70acf9ca73fdf370e1eb7e1da64e486dcbb5.zip | |
wifi: use UHR operation field presence bits
The spec originally had the idea that the fact that it's
a beacon frame determines the (non-)presence of the values,
but added presence bits in D1.4. Use those presence bits in
addition to the enable bits.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715210407.3b1a79b0d002.Iaa762c55b4b6dc63d55f2d7b8b42acd47e640d50@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
| -rw-r--r-- | include/linux/ieee80211-uhr.h | 44 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
| -rw-r--r-- | net/mac80211/parse.c | 4 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 2 |
4 files changed, 25 insertions, 28 deletions
diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h index 597c9e559261..665d4b3a5b41 100644 --- a/include/linux/ieee80211-uhr.h +++ b/include/linux/ieee80211-uhr.h @@ -17,6 +17,11 @@ #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004 #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008 #define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070 +#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0080 +#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0100 +#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0200 +#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0400 +#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x0800 struct ieee80211_uhr_operation { __le16 params; @@ -265,8 +270,7 @@ struct ieee80211_uhr_p_edca_info { __le16 params; } __packed; -static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, - bool beacon) +static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len) { const struct ieee80211_uhr_operation *oper = (const void *)data; u8 needed = sizeof(*oper); @@ -274,19 +278,15 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, if (len < needed) return false; - /* nothing else present in beacons */ - if (beacon) - return true; - /* DPS Operation Parameters (fixed 4 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) { needed += sizeof(struct ieee80211_uhr_dps_info); if (len < needed) return false; } /* NPCA Operation Parameters (fixed 4 bytes + optional 2 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)(data + needed); @@ -303,14 +303,14 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, } /* P-EDCA Operation Parameters (fixed 3 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) { needed += sizeof(struct ieee80211_uhr_p_edca_info); if (len < needed) return false; } /* DBE Operation Parameters (fixed 1 byte + optional 2 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES)) { const struct ieee80211_uhr_dbe_info *dbe = (const void *)(data + needed); @@ -329,19 +329,19 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, return len >= needed; } -/* - * Note: cannot call this on the element coming from a beacon, - * must ensure ieee80211_uhr_oper_size_ok(..., false) first - */ +/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */ static inline const struct ieee80211_uhr_npca_info * ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper) { const u8 *pos = oper->variable; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES))) + return NULL; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA))) return NULL; - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info); return (const void *)pos; @@ -360,22 +360,22 @@ ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper) return npca->dis_subch_bmap; } -/* - * Note: cannot call this on the element coming from a beacon, - * must ensure ieee80211_uhr_oper_size_ok(..., false) first - */ +/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */ static inline const struct ieee80211_uhr_dbe_info * ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper) { const u8 *pos = oper->variable; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES))) + return NULL; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA))) return NULL; - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info); - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)pos; pos += sizeof(*npca); @@ -383,7 +383,7 @@ ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper) pos += sizeof(npca->dis_subch_bmap[0]); } - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) pos += sizeof(struct ieee80211_uhr_p_edca_info); return (const void *)pos; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1afdb610dff2..c4590c4a56b0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1701,8 +1701,7 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link, if (stype != IEEE80211_STYPE_BEACON && chanreq.oper.npca_chan && elems->uhr_operation && ieee80211_uhr_oper_size_ok((const void *)elems->uhr_operation, - elems->uhr_operation_len, - false)) { + elems->uhr_operation_len)) { const struct ieee80211_uhr_npca_info *npca; struct ieee80211_bss_npca_params params = {}; diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c index c2f2f78f2b4f..cb2be167cde7 100644 --- a/net/mac80211/parse.c +++ b/net/mac80211/parse.c @@ -209,9 +209,7 @@ ieee80211_parse_extension_element(u32 *crc, if (params->mode < IEEE80211_CONN_MODE_UHR) break; calc_crc = true; - if (ieee80211_uhr_oper_size_ok(data, len, - params->type == (IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_BEACON))) { + if (ieee80211_uhr_oper_size_ok(data, len)) { elems->uhr_operation = data; elems->uhr_operation_len = len; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 242071ad10d6..5fa70974d57c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -441,7 +441,7 @@ static int validate_uhr_operation(const struct nlattr *attr, const u8 *data = nla_data(attr); unsigned int len = nla_len(attr); - if (!ieee80211_uhr_oper_size_ok(data, len, false)) + if (!ieee80211_uhr_oper_size_ok(data, len)) return -EINVAL; return 0; } |
