]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: cfg80211: add proximity detection capabilities to PMSR
authorPeddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
Mon, 20 Apr 2026 09:08:48 +0000 (14:38 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 5 May 2026 11:36:30 +0000 (13:36 +0200)
Introduce Proximity Detection (PD) capabilities in Peer Measurement
Service (PMSR) as defined in the Wi-Fi Alliance specification
"Proximity Ranging (PR) Implementation Consideration Draft 1.9 Rev 1
section 3.3". This enables devices to advertise peer to peer ranging
support.

Restructure FTM capabilities in cfg80211_pmsr_capabilities to replace
the single support_rsta flag with nested ista and rsta sub-structs,
each carrying per-mode flags for Non-Trigger Based (NTB), Trigger Based
(TB), and EDCA based ranging. This allows drivers to advertise detailed
role and protocol support for both initiator and responder roles.

Add support to pass additional ISTA and RSTA role capabilities to
userspace using new nested ISTA_CAPS and RSTA_CAPS attributes. The
legacy RSTA_SUPPORT flag is retained for backward compatibility.

Add NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS nested attribute using the
nl80211_peer_measurement_ftm_type_capa enum with two sub-flags:
NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INFRA_SUPPORT for STA-to-AP or
AP-to-STA ranging, and NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT
for peer-to-peer ranging.

Add CONCURRENT_ISTA_RSTA_SUPPORT as a FTM capability flag indicating
the device can simultaneously act as initiator and responder in a
multi-peer measurement request.

Extend FTM capabilities with antenna configuration fields
(max_no_of_tx_antennas, max_no_of_rx_antennas) for the PR Element
during PASN negotiation, and ranging interval limits
(min_allowed_ranging_interval_edca, min_allowed_ranging_interval_ntb)
to advertise device timing constraints for EDCA and NTB-based ranging.

Update the FTM request validation path in pmsr.c to check RSTA
requests against the per-mode rsta capabilities (NTB, TB, EDCA),
rejecting requests for modes the device does not support.

Co-developed-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
Link: https://patch.msgid.link/20260420090856.2152905-6-peddolla.reddy@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/pmsr.c

index 8f010af419bf788dc0605b135eb45f2899a80b96..98943a510112ab225d473d89d49a29e7efd332c6 100644 (file)
@@ -5911,7 +5911,45 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype type);
  *     (0 means unknown)
  * @ftm.max_total_ltf_rx: maximum total number of LTFs that can be received
  *     (0 means unknown)
- * @ftm.support_rsta: supports operating as RSTA in PMSR FTM request
+ * @ftm.ista: initiator role capabilities
+ * @ftm.ista.support_ntb: supports operating as ISTA in PMSR FTM request for
+ *     NTB ranging.
+ * @ftm.ista.support_tb: supports operating as ISTA in PMSR FTM request for
+ *     TB ranging.
+ * @ftm.ista.support_edca: supports operating as ISTA in PMSR FTM request for
+ *     EDCA based ranging.
+ * @ftm.rsta: responder role capabilities
+ * @ftm.rsta.support_ntb: supports operating as RSTA in PMSR FTM request for
+ *     NTB ranging.
+ * @ftm.rsta.support_tb: supports operating as RSTA in PMSR FTM request for
+ *     TB ranging.
+ * @ftm.rsta.support_edca: supports operating as RSTA in PMSR FTM request for
+ *     EDCA based ranging.
+ * @ftm.max_no_of_tx_antennas: maximum number of transmit antennas supported for
+ *     EDCA based ranging (0 means unknown)
+ * @ftm.max_no_of_rx_antennas: maximum number of receive antennas supported for
+ *     EDCA based ranging (0 means unknown)
+ * @ftm.min_allowed_ranging_interval_edca: Minimum EDCA ranging
+ *     interval supported by the device in milli seconds. (0 means unknown).
+ *     Applications can use this value to estimate the burst period to be
+ *     given in the FTM request for the EDCA based ranging case. If
+ *     non-zero, this value will be used to validate the burst period in
+ *     the FTM request.
+ * @ftm.min_allowed_ranging_interval_ntb: Minimum NTB ranging
+ *     interval supported by the device in milli seconds. (0 means unknown).
+ *     Applications can use this value to estimate the burst period to be
+ *     given in the FTM request for the NTB ranging case. If non-zero,
+ *     this value will be used to validate the nominal time in the FTM
+ *     request.
+ * @ftm.type: ranging type capabilities
+ * @ftm.type.infra_support: supports infrastructure ranging (STA-to-AP or
+ *     AP-to-STA) as part of Proximity Detection
+ * @ftm.type.pd_support: supports peer-to-peer ranging as mentioned in the
+ *     specification "PR Implementation Consideration Draft 1.9 rev 1" where
+ *     PD stands for proximity detection
+ * @ftm.concurrent_ista_rsta_support: indicates if the device can
+ *     simultaneously act as initiator and responder in a multi-peer
+ *     measurement request. Only valid if @ftm.rsta_support is set.
  */
 struct cfg80211_pmsr_capabilities {
        unsigned int max_peers;
@@ -5937,7 +5975,25 @@ struct cfg80211_pmsr_capabilities {
                u8 max_rx_sts;
                u8 max_total_ltf_tx;
                u8 max_total_ltf_rx;
-               u8 support_rsta:1;
+               struct {
+                       u8 support_ntb:1,
+                          support_tb:1,
+                          support_edca:1;
+               } ista;
+               struct {
+                       u8 support_ntb:1,
+                          support_tb:1,
+                          support_edca:1;
+               } rsta;
+               u8 max_no_of_tx_antennas;
+               u8 max_no_of_rx_antennas;
+               u32 min_allowed_ranging_interval_edca;
+               u32 min_allowed_ranging_interval_ntb;
+               struct {
+                       u8 infra_support:1,
+                          pd_support:1;
+               } type;
+               u8 concurrent_ista_rsta_support:1;
        } ftm;
 };
 
index 704607824b8a2b1eaaa12c10cce308f5751a608c..ea0acce724ca309978a61cb2922b0276112a2b95 100644 (file)
@@ -8111,6 +8111,46 @@ enum nl80211_peer_measurement_attrs {
  *     This limits the allowed combinations of LTF repetitions and STS.
  * @NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT: flag attribute indicating the
  *     device supports operating as the RSTA in PMSR FTM request
+ * @NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS: nested attribute containing ISTA
+ *     (initiator) role capabilities. Uses the same sub-attributes as
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS: nested attribute containing RSTA
+ *     (responder) role capabilities.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB: flag attribute (used inside
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS or
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS) indicating NTB ranging support.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB: flag attribute (used inside
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS or
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS) indicating TB ranging support.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA: flag attribute (used inside
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS or
+ *     %NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS) indicating EDCA based ranging
+ *     support.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS: nested attribute containing ranging
+ *     type capabilities. Uses sub-attributes from
+ *     &enum nl80211_peer_measurement_ftm_type_capa.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_CONCURRENT_ISTA_RSTA_SUPPORT: flag attribute
+ *     indicating that the device can simultaneously act as initiator and
+ *     responder in a multi-peer measurement request. Only valid if
+ *     @NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT is set.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS: u32 attribute indicating
+ *     the maximum number of transmit antennas supported for EDCA based ranging
+ *     (0 means unknown)
+ * @NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS: u32 attribute indicating
+ *     the maximum number of receive antennas supported for EDCA based ranging
+ *     (0 means unknown)
+ * @NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA: u32 attribute indicating
+ *     the minimum EDCA ranging interval supported by the device
+ *     in milli seconds. (0 means unknown). Applications can use this value
+ *     to estimate the burst period to be given in the FTM request for the
+ *     EDCA based ranging case. If non-zero, this value will be used to
+ *     validate the burst period in the FTM request.
+ * @NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB: u32 attribute indicating
+ *     the minimum NTB ranging interval supported by the device
+ *     in milli seconds. (0 means unknown). Applications can use this value
+ *     to estimate the burst period to be given in the FTM request for the
+ *     NTB ranging case. If non-zero, this value will be used to validate
+ *     the nominal time in the FTM request.
  *
  * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
  * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
@@ -8136,12 +8176,50 @@ enum nl80211_peer_measurement_ftm_capa {
        NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_TX,
        NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_RX,
        NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT,
+       NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS,
+       NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS,
+       NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB,
+       NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB,
+       NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA,
+       NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS,
+       NL80211_PMSR_FTM_CAPA_ATTR_CONCURRENT_ISTA_RSTA_SUPPORT,
+       NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS,
+       NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS,
+       NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA,
+       NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB,
 
        /* keep last */
        NUM_NL80211_PMSR_FTM_CAPA_ATTR,
        NL80211_PMSR_FTM_CAPA_ATTR_MAX = NUM_NL80211_PMSR_FTM_CAPA_ATTR - 1
 };
 
+/**
+ * enum nl80211_peer_measurement_ftm_type_capa - FTM ranging type capability
+ *     sub-attributes, used inside %NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS
+ * @__NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INVALID: invalid
+ *
+ * @NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INFRA_SUPPORT: flag attribute indicating
+ *     that the device supports infrastructure ranging (STA-to-AP or
+ *     AP-to-STA) as part of Proximity Detection
+ * @NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT: flag attribute indicating that
+ *     the device supports peer-to-peer ranging as mentioned in the
+ *     specification "PR Implementation Consideration Draft 1.9 rev 1" where
+ *     PD stands for proximity detection
+ *
+ * @NUM_NL80211_PMSR_FTM_TYPE_CAPA_ATTR: internal
+ * @NL80211_PMSR_FTM_TYPE_CAPA_ATTR_MAX: highest attribute number
+ */
+enum nl80211_peer_measurement_ftm_type_capa {
+       __NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INVALID,
+
+       NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INFRA_SUPPORT,
+       NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT,
+
+       /* keep last */
+       NUM_NL80211_PMSR_FTM_TYPE_CAPA_ATTR,
+       NL80211_PMSR_FTM_TYPE_CAPA_ATTR_MAX = NUM_NL80211_PMSR_FTM_TYPE_CAPA_ATTR - 1
+};
+
 /**
  * enum nl80211_peer_measurement_ftm_req - FTM request attributes
  * @__NL80211_PMSR_FTM_REQ_ATTR_INVALID: invalid
index 8e20fb714eff9da3f1b4c99a16442916b8e8a698..0a87f4f81cd2b2dac107305cedf42fed6a702933 100644 (file)
@@ -2503,10 +2503,97 @@ nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
            nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_RX,
                        cap->ftm.max_total_ltf_rx))
                return -ENOBUFS;
-       if (cap->ftm.support_rsta &&
-           nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT))
+
+       if (cap->ftm.ista.support_ntb || cap->ftm.ista.support_tb ||
+           cap->ftm.ista.support_edca) {
+               struct nlattr *ista_caps;
+
+               ista_caps = nla_nest_start_noflag(msg,
+                                                 NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS);
+               if (!ista_caps)
+                       return -ENOBUFS;
+               if (cap->ftm.ista.support_ntb &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB))
+                       return -ENOBUFS;
+               if (cap->ftm.ista.support_tb &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB))
+                       return -ENOBUFS;
+               if (cap->ftm.ista.support_edca &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA))
+                       return -ENOBUFS;
+               nla_nest_end(msg, ista_caps);
+       }
+
+       if (cap->ftm.rsta.support_ntb || cap->ftm.rsta.support_tb ||
+           cap->ftm.rsta.support_edca) {
+               struct nlattr *rsta_caps;
+
+               /*
+                * Set the generic RSTA_SUPPORT flag if any of the specific
+                * ranging modes is supported to maintain the backward
+                * compatibility.
+                */
+               if (nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT))
+                       return -ENOBUFS;
+
+               rsta_caps = nla_nest_start_noflag(msg,
+                                                 NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS);
+               if (!rsta_caps)
+                       return -ENOBUFS;
+               if (cap->ftm.rsta.support_ntb &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB))
+                       return -ENOBUFS;
+               if (cap->ftm.rsta.support_tb &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB))
+                       return -ENOBUFS;
+               if (cap->ftm.rsta.support_edca &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA))
+                       return -ENOBUFS;
+               nla_nest_end(msg, rsta_caps);
+       }
+
+       if (cap->ftm.max_no_of_tx_antennas &&
+           nla_put_u8(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS,
+                      cap->ftm.max_no_of_tx_antennas))
+               return -ENOBUFS;
+
+       if (cap->ftm.max_no_of_rx_antennas &&
+           nla_put_u8(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS,
+                      cap->ftm.max_no_of_rx_antennas))
+               return -ENOBUFS;
+
+       if (cap->ftm.min_allowed_ranging_interval_edca &&
+           nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA,
+                       cap->ftm.min_allowed_ranging_interval_edca))
                return -ENOBUFS;
 
+       if (cap->ftm.min_allowed_ranging_interval_ntb &&
+           nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB,
+                       cap->ftm.min_allowed_ranging_interval_ntb))
+               return -ENOBUFS;
+
+       if (cap->ftm.type.infra_support || cap->ftm.type.pd_support) {
+               struct nlattr *pd_caps;
+
+               pd_caps = nla_nest_start_noflag(msg,
+                                               NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS);
+               if (!pd_caps)
+                       return -ENOBUFS;
+
+               if (cap->ftm.type.infra_support &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INFRA_SUPPORT))
+                       return -ENOBUFS;
+
+               if (cap->ftm.type.pd_support &&
+                   nla_put_flag(msg, NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT))
+                       return -ENOBUFS;
+
+               nla_nest_end(msg, pd_caps);
+       }
+
+       if (cap->ftm.concurrent_ista_rsta_support &&
+           nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_CONCURRENT_ISTA_RSTA_SUPPORT))
+               return -ENOBUFS;
        nla_nest_end(msg, ftm);
        return 0;
 }
index afc0e3f931ec99c55d1c8fa94871ddc025732283..c21f693fac297336929f6c44682060573ca0a985 100644 (file)
@@ -188,10 +188,28 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
        }
 
        out->ftm.rsta = !!tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA];
-       if (out->ftm.rsta && !capa->ftm.support_rsta) {
+       if (out->ftm.rsta && out->ftm.non_trigger_based &&
+           !capa->ftm.rsta.support_ntb) {
                NL_SET_ERR_MSG_ATTR(info->extack,
                                    tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA],
-                                   "FTM: RSTA not supported by device");
+                                   "FTM: NTB RSTA not supported by device");
+               return -EOPNOTSUPP;
+       }
+
+       if (out->ftm.rsta && out->ftm.trigger_based &&
+           !capa->ftm.rsta.support_tb) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA],
+                                   "FTM: TB RSTA not supported by device");
+               return -EOPNOTSUPP;
+       }
+
+       if (out->ftm.rsta && !out->ftm.non_trigger_based &&
+           !out->ftm.trigger_based &&
+           !capa->ftm.rsta.support_edca) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA],
+                                   "FTM: EDCA RSTA not supported by device");
                return -EOPNOTSUPP;
        }