summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorLior David <liord@codeaurora.org>2016-11-24 23:40:46 +0200
committerLior David <liord@codeaurora.org>2016-11-24 23:57:16 +0200
commita43a0922820f45abe9ca30a8c4f4a418b4bb7cfe (patch)
tree6c5c5f65d3bb32328786d2f34808c2ff7b76f58e /drivers/net
parenta9a8ec4cae40a79da84d2fa641b5cb5821e463c4 (diff)
wil6210: support FTM/AOA while unassociated
Prepare driver for FTM/AOA while unassociated. 1. Added attributes allowing user space to specify the frequency where FTM/AOA peer is listening. When specified it will override the entry in the kernel scan results cache. If not specified, the kernel scan results cache will be used like today. This gives user space location framework more flexibility - it can maintain its own cache of peers, or perform scans less often (since entries in the kernel scan results cache expire quickly) 2. Remove associated check when starting FTM session, so session can start even when unassociated. Change-Id: Ib0ba52c506e1d8d59ab8c12043acd792405d69a0 CRs-Fixed: 1094147 Signed-off-by: Lior David <liord@codeaurora.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/wil6210/ftm.c97
-rw-r--r--drivers/net/wireless/ath/wil6210/ftm.h10
2 files changed, 68 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath/wil6210/ftm.c b/drivers/net/wireless/ath/wil6210/ftm.c
index 5cf07343a33c..6891a38d7a59 100644
--- a/drivers/net/wireless/ath/wil6210/ftm.c
+++ b/drivers/net/wireless/ath/wil6210/ftm.c
@@ -52,6 +52,7 @@ nla_policy wil_nl80211_loc_policy[QCA_WLAN_VENDOR_ATTR_LOC_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_FTM_INITIAL_TOKEN] = { .type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_AOA_TYPE] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK] = { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_FREQ] = { .type = NLA_U32 },
};
static const struct
@@ -61,6 +62,7 @@ nla_policy wil_nl80211_ftm_peer_policy[
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS] = { .type = NLA_NESTED },
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 },
};
static const struct
@@ -72,6 +74,37 @@ nla_policy wil_nl80211_ftm_meas_param_policy[
[QCA_WLAN_VENDOR_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)
@@ -273,7 +306,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
{
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;
@@ -283,12 +316,6 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
rc = -EAGAIN;
goto out;
}
- /* for now allow measurement to associated AP only */
- if (!test_bit(wil_status_fwconnected, wil->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 &
@@ -333,7 +360,14 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
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_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE) {
cmd->ftm_dest_info[i].flags |=
@@ -367,14 +401,13 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
}
rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, cmd, cmd_len);
- kfree(cmd);
-
- if (rc)
- goto out_ftm_res;
-
- wil->ftm.session_cookie = request->session_cookie;
- wil->ftm.session_started = 1;
+ if (!rc) {
+ wil->ftm.session_cookie = request->session_cookie;
+ wil->ftm.session_started = 1;
+ }
+out_cmd:
+ kfree(cmd);
out_ftm_res:
if (rc) {
kfree(wil->ftm.ftm_res);
@@ -444,8 +477,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_priv *wil,
struct wil_aoa_meas_request *request)
{
int rc = 0;
- struct cfg80211_bss *bss;
struct wmi_aoa_meas_cmd cmd;
+ u8 channel;
mutex_lock(&wil->ftm.lock);
@@ -460,30 +493,25 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_priv *wil,
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, &cmd, sizeof(cmd));
if (rc)
- goto out_bss;
+ goto out;
ether_addr_copy(wil->ftm.aoa_peer_mac_addr, request->mac_addr);
mod_timer(&wil->ftm.aoa_timer,
jiffies + msecs_to_jiffies(WIL_AOA_MEASUREMENT_TIMEOUT));
wil->ftm.aoa_started = 1;
-out_bss:
- cfg80211_put_bss(wil_to_wiphy(wil), bss);
out:
mutex_unlock(&wil->ftm.lock);
return rc;
@@ -721,7 +749,6 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev,
struct nlattr *tb2[QCA_WLAN_VENDOR_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;
@@ -785,17 +812,9 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev,
memcpy(request->peers[index].mac_addr,
nla_data(tb2[QCA_WLAN_VENDOR_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_WLAN_VENDOR_ATTR_FTM_PEER_FREQ])
+ request->peers[index].freq = nla_get_u32(
+ tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ]);
if (tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS])
request->peers[index].flags = nla_get_u32(
tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS]);
@@ -868,6 +887,8 @@ int wil_aoa_start_measurement(struct wiphy *wiphy, struct wireless_dev *wdev,
ether_addr_copy(request.mac_addr,
nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]));
request.type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_AOA_TYPE]);
+ if (tb[QCA_WLAN_VENDOR_ATTR_FREQ])
+ request.freq = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_FREQ]);
rc = wil_aoa_cfg80211_start_measurement(wil, &request);
return rc;
diff --git a/drivers/net/wireless/ath/wil6210/ftm.h b/drivers/net/wireless/ath/wil6210/ftm.h
index 9721344579aa..ea186d641d59 100644
--- a/drivers/net/wireless/ath/wil6210/ftm.h
+++ b/drivers/net/wireless/ath/wil6210/ftm.h
@@ -77,6 +77,8 @@
* %QCA_WLAN_VENDOR_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_wlan_vendor_attr_loc {
/* we reuse these attributes */
@@ -94,6 +96,7 @@ enum qca_wlan_vendor_attr_loc {
QCA_WLAN_VENDOR_ATTR_AOA_TYPE = 23,
QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK = 24,
QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT = 25,
+ QCA_WLAN_VENDOR_ATTR_FREQ = 26,
/* keep last */
QCA_WLAN_VENDOR_ATTR_LOC_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_LOC_MAX = QCA_WLAN_VENDOR_ATTR_LOC_AFTER_LAST - 1,
@@ -176,6 +179,9 @@ enum qca_wlan_vendor_attr_loc_capa_flags {
* @QCA_WLAN_VENDOR_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_wlan_vendor_attr_ftm_peer_info {
QCA_WLAN_VENDOR_ATTR_FTM_PEER_INVALID,
@@ -184,6 +190,7 @@ enum qca_wlan_vendor_attr_ftm_peer_info {
QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD,
+ QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ,
/* keep last */
QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX =
@@ -426,7 +433,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_wlan_vendor_attr_ftm_peer_meas_flags */
struct wil_ftm_meas_params params;
u8 secure_token_id;
@@ -465,6 +472,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;
};