diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8f010af419bf..98943a510112 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -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; }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 704607824b8a..ea0acce724ca 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -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 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8e20fb714eff..0a87f4f81cd2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -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; } diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c index afc0e3f931ec..c21f693fac29 100644 --- a/net/wireless/pmsr.c +++ b/net/wireless/pmsr.c @@ -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; }