Devices may support different preamble and bandwidth configurations for proximity detection (PD) ranging versus standard ranging. Add separate pd_preambles and pd_bandwidths fields to cfg80211_pmsr_capabilities to allow drivers to advertise PD-specific capabilities. Expose these over nl80211 using new attributes NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES and NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS, advertised only when pd_support is set. For PD requests, validate bandwidth and preamble against pd_bandwidths and pd_preambles. For non-PD requests, validate against the existing bandwidths and preambles fields. Signed-off-by: Peddolla Harshavardhan Reddy --- include/net/cfg80211.h | 6 ++++++ include/uapi/linux/nl80211.h | 10 ++++++++++ net/wireless/nl80211.c | 12 ++++++++++++ net/wireless/pmsr.c | 21 +++++++++++++++++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b16f36473b2f..1d19cb2f14fa 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6050,6 +6050,10 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype type); * @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. + * @ftm.pd_preambles: bitmap of preambles supported (&enum nl80211_preamble) + * for PD ranging requests. Ignored if @ftm.type.pd_support is not set. + * @ftm.pd_bandwidths: bitmap of bandwidths supported (&enum nl80211_chan_width) + * for PD ranging requests. Ignored if @ftm.type.pd_support is not set. */ struct cfg80211_pmsr_capabilities { unsigned int max_peers; @@ -6096,6 +6100,8 @@ struct cfg80211_pmsr_capabilities { pd_support:1; } type; u8 concurrent_ista_rsta_support:1; + u32 pd_preambles; + u32 pd_bandwidths; } ftm; }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 1400adfee10b..f701b862e50f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -8178,6 +8178,14 @@ enum nl80211_peer_measurement_attrs { * 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. + * @NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES: u32 bitmap of values from + * &enum nl80211_preamble indicating the supported preambles for PD + * ranging requests. Only valid if %NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT + * is set. + * @NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS: u32 bitmap of values from + * &enum nl80211_chan_width indicating the supported channel bandwidths + * for PD ranging requests. Only valid if + * %NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT is set. * * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number @@ -8214,6 +8222,8 @@ enum nl80211_peer_measurement_ftm_capa { 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, + NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES, + NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS, /* keep last */ NUM_NL80211_PMSR_FTM_CAPA_ATTR, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0e0c66fe39db..322c7ed881d8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2614,6 +2614,18 @@ nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap, if (cap->ftm.concurrent_ista_rsta_support && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_CONCURRENT_ISTA_RSTA_SUPPORT)) return -ENOBUFS; + + if (cap->ftm.type.pd_support) { + if (cap->ftm.pd_preambles && + nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES, + cap->ftm.pd_preambles)) + return -ENOBUFS; + if (cap->ftm.pd_bandwidths && + nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS, + cap->ftm.pd_bandwidths)) + return -ENOBUFS; + } + nla_nest_end(msg, ftm); return 0; } diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c index 46c444d0327b..202e2c46522b 100644 --- a/net/wireless/pmsr.c +++ b/net/wireless/pmsr.c @@ -17,11 +17,19 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, u32 preamble = NL80211_PREAMBLE_DMG; /* only optional in DMG */ /* validate existing data */ - if (!(rdev->wiphy.pmsr_capa->ftm.bandwidths & BIT(out->chandef.width))) { + if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_INFRA && + !(capa->ftm.bandwidths & BIT(out->chandef.width))) { NL_SET_ERR_MSG(info->extack, "FTM: unsupported bandwidth"); return -EINVAL; } + if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && + !(capa->ftm.pd_bandwidths & BIT(out->chandef.width))) { + NL_SET_ERR_MSG(info->extack, + "FTM: unsupported bandwidth for PD request"); + return -EINVAL; + } + /* no validation needed - was already done via nested policy */ nla_parse_nested_deprecated(tb, NL80211_PMSR_FTM_REQ_ATTR_MAX, ftmreq, NULL, NULL); @@ -44,13 +52,22 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, } } - if (!(capa->ftm.preambles & BIT(preamble))) { + if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_INFRA && + !(capa->ftm.preambles & BIT(preamble))) { NL_SET_ERR_MSG_ATTR(info->extack, tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE], "FTM: invalid preamble"); return -EINVAL; } + if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && + !(capa->ftm.pd_preambles & BIT(preamble))) { + NL_SET_ERR_MSG_ATTR(info->extack, + tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE], + "FTM: invalid preamble for PD request"); + return -EINVAL; + } + out->ftm.preamble = preamble; out->ftm.burst_period = 0; -- 2.34.1