From: Kavita Kavita Introduce support for continuous ranging and advanced timing parameters in the FTM (Fine Timing Measurement) request, response, and capability paths. This enables more flexible ranging scenarios with improved control over measurement timing and session management. Signed-off-by: Kavita Kavita Signed-off-by: Peddolla Harshavardhan Reddy --- drivers/net/wireless/virtual/mac80211_hwsim.c | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index 475918ee8132..12257797f29d 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -844,6 +844,18 @@ hwsim_ftm_result_policy[NL80211_PMSR_FTM_RESP_ATTR_MAX + 1] = { [NL80211_PMSR_FTM_RESP_ATTR_DIST_SPREAD] = { .type = NLA_U64 }, [NL80211_PMSR_FTM_RESP_ATTR_LCI] = { .type = NLA_STRING }, [NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_STRING }, + [NL80211_PMSR_FTM_RESP_ATTR_TX_LTF_REPETITION_COUNT] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_RX_LTF_REPETITION_COUNT] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_NUM_TX_SPATIAL_STREAMS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_NUM_RX_SPATIAL_STREAMS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_NOMINAL_TIME] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_AVAILABILITY_WINDOW] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_MEASUREMENTS_PER_AW] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_PREAMBLE] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_RESP_ATTR_IS_DELAYED_LMR] = { .type = NLA_FLAG }, }; static const struct nla_policy @@ -889,6 +901,16 @@ hwsim_ftm_capa_policy[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1] = { [NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST] = NLA_POLICY_MAX(NLA_U8, 31), [NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG }, [NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG }, + [NL80211_PMSR_FTM_CAPA_ATTR_EDCA_BASED_RESPONDER] = { .type = NLA_FLAG }, + [NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_PREAMBLES] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_PREAMBLES] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_BANDWIDTHS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_BANDWIDTHS] = { .type = NLA_U32 }, + [NL80211_PMSR_FTM_CAPA_ATTR_RANGE_REPORT] = { .type = NLA_FLAG }, }; static const struct nla_policy @@ -903,6 +925,15 @@ hwsim_pmsr_capa_policy[NL80211_PMSR_ATTR_MAX + 1] = { [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_FLAG }, [NL80211_PMSR_ATTR_TYPE_CAPA] = NLA_POLICY_NESTED(hwsim_pmsr_capa_type_policy), [NL80211_PMSR_ATTR_PEERS] = { .type = NLA_REJECT }, // only for request. + [NL80211_PMSR_ATTR_PD_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_PMSR_ATTR_PD_CONCURRENT_ISTA_RSTA_SUPPORT] = { + .type = NLA_FLAG + }, + [NL80211_PMSR_ATTR_PD_MAX_PEER_ISTA_ROLE] = { .type = NLA_U32 }, + [NL80211_PMSR_ATTR_PD_MAX_PEER_RSTA_ROLE] = { .type = NLA_U32 }, + [NL80211_PMSR_ATTR_PD_RANDOMIZE_MAC_ADDR_CONNECTED] = { + .type = NLA_FLAG + }, }; static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { @@ -3561,6 +3592,49 @@ static int mac80211_hwsim_send_pmsr_ftm_request_peer(struct sk_buff *msg, if (nla_put_u8(msg, NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR, request->bss_color)) return -ENOBUFS; + if (request->min_time_between_measurements && + nla_put_u32(msg, NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS, + request->min_time_between_measurements)) + return -ENOBUFS; + + if (request->max_time_between_measurements && + nla_put_u32(msg, NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS, + request->max_time_between_measurements)) + return -ENOBUFS; + + if (request->availability_window && + nla_put_u32(msg, NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION, + request->availability_window)) + return -ENOBUFS; + + if (request->nominal_time && + nla_put_u32(msg, NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME, + request->nominal_time)) + return -ENOBUFS; + + if (request->measurements_per_aw && + nla_put_u32(msg, NL80211_PMSR_FTM_REQ_ATTR_MEAS_PER_AW, + request->measurements_per_aw)) + return -ENOBUFS; + + if (request->ingress_distancemm && + nla_put_u64_64bit(msg, NL80211_PMSR_FTM_REQ_ATTR_INGRESS, + request->ingress_distancemm, NL80211_PMSR_FTM_REQ_ATTR_PAD)) + return -ENOBUFS; + + if (request->egress_distancemm && + nla_put_u64_64bit(msg, NL80211_PMSR_FTM_REQ_ATTR_EGRESS, + request->egress_distancemm, NL80211_PMSR_FTM_REQ_ATTR_PAD)) + return -ENOBUFS; + + if (request->range_report && + nla_put_flag(msg, NL80211_PMSR_FTM_REQ_ATTR_RANGE_REPORT)) + return -ENOBUFS; + + if (request->pd_suppress_range_results && + nla_put_flag(msg, NL80211_PMSR_FTM_REQ_ATTR_PD_SUPPRESS_RESULTS)) + return -ENOBUFS; + nla_nest_end(msg, ftm); return 0; @@ -3930,6 +4004,57 @@ static int mac80211_hwsim_parse_ftm_result(struct nlattr *ftm, result->civicloc_len = nla_len(tb[NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC]); } + if (tb[NL80211_PMSR_FTM_RESP_ATTR_TX_LTF_REPETITION_COUNT]) + result->tx_ltf_repetition_count = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_TX_LTF_REPETITION_COUNT]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_RX_LTF_REPETITION_COUNT]) + result->rx_ltf_repetition_count = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_RX_LTF_REPETITION_COUNT]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS]) + result->max_time_between_measurements = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS]) + result->min_time_between_measurements = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_NUM_TX_SPATIAL_STREAMS]) + result->num_tx_spatial_streams = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_NUM_TX_SPATIAL_STREAMS]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_NUM_RX_SPATIAL_STREAMS]) + result->num_rx_spatial_streams = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_NUM_RX_SPATIAL_STREAMS]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_NOMINAL_TIME]) + result->nominal_time = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_NOMINAL_TIME]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_AVAILABILITY_WINDOW]) + result->availability_window = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_AVAILABILITY_WINDOW]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_MEASUREMENTS_PER_AW]) + result->measurements_per_aw = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_MEASUREMENTS_PER_AW]); + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_CHANNEL_WIDTH]) { + result->chan_width_valid = 1; + result->chan_width = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_CHANNEL_WIDTH]); + } + + if (tb[NL80211_PMSR_FTM_RESP_ATTR_PREAMBLE]) { + result->preamble_valid = 1; + result->preamble = + nla_get_u32(tb[NL80211_PMSR_FTM_RESP_ATTR_PREAMBLE]); + } + + result->is_delayed_lmr = + nla_get_flag(tb[NL80211_PMSR_FTM_RESP_ATTR_IS_DELAYED_LMR]); + return 0; } @@ -6431,6 +6556,41 @@ static int parse_ftm_capa(const struct nlattr *ftm_capa, struct cfg80211_pmsr_ca out->ftm.request_civicloc = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC]; out->ftm.trigger_based = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED]; out->ftm.non_trigger_based = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED]; + out->ftm.support_edca_responder = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_EDCA_BASED_RESPONDER]; + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS]) + out->ftm.max_no_of_tx_antennas = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS]) + out->ftm.max_no_of_rx_antennas = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA]) + out->ftm.min_allowed_ranging_interval_edca = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB]) + out->ftm.min_allowed_ranging_interval_ntb = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_PREAMBLES]) + out->ftm.pd_edca_preambles = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_PREAMBLES]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_PREAMBLES]) + out->ftm.pd_ntb_preambles = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_PREAMBLES]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_BANDWIDTHS]) + out->ftm.pd_edca_bandwidths = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_EDCA_BANDWIDTHS]); + + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_BANDWIDTHS]) + out->ftm.pd_ntb_bandwidths = + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_NTB_BANDWIDTHS]); + + out->ftm.support_range_report = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_RANGE_REPORT]; return 0; } @@ -6453,6 +6613,17 @@ static int parse_pmsr_capa(const struct nlattr *pmsr_capa, struct cfg80211_pmsr_ out->max_peers = nla_get_u32(tb[NL80211_PMSR_ATTR_MAX_PEERS]); out->report_ap_tsf = !!tb[NL80211_PMSR_ATTR_REPORT_AP_TSF]; out->randomize_mac_addr = !!tb[NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR]; + out->pd_randomize_mac_addr_conn = + !!tb[NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR]; + out->pd_support = !!tb[NL80211_PMSR_ATTR_PD_SUPPORT]; + out->pd_concurrent_ista_rsta_support = + !!tb[NL80211_PMSR_ATTR_PD_CONCURRENT_ISTA_RSTA_SUPPORT]; + if (tb[NL80211_PMSR_ATTR_PD_MAX_PEER_ISTA_ROLE]) + out->pd_max_peer_ista_role = + nla_get_u32(tb[NL80211_PMSR_ATTR_PD_MAX_PEER_ISTA_ROLE]); + if (tb[NL80211_PMSR_ATTR_PD_MAX_PEER_RSTA_ROLE]) + out->pd_max_peer_rsta_role = + nla_get_u32(tb[NL80211_PMSR_ATTR_PD_MAX_PEER_RSTA_ROLE]); if (!tb[NL80211_PMSR_ATTR_TYPE_CAPA]) { NL_SET_ERR_MSG_ATTR(info->extack, tb[NL80211_PMSR_ATTR_TYPE_CAPA], -- 2.34.1