]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
authorKarthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com>
Wed, 4 Mar 2026 08:53:42 +0000 (14:23 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 4 Mar 2026 10:50:03 +0000 (11:50 +0100)
Add UHR Operation and Capability definitions and parsing helpers:

- Define ieee80211_uhr_dps_info, ieee80211_uhr_dbe_info,
  ieee80211_uhr_p_edca_info with masks.
- Update ieee80211_uhr_oper_size_ok() to account for optional
  DPS/DBE/P-EDCA blocks.
- Move NPCA pointer position after DPS Operation Parameter if it is
  present in ieee80211_uhr_oper_size_ok().
- Move NPCA pointer position after DPS info if it is present in
  ieee80211_uhr_npca_info().

Signed-off-by: Karthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com>
Link: https://patch.msgid.link/20260304085343.1093993-2-karthikeyan.kathirvel@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/linux/ieee80211-uhr.h

index 132acced7d798247eda400a814df60947a10e2a8..9729d23e47667df7eae09e5fc5bc934e2ec3ee17 100644 (file)
@@ -29,11 +29,216 @@ struct ieee80211_uhr_operation {
 #define IEEE80211_UHR_NPCA_PARAMS_MOPLEN               0x00400000
 #define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES  0x00800000
 
+/**
+ * struct ieee80211_uhr_npca_info - npca operation information
+ *
+ * This structure is the "NPCA Operation Parameters field format" of "UHR
+ * Operation Element" fields as described in P802.11bn_D1.3
+ * subclause 9.4.2.353. See Figure 9-aa4.
+ *
+ * Refer to IEEE80211_UHR_NPCA*
+ * @params:
+ *     NPCA Primary Channel - NPCA primary channel
+ *     NPCA_Min Duration Threshold - Minimum duration of inter-BSS activity
+ *     NPCA Switching Delay -
+ *             Time needed by an NPCA AP to switch from the
+ *             BSS primary channel to the NPCA primary channel
+ *             in the unit of 4 µs.
+ *     NPCA Switching Back Delay -
+ *             Time to switch from the NPCA primary channel
+ *             to the BSS primary channel in the unit of 4 µs.
+ *     NPCA Initial QSRC -
+ *             Initialize the EDCAF QSRC[AC] variables
+ *             when an NPCA STA in the BSS
+ *             switches to NPCA operation.
+ *     NPCA MOPLEN -
+ *             Indicates which conditions can be used to
+ *             initiate an NPCA operation,
+ *             1 -> both PHYLEN NPCA operation and MOPLEN
+ *             NPCA operation are
+ *             permitted in the BSS
+ *             0 -> only PHYLEN NPCA operation is allowed in the BSS.
+ *     NPCA Disabled Subchannel Bitmap Present -
+ *             Indicates whether the NPCA Disabled Subchannel
+ *             Bitmap field is present. A 1 in this field indicates that
+ *             the NPCA Disabled Subchannel Bitmap field is present
+ * @dis_subch_bmap:
+ *             A bit in the bitmap that lies within the BSS bandwidth is set
+ *             to 1 to indicate that the corresponding 20 MHz subchannel is
+ *             punctured and is set to 0 to indicate that the corresponding
+ *             20 MHz subchannel is not punctured. A bit in the bitmap that
+ *             falls outside of the BSS bandwidth is reserved. This field is
+ *             present when the value of the NPCA Disabled Subchannel Bitmap
+ *             Field Present field is equal to 1, and not present, otherwise
+ */
 struct ieee80211_uhr_npca_info {
        __le32 params;
        __le16 dis_subch_bmap[];
 } __packed;
 
+#define IEEE80211_UHR_DPS_PADDING_DELAY                        0x0000003F
+#define IEEE80211_UHR_DPS_TRANSITION_DELAY             0x00003F00
+#define IEEE80211_UHR_DPS_ICF_REQUIRED                 0x00010000
+#define IEEE80211_UHR_DPS_PARAMETERIZED_FLAG           0x00020000
+#define IEEE80211_UHR_DPS_LC_MODE_BW                   0x001C0000
+#define IEEE80211_UHR_DPS_LC_MODE_NSS                  0x01E00000
+#define IEEE80211_UHR_DPS_LC_MODE_MCS                  0x1E000000
+#define IEEE80211_UHR_DPS_MOBILE_AP_DPS_STATIC_HCM     0x20000000
+
+/**
+ * struct ieee80211_uhr_dps_info - DPS operation information
+ *
+ * This structure is the "DPS Operation Parameter field" of "UHR
+ * Operation Element" fields as described in P802.11bn_D1.3
+ * subclause 9.4.1.87. See Figure 9-207u.
+ *
+ * Refer to IEEE80211_UHR_DPS*
+ * @params:
+ *     DPS Padding Delay -
+ *             Indicates the minimum MAC padding
+ *             duration that is required by a DPS STA
+ *             in an ICF to cause the STA to transition
+ *             from the lower capability mode to the
+ *             higher capability mode. The DPS Padding
+ *             Delay field is in units of 4 µs.
+ *     DPS Transition Delay -
+ *             Indicates the amount of time required by a
+ *             DPS STA to transition from the higher
+ *             capability mode to the lower capability
+ *             mode. The DPS Transition Delay field is in
+ *             units of 4 µs.
+ *     ICF Required -
+ *             Indicates when the DPS assisting STA needs
+ *             to transmit an ICF frame to the peer DPS STA
+ *             before performing the frame exchanges with
+ *             the peer DPS STA in a TXOP.
+ *                     1 -> indicates that the transmission of the
+ *                     ICF frame to the peer DPS STA prior to
+ *                     any frame exchange is needed.
+ *                     0 -> ICF transmission before the frame
+ *                     exchanges with the peer DPS STA is only
+ *                     needed if the frame exchange is performed
+ *                     in the HC mode.
+ *     Parameterized Flag -
+ *             0 -> indicates that only 20 MHz, 1 SS,
+ *             non-HT PPDU format with the data
+ *             rate of 6, 12, and 24 Mb/s as the
+ *             default mode are supported by the
+ *             DPS STA in the LC mode
+ *             1 -> indicates that a bandwidth up to the
+ *             bandwidth indicated in the LC Mode
+ *             Bandwidth field, a number of spatial
+ *             streams up to the NSS indicated in
+ *             the LC Mode Nss field, and an MCS up
+ *             to the MCS indicated in the LC Mode
+ *             MCS fields are supported by the DPS
+ *             STA in the LC mode as the
+ *             parameterized mode.
+ *     LC Mode Bandwidth -
+ *             Indicates the maximum bandwidth supported
+ *             by the STA in the LC mode.
+ *     LC Mode NSS -
+ *             Indicates the maximum number of the spatial
+ *             streams supported by the STA in the LC mode.
+ *     LC Mode MCS -
+ *             Indicates the highest MCS supported by the STA
+ *             in the LC mode.
+ *     Mobile AP DPS Static HCM -
+ *             1 -> indicates that it will remain in the DPS high
+ *             capability mode until the next TBTT on that
+ *             link.
+ *             0 -> otherwise.
+ */
+struct ieee80211_uhr_dps_info {
+       __le32 params;
+} __packed;
+
+#define IEEE80211_UHR_DBE_OPER_BANDWIDTH                       0x07
+#define IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP_PRES      0x08
+
+/**
+ * enum ieee80211_uhr_dbe_oper_bw - DBE Operational Bandwidth
+ *
+ * Encoding for the DBE Operational Bandwidth field in the UHR Operation
+ * element (DBE Operation Parameters).
+ *
+ * @IEEE80211_UHR_DBE_OPER_BW_40: 40 MHz operational DBE bandwidth
+ * @IEEE80211_UHR_DBE_OPER_BW_80: 80 MHz operational DBE bandwidth
+ * @IEEE80211_UHR_DBE_OPER_BW_160: 160 MHz operational DBE bandwidth
+ * @IEEE80211_UHR_DBE_OPER_BW_320_1: 320-1 MHz operational DBE bandwidth
+ * @IEEE80211_UHR_DBE_OPER_BW_320_2: 320-2 MHz operational DBE bandwidth
+ */
+enum ieee80211_uhr_dbe_oper_bw {
+       IEEE80211_UHR_DBE_OPER_BW_40 = 1,
+       IEEE80211_UHR_DBE_OPER_BW_80 = 2,
+       IEEE80211_UHR_DBE_OPER_BW_160 = 3,
+       IEEE80211_UHR_DBE_OPER_BW_320_1 = 4,
+       IEEE80211_UHR_DBE_OPER_BW_320_2 = 5,
+};
+
+/**
+ * struct ieee80211_uhr_dbe_info - DBE operation information
+ *
+ * This structure is the "DBE Operation Parameters field" of
+ * "UHR Operation Element" fields as described in P802.11bn_D1.3
+ * subclause 9.4.2.353. See Figure 9-aa6.
+ *
+ * Refer to IEEE80211_UHR_DBE_OPER*
+ * @params:
+ *     B0-B2 - DBE Operational Bandwidth field, see
+ *     "enum ieee80211_uhr_dbe_oper_bw" for values.
+ *     Value 0 is reserved.
+ *     Value 1 indicates 40 MHz operational DBE bandwidth.
+ *     Value 2 indicates 80 MHz operational DBE bandwidth.
+ *     Value 3 indicates 160 MHz operational DBE bandwidth.
+ *     Value 4 indicates 320-1 MHz operational DBE bandwidth.
+ *     Value 5 indicates 320-2 MHz operational DBE bandwidth.
+ *     Values 6 to 7 are reserved.
+ *     B3 - DBE Disabled Subchannel Bitmap Present.
+ * @dis_subch_bmap: DBE Disabled Subchannel Bitmap field is set to indicate
+ *     disabled 20 MHz subchannels within the DBE Bandwidth.
+ */
+struct ieee80211_uhr_dbe_info {
+       u8 params;
+       __le16 dis_subch_bmap[];
+} __packed;
+
+#define IEEE80211_UHR_P_EDCA_ECWMIN            0x0F
+#define IEEE80211_UHR_P_EDCA_ECWMAX            0xF0
+#define IEEE80211_UHR_P_EDCA_AIFSN             0x000F
+#define IEEE80211_UHR_P_EDCA_CW_DS             0x0030
+#define IEEE80211_UHR_P_EDCA_PSRC_THRESHOLD    0x01C0
+#define IEEE80211_UHR_P_EDCA_QSRC_THRESHOLD    0x0600
+
+/**
+ * struct ieee80211_uhr_p_edca_info - P-EDCA operation information
+ *
+ * This structure is the "P-EDCA Operation Parameters field" of
+ * "UHR Operation Element" fields as described in P802.11bn_D1.3
+ * subclause 9.4.2.353. See Figure 9-aa5.
+ *
+ * Refer to IEEE80211_UHR_P_EDCA*
+ * @p_edca_ec: P-EDCA ECWmin and ECWmax.
+ *     These fields indicate the CWmin and CWmax values used by a
+ *     P-EDCA STA during P-EDCA contention.
+ * @params: AIFSN, CW DS, PSRC threshold, and QSRC threshold.
+ *     - The AIFSN field indicates the AIFSN value used by a P-EDCA STA
+ *       during P-EDCA contention.
+ *     - The CW DS field indicates the value used for randomization of the
+ *       transmission slot of the DS-CTS frame. The value 3 is reserved.
+ *       The value 0 indicates that randomization is not enabled.
+ *     - The P-EDCA PSRC threshold field indicates the maximum number of
+ *       allowed consecutive DS-CTS transmissions. The value 0 and values
+ *       greater than 4 are reserved.
+ *     - The P-EDCA QSRC threshold field indicates the value of the
+ *       QSRC[AC_VO] counter required to start P-EDCA contention. The
+ *       value 0 is reserved.
+ */
+struct ieee80211_uhr_p_edca_info {
+       u8 p_edca_ec;
+       __le16 params;
+} __packed;
+
 static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
                                              bool beacon)
 {
@@ -47,19 +252,52 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
        if (beacon)
                return true;
 
-       /* FIXME: DPS, DBE, P-EDCA (consider order, also relative to NPCA) */
+       /* DPS Operation Parameters (fixed 4 bytes) */
+       if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) {
+               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)) {
                const struct ieee80211_uhr_npca_info *npca =
-                       (const void *)oper->variable;
+                       (const void *)(data + needed);
 
                needed += sizeof(*npca);
-
                if (len < needed)
                        return false;
 
-               if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES))
+               if (npca->params &
+                   cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) {
                        needed += sizeof(npca->dis_subch_bmap[0]);
+                       if (len < needed)
+                               return false;
+               }
+       }
+
+       /* P-EDCA Operation Parameters (fixed 3 bytes) */
+       if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) {
+               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)) {
+               const struct ieee80211_uhr_dbe_info *dbe =
+                       (const void *)(data + needed);
+
+               needed += sizeof(*dbe);
+               if (len < needed)
+                       return false;
+
+               if (dbe->params &
+                   IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP_PRES) {
+                       needed += sizeof(dbe->dis_subch_bmap[0]);
+                       if (len < needed)
+                               return false;
+               }
        }
 
        return len >= needed;
@@ -72,12 +310,15 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
 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_ENA)))
                return NULL;
 
-       /* FIXME: DPS */
+       if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA))
+               pos += sizeof(struct ieee80211_uhr_dps_info);
 
-       return (const void *)oper->variable;
+       return (const void *)pos;
 }
 
 static inline const __le16 *
@@ -131,6 +372,24 @@ 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
 
+/**
+ * enum ieee80211_uhr_dbe_max_supported_bw - DBE Maximum Supported Bandwidth
+ *
+ * As per spec P802.11bn_D1.3 "Table 9-bb5—Encoding of the DBE Maximum
+ * Supported Bandwidth field".
+ *
+ * @IEEE80211_UHR_DBE_MAX_BW_40: Indicates 40 MHz DBE max supported bw
+ * @IEEE80211_UHR_DBE_MAX_BW_80: Indicates 80 MHz DBE max supported bw
+ * @IEEE80211_UHR_DBE_MAX_BW_160: Indicates 160 MHz DBE max supported bw
+ * @IEEE80211_UHR_DBE_MAX_BW_320: Indicates 320 MHz DBE max supported bw
+ */
+enum ieee80211_uhr_dbe_max_supported_bw {
+       IEEE80211_UHR_DBE_MAX_BW_40 = 1,
+       IEEE80211_UHR_DBE_MAX_BW_80 = 2,
+       IEEE80211_UHR_DBE_MAX_BW_160 = 3,
+       IEEE80211_UHR_DBE_MAX_BW_320 = 4,
+};
+
 struct ieee80211_uhr_cap_mac {
        u8 mac_cap[5];
 } __packed;