* [PATCH wireless-next v4 00/02] wifi: ieee80211/mac80211: Add UHR (802.11bn) Capability and Operation parsing helpers
@ 2026-02-17 5:47 Karthikeyan Kathirvel
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
2026-02-17 5:47 ` [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver Karthikeyan Kathirvel
0 siblings, 2 replies; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-02-17 5:47 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, ath12k, Karthikeyan Kathirvel
This series covers support for UHR capability and operation (11bn)
parsing helpers for DPS/DBE/P-EDCA, and adds mac80211 hwsim changes.
The code changes are based on the IEEE 802.11bn Draft P802.11bn/D1.3.
There may be changes in the code to adopt upcoming 11bn spec changes.
---
v4:
- Addressed Pablo's comment on mac80211_hwsim
v3:
- Addressed Johannes's comments
- Removed reserved macros and unwanted
IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP
v2:
- Rebased the changes on top of Johannes's initial UHR commits
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 288 ++++++++++++++++++
include/linux/ieee80211-uhr.h | 239 ++++++++++++++-
2 files changed, 520 insertions(+), 7 deletions(-)
base-commit: 37a93dd5c49b5fda807fd204edf2547c3493319c
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-17 5:47 [PATCH wireless-next v4 00/02] wifi: ieee80211/mac80211: Add UHR (802.11bn) Capability and Operation parsing helpers Karthikeyan Kathirvel
@ 2026-02-17 5:47 ` Karthikeyan Kathirvel
2026-02-24 16:32 ` Johannes Berg
` (2 more replies)
2026-02-17 5:47 ` [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver Karthikeyan Kathirvel
1 sibling, 3 replies; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-02-17 5:47 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, ath12k, Karthikeyan Kathirvel
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>
---
include/linux/ieee80211-uhr.h | 252 +++++++++++++++++++++++++++++++++-
1 file changed, 246 insertions(+), 6 deletions(-)
diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h
index 132acced7d79..e9f365ffcdac 100644
--- a/include/linux/ieee80211-uhr.h
+++ b/include/linux/ieee80211-uhr.h
@@ -29,11 +29,196 @@ 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*
+ * @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 -> indicate 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 -> indicate 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 -> indicate 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 dps_params;
+} __packed;
+
+#define IEEE80211_UHR_DBE_OPER_BANDWIDTH 0x07
+#define IEEE80211_UHR_DBE_OPER_DIS_SUBCHANNEL_BITMAP_PRES 0x08
+
+/**
+ * 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*
+ * @dbe_params:
+ * B0-B2 - DBE Bandwidth field is set to indicate
+ * expanded bandwidth for DBE mode
+ * Value 0 is reserved.
+ * Set to 1 to indicate 40 MHz DBE bandwidth.
+ * Set to 2 to indicate 80 MHz DBE bandwidth.
+ * Set to 3 to indicate 160 MHz DBE bandwidth.
+ * Set to 4 to indicate 320-1 MHz DBE bandwidth.
+ * Set to 5 to indicate 320-2 MHz 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 dbe_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: The P-EDCA ECWmin, P-EDCA and ECWmax
+ * fields indicate the CWmin and CWmax
+ * value that are used by a P-EDCA STA during P-EDCA contention.
+ * @p_edca_params: The AIFSN field indicate the AIFSN value that are
+ * used by a P-EDCA STA during P-EDCA contention.
+ * The CW DS field indicate the value used
+ * for the randomization of the transmission slot of the DS-CTS
+ * frame. The value 3 is reserved. The value 0 indicate that
+ * randomization 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 to be allowed to start P-EDCA contention.
+ * The value 0 is reserved.
+ */
+struct ieee80211_uhr_p_edca_info {
+ u8 p_edca_ec;
+ __le16 p_edca_params;
+} __packed;
+
static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
bool beacon)
{
@@ -47,19 +232,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->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 +290,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 +352,25 @@ 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_dbe_bandwidth - DBE Bandwidth
+ *
+ * As per spec P802.11bn_D1.3 "Table 9-bb5—Encoding of the DBE Maximum
+ * Supported Bandwidth field"
+ *
+ * @IEEE80211_DBE_BANDWIDTH_40MHZ: Indicate 40 MHz DBE bandwidth
+ * @IEEE80211_DBE_BANDWIDTH_80MHZ: Indicate 80 MHz DBE bandwidth
+ * @IEEE80211_DBE_BANDWIDTH_160MHZ: Indicate 160 MHz DBE bandwidth
+ * @IEEE80211_DBE_BANDWIDTH_320MHZ: Indicate 320 MHz DBE bandwidth
+ *
+ */
+enum ieee80211_dbe_bandwidth {
+ IEEE80211_DBE_BANDWIDTH_40MHZ = 1,
+ IEEE80211_DBE_BANDWIDTH_80MHZ = 2,
+ IEEE80211_DBE_BANDWIDTH_160MHZ = 3,
+ IEEE80211_DBE_BANDWIDTH_320MHZ = 4,
+};
+
struct ieee80211_uhr_cap_mac {
u8 mac_cap[5];
} __packed;
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver
2026-02-17 5:47 [PATCH wireless-next v4 00/02] wifi: ieee80211/mac80211: Add UHR (802.11bn) Capability and Operation parsing helpers Karthikeyan Kathirvel
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
@ 2026-02-17 5:47 ` Karthikeyan Kathirvel
2026-02-24 16:20 ` Johannes Berg
1 sibling, 1 reply; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-02-17 5:47 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, ath12k, Karthikeyan Kathirvel
Add UHR capabilities for bringing up the interface in UHR mode.
This is required to validate UHR test cases.
Signed-off-by: Karthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 285 ++++++++++++++++++
1 file changed, 285 insertions(+)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 4d9f5f87e814..7af429e589ff 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -4478,6 +4478,51 @@ static const struct ieee80211_sband_iftype_data sband_capa_2ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
{
.types_mask = BIT(NL80211_IFTYPE_AP) |
@@ -4586,6 +4631,52 @@ static const struct ieee80211_sband_iftype_data sband_capa_2ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DBE_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
#ifdef CONFIG_MAC80211_MESH
{
@@ -4755,6 +4846,53 @@ static const struct ieee80211_sband_iftype_data sband_capa_5ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
{
.types_mask = BIT(NL80211_IFTYPE_AP) |
@@ -4880,6 +5018,54 @@ static const struct ieee80211_sband_iftype_data sband_capa_5ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DBE_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
#ifdef CONFIG_MAC80211_MESH
{
@@ -5073,6 +5259,55 @@ static const struct ieee80211_sband_iftype_data sband_capa_6ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
{
.types_mask = BIT(NL80211_IFTYPE_AP) |
@@ -5219,6 +5454,56 @@ static const struct ieee80211_sband_iftype_data sband_capa_6ghz[] = {
},
/* PPE threshold information is not supported */
},
+ .uhr_cap = {
+ .has_uhr = true,
+ .mac = {
+ .mac_cap[0] =
+ IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
+ IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP |
+ IEEE80211_UHR_MAC_CAP0_NPCA_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP |
+ IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP |
+ IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP,
+ .mac_cap[1] =
+ IEEE80211_UHR_MAC_CAP1_DSO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DBE_SUPP |
+ IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP |
+ IEEE80211_UHR_MAC_CAP1_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
+ IEEE80211_UHR_MAC_CAP1_DUO_SUPP,
+ .mac_cap[2] =
+ IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP |
+ IEEE80211_UHR_MAC_CAP2_AOM_SUPP |
+ IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP |
+ IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP |
+ IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG |
+ IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW,
+ .mac_cap[3] =
+ IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH |
+ IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV |
+ IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW,
+ .mac_cap[4] =
+ IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH |
+ IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS |
+ IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE |
+ IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP,
+ },
+ .phy = {
+ .cap =
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 |
+ IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 |
+ IEEE80211_UHR_PHY_CAP_ELR_RX |
+ IEEE80211_UHR_PHY_CAP_ELR_TX,
+ },
+ },
},
#ifdef CONFIG_MAC80211_MESH
{
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver
2026-02-17 5:47 ` [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver Karthikeyan Kathirvel
@ 2026-02-24 16:20 ` Johannes Berg
2026-03-03 11:41 ` Karthikeyan Kathirvel
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2026-02-24 16:20 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
On Tue, 2026-02-17 at 11:17 +0530, Karthikeyan Kathirvel wrote:
>
> + .uhr_cap = {
> + .has_uhr = true,
> + .mac = {
> + .mac_cap[0] =
> + IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
> + IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
I'm really not sure we should claim all of this, e.g. DPS assist, right
now.
Also, I think you really mixed this up - a regular AP shouldn't claim
DPS below (only mobile AP), but this here station should probably not
normally claim DPS assist?
Just as examples! There are other issues like this such as:
> + IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
I don't think the station should claim AP PUO support.
Certainly not an exhaustive list, ELR also seems wrong, etc.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
@ 2026-02-24 16:32 ` Johannes Berg
2026-03-03 10:11 ` Karthikeyan Kathirvel
2026-02-24 16:42 ` Johannes Berg
2026-02-24 20:47 ` Johannes Berg
2 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2026-02-24 16:32 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
On Tue, 2026-02-17 at 11:17 +0530, Karthikeyan Kathirvel wrote:
>
> + * Refer to IEEE80211_UHR_P_EDCA*
> + * @p_edca_ec: The P-EDCA ECWmin, P-EDCA and ECWmax
that seems unclear?
> + * @p_edca_params: The AIFSN field indicate the AIFSN value that are
"indicates", "value that is used"? I think it's one? Or "values that are
used"
> + * used by a P-EDCA STA during P-EDCA contention.
> + * The CW DS field indicate the value used
indicates
> + * for the randomization of the transmission slot of the DS-CTS
> + * frame. The value 3 is reserved. The value 0 indicate that
indicates
> + * randomization 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 to be allowed to start P-EDCA contention.
> + * The value 0 is reserved.
> + */
> +struct ieee80211_uhr_p_edca_info {
> + u8 p_edca_ec;
> + __le16 p_edca_params;
> +} __packed;
> +
> static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
> bool beacon)
> {
> @@ -47,19 +232,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->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 +290,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 +352,25 @@ 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_dbe_bandwidth - DBE Bandwidth
> + *
> + * As per spec P802.11bn_D1.3 "Table 9-bb5—Encoding of the DBE Maximum
> + * Supported Bandwidth field"
> + *
> + * @IEEE80211_DBE_BANDWIDTH_40MHZ: Indicate 40 MHz DBE bandwidth
> + * @IEEE80211_DBE_BANDWIDTH_80MHZ: Indicate 80 MHz DBE bandwidth
> + * @IEEE80211_DBE_BANDWIDTH_160MHZ: Indicate 160 MHz DBE bandwidth
> + * @IEEE80211_DBE_BANDWIDTH_320MHZ: Indicate 320 MHz DBE bandwidth
> + *
> + */
> +enum ieee80211_dbe_bandwidth {
> + IEEE80211_DBE_BANDWIDTH_40MHZ = 1,
> + IEEE80211_DBE_BANDWIDTH_80MHZ = 2,
> + IEEE80211_DBE_BANDWIDTH_160MHZ = 3,
> + IEEE80211_DBE_BANDWIDTH_320MHZ = 4,
> +};
> +
> struct ieee80211_uhr_cap_mac {
> u8 mac_cap[5];
> } __packed;
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
2026-02-24 16:32 ` Johannes Berg
@ 2026-02-24 16:42 ` Johannes Berg
2026-02-24 17:38 ` Johannes Berg
2026-02-24 20:47 ` Johannes Berg
2 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2026-02-24 16:42 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
Oh, another thing
> + * @dbe_params:
> + * B0-B2 - DBE Bandwidth field is set to indicate
> + * expanded bandwidth for DBE mode
> + * Value 0 is reserved.
> + * Set to 1 to indicate 40 MHz DBE bandwidth.
> + * Set to 2 to indicate 80 MHz DBE bandwidth.
> + * Set to 3 to indicate 160 MHz DBE bandwidth.
> + * Set to 4 to indicate 320-1 MHz DBE bandwidth.
> + * Set to 5 to indicate 320-2 MHz DBE bandwidth.
> + * Values 6 to 7 are reserved.
> + * B3 - DBE Disabled Subchannel Bitmap Present.
Seems we should have an enum for the possible bandwidth values?
And also, it's confusing:
> +/**
> + * enum ieee80211_dbe_bandwidth - DBE Bandwidth
because this one is just "DBE Bandwidth" - I think you should rename
this to "DBE Maximum Supported Bandwidth" or something related, and add
the operational, since there's a 4/5 difference with 320 vs. 320-1/320-2
(the latter in UHR operation)
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-24 16:42 ` Johannes Berg
@ 2026-02-24 17:38 ` Johannes Berg
2026-03-03 10:11 ` Karthikeyan Kathirvel
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2026-02-24 17:38 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
On Tue, 2026-02-24 at 17:42 +0100, Johannes Berg wrote:
> Oh, another thing
>
> > + * @dbe_params:
> > + * B0-B2 - DBE Bandwidth field is set to indicate
> > + * expanded bandwidth for DBE mode
> > + * Value 0 is reserved.
> > + * Set to 1 to indicate 40 MHz DBE bandwidth.
> > + * Set to 2 to indicate 80 MHz DBE bandwidth.
> > + * Set to 3 to indicate 160 MHz DBE bandwidth.
> > + * Set to 4 to indicate 320-1 MHz DBE bandwidth.
> > + * Set to 5 to indicate 320-2 MHz DBE bandwidth.
> > + * Values 6 to 7 are reserved.
> > + * B3 - DBE Disabled Subchannel Bitmap Present.
>
> Seems we should have an enum for the possible bandwidth values?
How about this?
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_32_2 = 5,
};
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
2026-02-24 16:32 ` Johannes Berg
2026-02-24 16:42 ` Johannes Berg
@ 2026-02-24 20:47 ` Johannes Berg
2 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2026-02-24 20:47 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
On Tue, 2026-02-17 at 11:17 +0530, Karthikeyan Kathirvel wrote:
>
> +/**
> + * 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*
> + * @dps_params:
I think it being in a DPS specific struct, we can drop the dps_ prefix
here?
> +/**
> + * 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*
> + * @dbe_params:
same here
> +/**
> + * 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: The P-EDCA ECWmin, P-EDCA and ECWmax
> + * fields indicate the CWmin and CWmax
> + * value that are used by a P-EDCA STA during P-EDCA contention.
> + * @p_edca_params: The AIFSN field indicate the AIFSN value that are
and here
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-24 16:32 ` Johannes Berg
@ 2026-03-03 10:11 ` Karthikeyan Kathirvel
0 siblings, 0 replies; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-03-03 10:11 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, ath12k
On 2/24/2026 10:02 PM, Johannes Berg wrote:
> On Tue, 2026-02-17 at 11:17 +0530, Karthikeyan Kathirvel wrote:
>>
>> + * Refer to IEEE80211_UHR_P_EDCA*
>> + * @p_edca_ec: The P-EDCA ECWmin, P-EDCA and ECWmax
>
> that seems unclear?
>
>
>> + * @p_edca_params: The AIFSN field indicate the AIFSN value that are
>
> "indicates", "value that is used"? I think it's one? Or "values that are
> used"
>
>> + * used by a P-EDCA STA during P-EDCA contention.
>> + * The CW DS field indicate the value used
>
> indicates
>
>> + * for the randomization of the transmission slot of the DS-CTS
>> + * frame. The value 3 is reserved. The value 0 indicate that
>
> indicates
>
Will address this grammatical errors in next version
>> + * randomization 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 to be allowed to start P-EDCA contention.
>> + * The value 0 is reserved.
>> + */
>> +struct ieee80211_uhr_p_edca_info {
>> + u8 p_edca_ec;
>> + __le16 p_edca_params;
>> +} __packed;
>> +
>> static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
>> bool beacon)
>> {
>> @@ -47,19 +232,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->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 +290,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 +352,25 @@ 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_dbe_bandwidth - DBE Bandwidth
>> + *
>> + * As per spec P802.11bn_D1.3 "Table 9-bb5—Encoding of the DBE Maximum
>> + * Supported Bandwidth field"
>> + *
>> + * @IEEE80211_DBE_BANDWIDTH_40MHZ: Indicate 40 MHz DBE bandwidth
>> + * @IEEE80211_DBE_BANDWIDTH_80MHZ: Indicate 80 MHz DBE bandwidth
>> + * @IEEE80211_DBE_BANDWIDTH_160MHZ: Indicate 160 MHz DBE bandwidth
>> + * @IEEE80211_DBE_BANDWIDTH_320MHZ: Indicate 320 MHz DBE bandwidth
>> + *
>> + */
>> +enum ieee80211_dbe_bandwidth {
>> + IEEE80211_DBE_BANDWIDTH_40MHZ = 1,
>> + IEEE80211_DBE_BANDWIDTH_80MHZ = 2,
>> + IEEE80211_DBE_BANDWIDTH_160MHZ = 3,
>> + IEEE80211_DBE_BANDWIDTH_320MHZ = 4,
>> +};
>> +
>> struct ieee80211_uhr_cap_mac {
>> u8 mac_cap[5];
>> } __packed;
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing
2026-02-24 17:38 ` Johannes Berg
@ 2026-03-03 10:11 ` Karthikeyan Kathirvel
0 siblings, 0 replies; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-03-03 10:11 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, ath12k
On 2/24/2026 11:08 PM, Johannes Berg wrote:
> On Tue, 2026-02-24 at 17:42 +0100, Johannes Berg wrote:
>> Oh, another thing
>>
>>> + * @dbe_params:
>>> + * B0-B2 - DBE Bandwidth field is set to indicate
>>> + * expanded bandwidth for DBE mode
>>> + * Value 0 is reserved.
>>> + * Set to 1 to indicate 40 MHz DBE bandwidth.
>>> + * Set to 2 to indicate 80 MHz DBE bandwidth.
>>> + * Set to 3 to indicate 160 MHz DBE bandwidth.
>>> + * Set to 4 to indicate 320-1 MHz DBE bandwidth.
>>> + * Set to 5 to indicate 320-2 MHz DBE bandwidth.
>>> + * Values 6 to 7 are reserved.
>>> + * B3 - DBE Disabled Subchannel Bitmap Present.
>>
>> Seems we should have an enum for the possible bandwidth values?
>
> How about this?
>
> 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_32_2 = 5,
> };
>
>
> johannes
Sure will add like this.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver
2026-02-24 16:20 ` Johannes Berg
@ 2026-03-03 11:41 ` Karthikeyan Kathirvel
2026-03-03 11:44 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Karthikeyan Kathirvel @ 2026-03-03 11:41 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, ath12k
On 2/24/2026 9:50 PM, Johannes Berg wrote:
> On Tue, 2026-02-17 at 11:17 +0530, Karthikeyan Kathirvel wrote:
>>
>> + .uhr_cap = {
>> + .has_uhr = true,
>> + .mac = {
>> + .mac_cap[0] =
>> + IEEE80211_UHR_MAC_CAP0_DPS_SUPP |
>> + IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP |
>
> I'm really not sure we should claim all of this, e.g. DPS assist, right
> now.
>
> Also, I think you really mixed this up - a regular AP shouldn't claim
> DPS below (only mobile AP), but this here station should probably not
> normally claim DPS assist?
>
> Just as examples! There are other issues like this such as:
>
>> + IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP |
>
> I don't think the station should claim AP PUO support.
>
> Certainly not an exhaustive list, ELR also seems wrong, etc.
>
> johannes
Got it. It looks like this requires a deeper feature-level understanding
or a review of the full spec document for each feature. Instead, I used
AI to simplify this. Below, I’ve pasted the AI output, categorized by
AP/non-AP STA and by bands. Is this approach fine? Shall I go ahead and
make the changes based on this?
### UHR MAC capabilities
| Macro | Role tag | Band tag |
|---------------------------------|-----------------------|----------|
| IEEE80211_UHR_MAC_CAP0_DPS_SUPP | Both (AP + non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP | Mobile AP only
(reserved for non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP0_NPCA_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP0_ENH_BSR_SUPP | Both (requires +HTC-HE=1) | All |
| IEEE80211_UHR_MAC_CAP0_ADD_MAP_TID_SUPP | Both (conditional; EHT
SCS Traffic Description Support) | All |
| IEEE80211_UHR_MAC_CAP0_EOTSP_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_DSO_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_PEDCA_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_DBE_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_UL_LLI_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_P2P_LLI_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP1_PUO_SUPP | Both (different meaning AP vs
STA) | All |
| IEEE80211_UHR_MAC_CAP1_AP_PUO_SUPP | Both (different meaning AP vs
STA) | All |
| IEEE80211_UHR_MAC_CAP1_DUO_SUPP | Both (different meaning AP vs
STA) | All |
| IEEE80211_UHR_MAC_CAP2_OMC_UL_MU_DIS_RX_SUPP | AP-only (reserved
for non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP2_AOM_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP2_IFCS_LOC_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP2_UHR_TRS_SUPP | non‑AP STA only (reserved for
AP; requires +HTC-HE=1) | All |
| IEEE80211_UHR_MAC_CAP2_TXSPG_SUPP | Both | All |
| IEEE80211_UHR_MAC_CAP2_TXOP_RET_IN_TXSPG | Both | All |
| IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW | Both | All |
| IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH | Both | All |
| IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV | AP-only (reserved
for non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW | AP-only (reserved for
non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH | AP-only (reserved
for non‑AP STA) | All |
| IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS | AP-only | All |
| IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE | AP-only | All |
| IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP | Both | All |
### UHR PHY capabilities
| Macro | Role tag | Band tag |
|---------------------------------|-----------------------|----------|
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 | Both | All (≤80) |
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 | non‑AP STA only
(reserved for AP) | All (≤80) |
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 | Both | 5/6 (160) |
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 | non‑AP STA only
(reserved for AP) | 5/6 (160) |
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 | Both | 6 (320) |
| IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 | non‑AP STA only
(reserved for AP) | 6 (320) |
| IEEE80211_UHR_PHY_CAP_ELR_RX | Both | All |
| IEEE80211_UHR_PHY_CAP_ELR_TX | Both | All |
/KK
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver
2026-03-03 11:41 ` Karthikeyan Kathirvel
@ 2026-03-03 11:44 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2026-03-03 11:44 UTC (permalink / raw)
To: Karthikeyan Kathirvel; +Cc: linux-wireless, ath12k
On Tue, 2026-03-03 at 17:11 +0530, Karthikeyan Kathirvel wrote:
> Got it. It looks like this requires a deeper feature-level understanding
> or a review of the full spec document for each feature.
>
Certainly some understanding, but I don't think you have to necessarily
deeply understand each feature - it's specified in the table of
capabilities which are reserved where (though one notable exception is
missing in the table, the update timeout.)
> Instead, I used
> AI to simplify this. Below, I’ve pasted the AI output, categorized by
> AP/non-AP STA and by bands. Is this approach fine? Shall I go ahead and
> make the changes based on this?
I can't really say anything on that unless I go cross-check this with
9.4.2.354 UHR Capabilities Element, which you can do just as well as I
can? :)
> ### UHR MAC capabilities
>
> | Macro | Role tag | Band tag |
> |---------------------------------|-----------------------|----------|
> | IEEE80211_UHR_MAC_CAP0_DPS_SUPP | Both (AP + non‑AP STA) | All |
> | IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP | Both | All |
Also the table is pretty unreadable anyway.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-03-03 11:44 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-17 5:47 [PATCH wireless-next v4 00/02] wifi: ieee80211/mac80211: Add UHR (802.11bn) Capability and Operation parsing helpers Karthikeyan Kathirvel
2026-02-17 5:47 ` [PATCH wireless-next v4 1/2] wifi: UHR: define DPS/DBE/P-EDCA elements and fix size parsing Karthikeyan Kathirvel
2026-02-24 16:32 ` Johannes Berg
2026-03-03 10:11 ` Karthikeyan Kathirvel
2026-02-24 16:42 ` Johannes Berg
2026-02-24 17:38 ` Johannes Berg
2026-03-03 10:11 ` Karthikeyan Kathirvel
2026-02-24 20:47 ` Johannes Berg
2026-02-17 5:47 ` [PATCH wireless-next v4 2/2] wifi: mac80211_hwsim: Add UHR capabilities to the driver Karthikeyan Kathirvel
2026-02-24 16:20 ` Johannes Berg
2026-03-03 11:41 ` Karthikeyan Kathirvel
2026-03-03 11:44 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox