nl80211/cfg80211: add support for non EDCA based ranging measurement
authorAvraham Stern <avraham.stern@intel.com>
Fri, 31 Jan 2020 11:12:38 +0000 (13:12 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 20 Mar 2020 13:42:19 +0000 (14:42 +0100)
Add support for requesting that the ranging measurement will use
the trigger-based / non trigger-based flow instead of the EDCA based
flow.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/20200131111300.891737-2-luca@coelho.fi
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/pmsr.c

index 329044c31220c26f3b0e11f5c3509c8487912056..e3988e1b3f6f0edea1d0d33db4de5e5ecab69327 100644 (file)
@@ -3270,6 +3270,12 @@ struct cfg80211_pmsr_result {
  * @ftmr_retries: number of retries for FTM request
  * @request_lci: request LCI information
  * @request_civicloc: request civic location information
+ * @trigger_based: use trigger based ranging for the measurement
+ *              If neither @trigger_based nor @non_trigger_based is set,
+ *              EDCA based ranging will be used.
+ * @non_trigger_based: use non trigger based ranging for the measurement
+ *              If neither @trigger_based nor @non_trigger_based is set,
+ *              EDCA based ranging will be used.
  *
  * See also nl80211 for the respective attribute documentation.
  */
@@ -3279,7 +3285,9 @@ struct cfg80211_pmsr_ftm_request_peer {
        u8 requested:1,
           asap:1,
           request_lci:1,
-          request_civicloc:1;
+          request_civicloc:1,
+          trigger_based:1,
+          non_trigger_based:1;
        u8 num_bursts_exp;
        u8 burst_duration;
        u8 ftms_per_burst;
@@ -4435,6 +4443,8 @@ struct wiphy_iftype_ext_capab {
  *     forbid using the value 15 to let the responder pick)
  * @ftm.max_ftms_per_burst: maximum FTMs per burst supported (set to 0 if
  *     not limited)
+ * @ftm.trigger_based: trigger based ranging measurement is supported
+ * @ftm.non_trigger_based: non trigger based ranging measurement is supported
  */
 struct cfg80211_pmsr_capabilities {
        unsigned int max_peers;
@@ -4450,7 +4460,9 @@ struct cfg80211_pmsr_capabilities {
                   asap:1,
                   non_asap:1,
                   request_lci:1,
-                  request_civicloc:1;
+                  request_civicloc:1,
+                  trigger_based:1,
+                  non_trigger_based:1;
        } ftm;
 };
 
index 66fffc30bb73c3f25821841fc1ea9112fd354d1c..c6bb296be99b8944fc253a55db0d2548cbe73b9b 100644 (file)
@@ -6323,12 +6323,14 @@ enum nl80211_ftm_responder_stats {
  * @NL80211_PREAMBLE_HT: HT preamble
  * @NL80211_PREAMBLE_VHT: VHT preamble
  * @NL80211_PREAMBLE_DMG: DMG preamble
+ * @NL80211_PREAMBLE_HE: HE preamble
  */
 enum nl80211_preamble {
        NL80211_PREAMBLE_LEGACY,
        NL80211_PREAMBLE_HT,
        NL80211_PREAMBLE_VHT,
        NL80211_PREAMBLE_DMG,
+       NL80211_PREAMBLE_HE,
 };
 
 /**
@@ -6521,6 +6523,10 @@ enum nl80211_peer_measurement_attrs {
  *     is valid)
  * @NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST: u32 attribute indicating
  *     the maximum FTMs per burst (if not present anything is valid)
+ * @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if
+ *     trigger based ranging measurement is supported
+ * @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating
+ *     if non trigger based ranging measurement is supported
  *
  * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
  * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
@@ -6536,6 +6542,8 @@ enum nl80211_peer_measurement_ftm_capa {
        NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
        NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
        NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
+       NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED,
+       NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED,
 
        /* keep last */
        NUM_NL80211_PMSR_FTM_CAPA_ATTR,
@@ -6565,6 +6573,20 @@ enum nl80211_peer_measurement_ftm_capa {
  * @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI: request LCI data (flag)
  * @NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC: request civic location data
  *     (flag)
+ * @NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED: request trigger based ranging
+ *     measurement (flag).
+ *     This attribute and %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED are
+ *     mutually exclusive.
+ *      if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
+ *     %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
+ *     ranging will be used.
+ * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non trigger based
+ *     ranging measurement (flag)
+ *     This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are
+ *     mutually exclusive.
+ *      if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
+ *     %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
+ *     ranging will be used.
  *
  * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
  * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -6581,6 +6603,8 @@ enum nl80211_peer_measurement_ftm_req {
        NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES,
        NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI,
        NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
+       NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
+       NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
 
        /* keep last */
        NUM_NL80211_PMSR_FTM_REQ_ATTR,
index 3e25229a059de83505860e9a4c9ca9428c57153b..341402b4f178808191d5fe1892747d9d92cbd3d1 100644 (file)
@@ -693,8 +693,14 @@ int wiphy_register(struct wiphy *wiphy)
                                ~(BIT(NL80211_PREAMBLE_LEGACY) |
                                  BIT(NL80211_PREAMBLE_HT) |
                                  BIT(NL80211_PREAMBLE_VHT) |
+                                 BIT(NL80211_PREAMBLE_HE) |
                                  BIT(NL80211_PREAMBLE_DMG))))
                        return -EINVAL;
+               if (WARN_ON((wiphy->pmsr_capa->ftm.trigger_based ||
+                            wiphy->pmsr_capa->ftm.non_trigger_based) &&
+                           !(wiphy->pmsr_capa->ftm.preambles &
+                             BIT(NL80211_PREAMBLE_HE))))
+                       return -EINVAL;
                if (WARN_ON(wiphy->pmsr_capa->ftm.bandwidths &
                                ~(BIT(NL80211_CHAN_WIDTH_20_NOHT) |
                                  BIT(NL80211_CHAN_WIDTH_20) |
index 6d76162256b41846b624c7698dda2fe788743a7d..6dd6db61c80b30ab9748941743ac18ce0d0b5e1d 100644 (file)
@@ -276,6 +276,8 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
        [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
        [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
        [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
+       [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
+       [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
 };
 
 static const struct nla_policy
@@ -1885,6 +1887,12 @@ nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
            nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
                        cap->ftm.max_ftms_per_burst))
                return -ENOBUFS;
+       if (cap->ftm.trigger_based &&
+           nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
+               return -ENOBUFS;
+       if (cap->ftm.non_trigger_based &&
+           nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
+               return -ENOBUFS;
 
        nla_nest_end(msg, ftm);
        return 0;
index c09fbf09549dfa6e9baa436c88e5adb7b9817dfb..63dc8023447f8bf46a0cbe31fe1ff5bce1cec73f 100644 (file)
@@ -126,6 +126,38 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
                            "FTM: civic location request not supported");
        }
 
+       out->ftm.trigger_based =
+               !!tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED];
+       if (out->ftm.trigger_based && !capa->ftm.trigger_based) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED],
+                                   "FTM: trigger based ranging is not supported");
+               return -EINVAL;
+       }
+
+       out->ftm.non_trigger_based =
+               !!tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED];
+       if (out->ftm.non_trigger_based && !capa->ftm.non_trigger_based) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED],
+                                   "FTM: trigger based ranging is not supported");
+               return -EINVAL;
+       }
+
+       if (out->ftm.trigger_based && out->ftm.non_trigger_based) {
+               NL_SET_ERR_MSG(info->extack,
+                              "FTM: can't set both trigger based and non trigger based");
+               return -EINVAL;
+       }
+
+       if ((out->ftm.trigger_based || out->ftm.non_trigger_based) &&
+           out->ftm.preamble != NL80211_PREAMBLE_HE) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE],
+                                   "FTM: non EDCA based ranging must use HE preamble");
+               return -EINVAL;
+       }
+
        return 0;
 }