Loading drivers/net/wireless/ath/wil6210/ftm.c +59 −38 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ nla_policy wil_nl80211_loc_policy[QCA_ATTR_LOC_MAX + 1] = { [QCA_ATTR_FTM_INITIAL_TOKEN] = { .type = NLA_U8 }, [QCA_ATTR_AOA_TYPE] = { .type = NLA_U32 }, [QCA_ATTR_LOC_ANTENNA_ARRAY_MASK] = { .type = NLA_U32 }, [QCA_ATTR_FREQ] = { .type = NLA_U32 }, }; static const struct Loading @@ -52,6 +53,7 @@ nla_policy wil_nl80211_ftm_peer_policy[QCA_ATTR_FTM_PEER_MAX + 1] = { [QCA_ATTR_FTM_PEER_MEAS_FLAGS] = { .type = NLA_U32 }, [QCA_ATTR_FTM_PEER_MEAS_PARAMS] = { .type = NLA_NESTED }, [QCA_ATTR_FTM_PEER_SEC_TOK_ID] = { .type = NLA_U8 }, [QCA_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 }, }; static const struct Loading @@ -62,6 +64,37 @@ nla_policy wil_nl80211_ftm_meas_param_policy[QCA_ATTR_FTM_PARAM_MAX + 1] = { [QCA_ATTR_FTM_PARAM_BURST_PERIOD] = { .type = NLA_U16 }, }; static u8 wil_ftm_get_channel(struct wil6210_priv *wil, const u8 *mac_addr, u32 freq) { struct wiphy *wiphy = wil_to_wiphy(wil); struct cfg80211_bss *bss; struct ieee80211_channel *chan; u8 channel; if (freq) { chan = ieee80211_get_channel(wiphy, freq); if (!chan) { wil_err(wil, "invalid freq: %d\n", freq); return 0; } channel = chan->hw_value; } else { bss = cfg80211_get_bss(wiphy, NULL, mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "Unable to find BSS\n"); return 0; } channel = bss->channel->hw_value; cfg80211_put_bss(wiphy, bss); } wil_dbg_misc(wil, "target %pM at channel %d\n", mac_addr, channel); return channel; } static int wil_ftm_parse_meas_params(struct wil6210_priv *wil, struct nlattr *attr, struct wil_ftm_meas_params *params) Loading Loading @@ -268,7 +301,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, struct wil6210_priv *wil = vif_to_wil(vif); int rc = 0; bool has_lci = false, has_lcr = false; u8 max_meas = 0, *ptr; u8 max_meas = 0, channel, *ptr; u32 i, cmd_len; struct wmi_tof_session_start_cmd *cmd; Loading @@ -278,12 +311,6 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, rc = -EAGAIN; goto out; } /* for now allow measurement to associated AP only */ if (!test_bit(wil_vif_fwconnected, vif->status)) { wil_err(wil, "must be associated\n"); rc = -ENOTSUPP; goto out; } for (i = 0; i < request->n_peers; i++) { if (request->peers[i].flags & Loading Loading @@ -328,7 +355,14 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, for (i = 0; i < request->n_peers; i++) { ether_addr_copy(cmd->ftm_dest_info[i].dst_mac, request->peers[i].mac_addr); cmd->ftm_dest_info[i].channel = request->peers[i].channel; channel = wil_ftm_get_channel(wil, request->peers[i].mac_addr, request->peers[i].freq); if (!channel) { wil_err(wil, "can't find FTM target at index %d\n", i); rc = -EINVAL; goto out_cmd; } cmd->ftm_dest_info[i].channel = channel - 1; if (request->peers[i].flags & QCA_ATTR_FTM_PEER_MEAS_FLAG_SECURE) { cmd->ftm_dest_info[i].flags |= Loading Loading @@ -363,14 +397,13 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, vif->mid, cmd, cmd_len); kfree(cmd); if (rc) goto out_ftm_res; if (!rc) { vif->ftm.session_cookie = request->session_cookie; vif->ftm.session_started = 1; } out_cmd: kfree(cmd); out_ftm_res: if (rc) { kfree(vif->ftm.ftm_res); Loading Loading @@ -444,8 +477,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, { struct wil6210_priv *wil = vif_to_wil(vif); int rc = 0; struct cfg80211_bss *bss; struct wmi_aoa_meas_cmd cmd; u8 channel; mutex_lock(&vif->ftm.lock); Loading @@ -460,30 +493,25 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, goto out; } bss = cfg80211_get_bss(wil_to_wiphy(wil), NULL, request->mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "Unable to find BSS\n"); rc = -ENOENT; channel = wil_ftm_get_channel(wil, request->mac_addr, request->freq); if (!channel) { rc = -EINVAL; goto out; } memset(&cmd, 0, sizeof(cmd)); ether_addr_copy(cmd.mac_addr, request->mac_addr); cmd.channel = bss->channel->hw_value - 1; cmd.channel = channel - 1; cmd.aoa_meas_type = request->type; rc = wmi_send(wil, WMI_AOA_MEAS_CMDID, vif->mid, &cmd, sizeof(cmd)); if (rc) goto out_bss; goto out; ether_addr_copy(vif->ftm.aoa_peer_mac_addr, request->mac_addr); mod_timer(&vif->ftm.aoa_timer, jiffies + msecs_to_jiffies(WIL_AOA_MEASUREMENT_TIMEOUT)); vif->ftm.aoa_started = 1; out_bss: cfg80211_put_bss(wil_to_wiphy(wil), bss); out: mutex_unlock(&vif->ftm.lock); return rc; Loading Loading @@ -725,7 +753,6 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, struct nlattr *tb2[QCA_ATTR_FTM_PEER_MAX + 1]; struct nlattr *peer; int rc, n_peers = 0, index = 0, tmp; struct cfg80211_bss *bss; if (!test_bit(WMI_FW_CAPABILITY_FTM, wil->fw_capabilities)) return -ENOTSUPP; Loading Loading @@ -789,17 +816,9 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, memcpy(request->peers[index].mac_addr, nla_data(tb2[QCA_ATTR_FTM_PEER_MAC_ADDR]), ETH_ALEN); bss = cfg80211_get_bss(wiphy, NULL, request->peers[index].mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "invalid bss at index %d\n", index); rc = -ENOENT; goto out; } request->peers[index].channel = bss->channel->hw_value - 1; cfg80211_put_bss(wiphy, bss); if (tb2[QCA_ATTR_FTM_PEER_FREQ]) request->peers[index].freq = nla_get_u32(tb2[QCA_ATTR_FTM_PEER_FREQ]); if (tb2[QCA_ATTR_FTM_PEER_MEAS_FLAGS]) request->peers[index].flags = nla_get_u32(tb2[QCA_ATTR_FTM_PEER_MEAS_FLAGS]); Loading Loading @@ -874,6 +893,8 @@ int wil_aoa_start_measurement(struct wiphy *wiphy, struct wireless_dev *wdev, ether_addr_copy(request.mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); request.type = nla_get_u32(tb[QCA_ATTR_AOA_TYPE]); if (tb[QCA_ATTR_FREQ]) request.freq = nla_get_u32(tb[QCA_ATTR_FREQ]); rc = wil_aoa_cfg80211_start_measurement(vif, &request); return rc; Loading drivers/net/wireless/ath/wil6210/ftm.h +9 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ * %QCA_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16 * values, phase and amplitude of the strongest CIR path for each * antenna in the measured array(s) * @QCA_WLAN_VENDOR_ATTR_FREQ: Frequency where peer is listening, in MHz. * Unsigned 32 bit value. */ enum qca_attr_loc { QCA_ATTR_FTM_SESSION_COOKIE = 14, Loading @@ -78,6 +80,7 @@ enum qca_attr_loc { QCA_ATTR_AOA_TYPE = 23, QCA_ATTR_LOC_ANTENNA_ARRAY_MASK = 24, QCA_ATTR_AOA_MEAS_RESULT = 25, QCA_ATTR_FREQ = 28, /* keep last */ QCA_ATTR_LOC_AFTER_LAST, QCA_ATTR_LOC_MAX = QCA_ATTR_LOC_AFTER_LAST - 1, Loading Loading @@ -160,6 +163,9 @@ enum qca_attr_loc_capa_flags { * @QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA * measurement every _value_ bursts. If 0 or not specified, * AOA measurements will be disabled for this peer. * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ: Frequency in MHz where * peer is listening. Optional; if not specified, use the * entry from the kernel scan results cache. */ enum qca_attr_ftm_peer_info { QCA_ATTR_FTM_PEER_INVALID, Loading @@ -168,6 +174,7 @@ enum qca_attr_ftm_peer_info { QCA_ATTR_FTM_PEER_MEAS_PARAMS, QCA_ATTR_FTM_PEER_SEC_TOK_ID, QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD, QCA_ATTR_FTM_PEER_FREQ, /* keep last */ QCA_ATTR_FTM_PEER_AFTER_LAST, QCA_ATTR_FTM_PEER_MAX = Loading Loading @@ -410,7 +417,7 @@ struct wil_ftm_meas_params { /* measurement request for a single peer */ struct wil_ftm_meas_peer_info { u8 mac_addr[ETH_ALEN]; u8 channel; u32 freq; u32 flags; /* enum qca_attr_ftm_peer_meas_flags */ struct wil_ftm_meas_params params; u8 secure_token_id; Loading Loading @@ -449,6 +456,7 @@ struct wil_ftm_peer_meas_res { /* standalone AOA measurement request */ struct wil_aoa_meas_request { u8 mac_addr[ETH_ALEN]; u32 freq; u32 type; }; Loading Loading
drivers/net/wireless/ath/wil6210/ftm.c +59 −38 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ nla_policy wil_nl80211_loc_policy[QCA_ATTR_LOC_MAX + 1] = { [QCA_ATTR_FTM_INITIAL_TOKEN] = { .type = NLA_U8 }, [QCA_ATTR_AOA_TYPE] = { .type = NLA_U32 }, [QCA_ATTR_LOC_ANTENNA_ARRAY_MASK] = { .type = NLA_U32 }, [QCA_ATTR_FREQ] = { .type = NLA_U32 }, }; static const struct Loading @@ -52,6 +53,7 @@ nla_policy wil_nl80211_ftm_peer_policy[QCA_ATTR_FTM_PEER_MAX + 1] = { [QCA_ATTR_FTM_PEER_MEAS_FLAGS] = { .type = NLA_U32 }, [QCA_ATTR_FTM_PEER_MEAS_PARAMS] = { .type = NLA_NESTED }, [QCA_ATTR_FTM_PEER_SEC_TOK_ID] = { .type = NLA_U8 }, [QCA_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 }, }; static const struct Loading @@ -62,6 +64,37 @@ nla_policy wil_nl80211_ftm_meas_param_policy[QCA_ATTR_FTM_PARAM_MAX + 1] = { [QCA_ATTR_FTM_PARAM_BURST_PERIOD] = { .type = NLA_U16 }, }; static u8 wil_ftm_get_channel(struct wil6210_priv *wil, const u8 *mac_addr, u32 freq) { struct wiphy *wiphy = wil_to_wiphy(wil); struct cfg80211_bss *bss; struct ieee80211_channel *chan; u8 channel; if (freq) { chan = ieee80211_get_channel(wiphy, freq); if (!chan) { wil_err(wil, "invalid freq: %d\n", freq); return 0; } channel = chan->hw_value; } else { bss = cfg80211_get_bss(wiphy, NULL, mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "Unable to find BSS\n"); return 0; } channel = bss->channel->hw_value; cfg80211_put_bss(wiphy, bss); } wil_dbg_misc(wil, "target %pM at channel %d\n", mac_addr, channel); return channel; } static int wil_ftm_parse_meas_params(struct wil6210_priv *wil, struct nlattr *attr, struct wil_ftm_meas_params *params) Loading Loading @@ -268,7 +301,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, struct wil6210_priv *wil = vif_to_wil(vif); int rc = 0; bool has_lci = false, has_lcr = false; u8 max_meas = 0, *ptr; u8 max_meas = 0, channel, *ptr; u32 i, cmd_len; struct wmi_tof_session_start_cmd *cmd; Loading @@ -278,12 +311,6 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, rc = -EAGAIN; goto out; } /* for now allow measurement to associated AP only */ if (!test_bit(wil_vif_fwconnected, vif->status)) { wil_err(wil, "must be associated\n"); rc = -ENOTSUPP; goto out; } for (i = 0; i < request->n_peers; i++) { if (request->peers[i].flags & Loading Loading @@ -328,7 +355,14 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, for (i = 0; i < request->n_peers; i++) { ether_addr_copy(cmd->ftm_dest_info[i].dst_mac, request->peers[i].mac_addr); cmd->ftm_dest_info[i].channel = request->peers[i].channel; channel = wil_ftm_get_channel(wil, request->peers[i].mac_addr, request->peers[i].freq); if (!channel) { wil_err(wil, "can't find FTM target at index %d\n", i); rc = -EINVAL; goto out_cmd; } cmd->ftm_dest_info[i].channel = channel - 1; if (request->peers[i].flags & QCA_ATTR_FTM_PEER_MEAS_FLAG_SECURE) { cmd->ftm_dest_info[i].flags |= Loading Loading @@ -363,14 +397,13 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, vif->mid, cmd, cmd_len); kfree(cmd); if (rc) goto out_ftm_res; if (!rc) { vif->ftm.session_cookie = request->session_cookie; vif->ftm.session_started = 1; } out_cmd: kfree(cmd); out_ftm_res: if (rc) { kfree(vif->ftm.ftm_res); Loading Loading @@ -444,8 +477,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, { struct wil6210_priv *wil = vif_to_wil(vif); int rc = 0; struct cfg80211_bss *bss; struct wmi_aoa_meas_cmd cmd; u8 channel; mutex_lock(&vif->ftm.lock); Loading @@ -460,30 +493,25 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, goto out; } bss = cfg80211_get_bss(wil_to_wiphy(wil), NULL, request->mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "Unable to find BSS\n"); rc = -ENOENT; channel = wil_ftm_get_channel(wil, request->mac_addr, request->freq); if (!channel) { rc = -EINVAL; goto out; } memset(&cmd, 0, sizeof(cmd)); ether_addr_copy(cmd.mac_addr, request->mac_addr); cmd.channel = bss->channel->hw_value - 1; cmd.channel = channel - 1; cmd.aoa_meas_type = request->type; rc = wmi_send(wil, WMI_AOA_MEAS_CMDID, vif->mid, &cmd, sizeof(cmd)); if (rc) goto out_bss; goto out; ether_addr_copy(vif->ftm.aoa_peer_mac_addr, request->mac_addr); mod_timer(&vif->ftm.aoa_timer, jiffies + msecs_to_jiffies(WIL_AOA_MEASUREMENT_TIMEOUT)); vif->ftm.aoa_started = 1; out_bss: cfg80211_put_bss(wil_to_wiphy(wil), bss); out: mutex_unlock(&vif->ftm.lock); return rc; Loading Loading @@ -725,7 +753,6 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, struct nlattr *tb2[QCA_ATTR_FTM_PEER_MAX + 1]; struct nlattr *peer; int rc, n_peers = 0, index = 0, tmp; struct cfg80211_bss *bss; if (!test_bit(WMI_FW_CAPABILITY_FTM, wil->fw_capabilities)) return -ENOTSUPP; Loading Loading @@ -789,17 +816,9 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, memcpy(request->peers[index].mac_addr, nla_data(tb2[QCA_ATTR_FTM_PEER_MAC_ADDR]), ETH_ALEN); bss = cfg80211_get_bss(wiphy, NULL, request->peers[index].mac_addr, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); if (!bss) { wil_err(wil, "invalid bss at index %d\n", index); rc = -ENOENT; goto out; } request->peers[index].channel = bss->channel->hw_value - 1; cfg80211_put_bss(wiphy, bss); if (tb2[QCA_ATTR_FTM_PEER_FREQ]) request->peers[index].freq = nla_get_u32(tb2[QCA_ATTR_FTM_PEER_FREQ]); if (tb2[QCA_ATTR_FTM_PEER_MEAS_FLAGS]) request->peers[index].flags = nla_get_u32(tb2[QCA_ATTR_FTM_PEER_MEAS_FLAGS]); Loading Loading @@ -874,6 +893,8 @@ int wil_aoa_start_measurement(struct wiphy *wiphy, struct wireless_dev *wdev, ether_addr_copy(request.mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); request.type = nla_get_u32(tb[QCA_ATTR_AOA_TYPE]); if (tb[QCA_ATTR_FREQ]) request.freq = nla_get_u32(tb[QCA_ATTR_FREQ]); rc = wil_aoa_cfg80211_start_measurement(vif, &request); return rc; Loading
drivers/net/wireless/ath/wil6210/ftm.h +9 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ * %QCA_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16 * values, phase and amplitude of the strongest CIR path for each * antenna in the measured array(s) * @QCA_WLAN_VENDOR_ATTR_FREQ: Frequency where peer is listening, in MHz. * Unsigned 32 bit value. */ enum qca_attr_loc { QCA_ATTR_FTM_SESSION_COOKIE = 14, Loading @@ -78,6 +80,7 @@ enum qca_attr_loc { QCA_ATTR_AOA_TYPE = 23, QCA_ATTR_LOC_ANTENNA_ARRAY_MASK = 24, QCA_ATTR_AOA_MEAS_RESULT = 25, QCA_ATTR_FREQ = 28, /* keep last */ QCA_ATTR_LOC_AFTER_LAST, QCA_ATTR_LOC_MAX = QCA_ATTR_LOC_AFTER_LAST - 1, Loading Loading @@ -160,6 +163,9 @@ enum qca_attr_loc_capa_flags { * @QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA * measurement every _value_ bursts. If 0 or not specified, * AOA measurements will be disabled for this peer. * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ: Frequency in MHz where * peer is listening. Optional; if not specified, use the * entry from the kernel scan results cache. */ enum qca_attr_ftm_peer_info { QCA_ATTR_FTM_PEER_INVALID, Loading @@ -168,6 +174,7 @@ enum qca_attr_ftm_peer_info { QCA_ATTR_FTM_PEER_MEAS_PARAMS, QCA_ATTR_FTM_PEER_SEC_TOK_ID, QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD, QCA_ATTR_FTM_PEER_FREQ, /* keep last */ QCA_ATTR_FTM_PEER_AFTER_LAST, QCA_ATTR_FTM_PEER_MAX = Loading Loading @@ -410,7 +417,7 @@ struct wil_ftm_meas_params { /* measurement request for a single peer */ struct wil_ftm_meas_peer_info { u8 mac_addr[ETH_ALEN]; u8 channel; u32 freq; u32 flags; /* enum qca_attr_ftm_peer_meas_flags */ struct wil_ftm_meas_params params; u8 secure_token_id; Loading Loading @@ -449,6 +456,7 @@ struct wil_ftm_peer_meas_res { /* standalone AOA measurement request */ struct wil_aoa_meas_request { u8 mac_addr[ETH_ALEN]; u32 freq; u32 type; }; Loading