Add support for FTM range report negotiation in EDCA-based ranging operations. This allows devices to negotiate whether range measurement reports should be exchanged after the FTM session. The implementation adds a new capability flag and request attribute for range report negotiation. Devices advertise range report support and userspace can request it for EDCA ranging sessions only. Signed-off-by: Peddolla Harshavardhan Reddy --- include/net/cfg80211.h | 8 +++++++- include/uapi/linux/nl80211.h | 6 ++++++ net/wireless/nl80211.c | 4 ++++ net/wireless/pmsr.c | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5224a68867cc..890d4b007033 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4392,6 +4392,8 @@ struct cfg80211_pmsr_result { * to be indicated in case the device moves out of this range. * (units mm, u64). measurement results need be sent on a burst index basis * in this case. + * @range_report: negotiate for FTM range report. Only valid for + * EDCA based ranging. * See also nl80211 for the respective attribute documentation. */ struct cfg80211_pmsr_ftm_request_peer { @@ -4417,6 +4419,7 @@ struct cfg80211_pmsr_ftm_request_peer { u8 measurements_per_aw; u64 ingress_distancemm; u64 egress_distancemm; + u8 range_report:1; }; /** @@ -5772,6 +5775,8 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype type); * @ftm.support_rsta: supports operating as RSTA in PMSR FTM request * @ftm.support_edca_responder: supports operating as FTM responder in PMSR FTM * request for EDCA-based ranging + * @ftm.support_range_report: capable of negotiating for FTM range report. Only + * valid for EDCA based ranging. * @ftm.pd_edca_bandwidths: bitmap of bandwidths supported * (&enum nl80211_chan_width) in case of PD request with EDCA based * initiator or responder role. ignored if @pd_support is not set. @@ -5812,7 +5817,8 @@ struct cfg80211_pmsr_capabilities { u32 min_allowed_ranging_interval_edca; u32 min_allowed_ranging_interval_ntb; u8 support_rsta:1, - support_edca_responder:1; + support_edca_responder:1, + support_range_report:1; u32 pd_edca_bandwidths; u32 pd_ntb_bandwidths; } ftm; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 181595ec960e..af80248d24a1 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -7875,6 +7875,8 @@ enum nl80211_peer_measurement_attrs { * Note that a higher channel bandwidth may be configured to allow for * other measurements types with different bandwidth requirement in the * same measurement. + * @NL80211_PMSR_FTM_CAPA_ATTR_RANGE_REPORT: flag indicating if range report + * negotiation and reporting is supported in case of EDCA based ranging. * * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number @@ -7907,6 +7909,7 @@ enum nl80211_peer_measurement_ftm_capa { NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB, NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_BANDWIDTHS, NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_BANDWIDTHS, + NL80211_PMSR_FTM_CAPA_ATTR_RANGE_REPORT, /* keep last */ NUM_NL80211_PMSR_FTM_CAPA_ATTR, @@ -7990,6 +7993,8 @@ enum nl80211_peer_measurement_ftm_capa { * @NL80211_PMSR_FTM_REQ_ATTR_EGRESS: the measurement result of the peer needs * to be indicated in case the device moves out of this range. * (units mm, u64) + * @NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT: Negotiate Range report in case of + * EDCA based ranging. * * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number @@ -8018,6 +8023,7 @@ enum nl80211_peer_measurement_ftm_req { NL80211_PMSR_FTM_REQ_ATTR_MEAS_PER_AW, NL80211_PMSR_FTM_REQ_ATTR_INGRESS, NL80211_PMSR_FTM_REQ_ATTR_EGRESS, + NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT, /* keep last */ NUM_NL80211_PMSR_FTM_REQ_ATTR, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 571d96a5ddf4..bbb80032d615 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -373,6 +373,7 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = { [NL80211_PMSR_FTM_REQ_ATTR_MEAS_PER_AW] = { .type = NLA_U8 }, [NL80211_PMSR_FTM_REQ_ATTR_INGRESS] = { .type = NLA_U64 }, [NL80211_PMSR_FTM_REQ_ATTR_EGRESS] = { .type = NLA_U64 }, + [NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT] = { .type = NLA_FLAG }, }; static const struct nla_policy @@ -2384,6 +2385,9 @@ nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap, if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_BANDWIDTHS, cap->ftm.pd_ntb_bandwidths)) return -ENOBUFS; + if (cap->ftm.support_range_report && + nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_RANGE_REPORT)) + return -ENOBUFS; nla_nest_end(msg, ftm); return 0; diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c index 0ed0f401db11..f89fcd9bb505 100644 --- a/net/wireless/pmsr.c +++ b/net/wireless/pmsr.c @@ -241,6 +241,25 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, out->ftm.egress_distancemm = nla_get_u64(tb[NL80211_PMSR_FTM_REQ_ATTR_EGRESS]); + if (tb[NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT]) + out->ftm.range_report = + nla_get_flag(tb[NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT]); + + if (!capa->ftm.support_range_report && out->ftm.range_report) { + NL_SET_ERR_MSG_ATTR(info->extack, + tb[NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT], + "FTM: Range report negotiation not supported"); + return -EINVAL; + } + + if ((out->ftm.non_trigger_based || out->ftm.trigger_based) && + out->ftm.range_report) { + NL_SET_ERR_MSG_ATTR(info->extack, + tb[NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT], + "FTM: Range report request is not valid for TB/NTB ranging"); + return -EINVAL; + } + return 0; } -- 2.34.1