mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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>
This commit is contained in:
@@ -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;
|
||||
|
||||
+1
-2
@@ -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 = {};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user