Loading drivers/net/wireless/ath/wil6210/ftm.c +37 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ /* initial token to use on non-secure FTM measurement */ #define WIL_TOF_FTM_DEFAULT_INITIAL_TOKEN 2 /* maximum AOA burst period, limited by FW */ #define WIL_AOA_MAX_BURST_PERIOD 255 #define WIL_TOF_FTM_MAX_LCI_LENGTH (240) #define WIL_TOF_FTM_MAX_LCR_LENGTH (240) Loading Loading @@ -53,6 +56,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_AOA_BURST_PERIOD] = { .type = NLA_U16 }, [QCA_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 }, }; Loading Loading @@ -351,6 +355,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, } cmd->session_id = cpu_to_le32(WIL_FTM_FW_SESSION_ID); cmd->aoa_type = request->aoa_type; cmd->num_of_dest = cpu_to_le16(request->n_peers); for (i = 0; i < request->n_peers; i++) { ether_addr_copy(cmd->ftm_dest_info[i].dst_mac, Loading Loading @@ -393,6 +398,8 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, request->peers[i].params.burst_duration; cmd->ftm_dest_info[i].burst_period = cpu_to_le16(request->peers[i].params.burst_period); cmd->ftm_dest_info[i].num_burst_per_aoa_meas = request->peers[i].aoa_burst_period; } rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, vif->mid, Loading Loading @@ -482,8 +489,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, mutex_lock(&vif->ftm.lock); if (vif->ftm.aoa_started) { wil_err(wil, "AOA measurement already running\n"); if (vif->ftm.aoa_started || vif->ftm.session_started) { wil_err(wil, "AOA or FTM measurement already running\n"); rc = -EAGAIN; goto out; } Loading Loading @@ -525,8 +532,8 @@ void wil_aoa_cfg80211_meas_result(struct wil6210_vif *vif, mutex_lock(&vif->ftm.lock); if (!vif->ftm.aoa_started) { wil_info(wil, "AOA not started, not sending result\n"); if (!vif->ftm.aoa_started && !vif->ftm.session_started) { wil_info(wil, "AOA/FTM not started, not sending result\n"); goto out; } Loading Loading @@ -681,6 +688,10 @@ void wil_aoa_evt_meas(struct wil6210_vif *vif, int data_len = len - offsetof(struct wmi_aoa_meas_event, meas_data); struct wil_aoa_meas_result *res; if (data_len < 0) { wil_err(wil, "AOA event too short (%d)\n", len); return; } data_len = min_t(int, le16_to_cpu(evt->length), data_len); res = kmalloc(sizeof(*res) + data_len, GFP_KERNEL); Loading Loading @@ -753,6 +764,7 @@ 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; u32 aoa_type = 0; if (!test_bit(WMI_FW_CAPABILITY_FTM, wil->fw_capabilities)) return -ENOTSUPP; Loading @@ -774,6 +786,14 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, return -EINVAL; } if (tb[QCA_ATTR_AOA_TYPE]) { aoa_type = nla_get_u32(tb[QCA_ATTR_AOA_TYPE]); if (aoa_type >= QCA_ATTR_AOA_TYPE_MAX) { wil_err(wil, "invalid AOA type: %d\n", aoa_type); return -EINVAL; } } nla_for_each_nested(peer, tb[QCA_ATTR_FTM_MEAS_PEERS], tmp) n_peers++; Loading @@ -797,6 +817,7 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, request->session_cookie = nla_get_u64(tb[QCA_ATTR_FTM_SESSION_COOKIE]); request->aoa_type = aoa_type; request->n_peers = n_peers; nla_for_each_nested(peer, tb[QCA_ATTR_FTM_MEAS_PEERS], tmp) { Loading Loading @@ -825,6 +846,18 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, if (tb2[QCA_ATTR_FTM_PEER_SEC_TOK_ID]) request->peers[index].secure_token_id = nla_get_u8(tb2[QCA_ATTR_FTM_PEER_SEC_TOK_ID]); if (tb2[QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD]) { request->peers[index].aoa_burst_period = nla_get_u16(tb2[QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD]); if (request->peers[index].aoa_burst_period > WIL_AOA_MAX_BURST_PERIOD) { wil_err(wil, "Invalid AOA burst period at index: %d\n", index); rc = -EINVAL; goto out; } } rc = wil_ftm_parse_meas_params(wil, tb2[QCA_ATTR_FTM_PEER_MEAS_PARAMS], Loading drivers/net/wireless/ath/wil6210/ftm.h +2 −0 Original line number Diff line number Diff line Loading @@ -421,12 +421,14 @@ struct wil_ftm_meas_peer_info { u32 flags; /* enum qca_attr_ftm_peer_meas_flags */ struct wil_ftm_meas_params params; u8 secure_token_id; u16 aoa_burst_period; /* 0 if no AOA, >0 every <value> bursts */ }; /* session request, passed to wil_ftm_cfg80211_start_session */ struct wil_ftm_session_request { u64 session_cookie; u32 n_peers; u32 aoa_type; /* enum qca_wlan_vendor_attr_aoa_type */ /* keep last, variable size according to n_peers */ struct wil_ftm_meas_peer_info peers[0]; }; Loading drivers/net/wireless/ath/wil6210/main.c +15 −5 Original line number Diff line number Diff line Loading @@ -1425,8 +1425,14 @@ static int wil_get_otp_info(struct wil6210_priv *wil) } if (!is_valid_ether_addr(mac)) { wil_err(wil, "Invalid MAC %pM\n", mac); return -EINVAL; u8 dummy_mac[ETH_ALEN] = { 0x00, 0xde, 0xad, 0x12, 0x34, 0x56, }; if (!test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) get_random_bytes(dummy_mac + 3, 3); wil_err(wil, "Invalid MAC %pM, using random %pM\n", mac, dummy_mac); ether_addr_copy(mac, dummy_mac); } ether_addr_copy(ndev->perm_addr, mac); Loading Loading @@ -1768,14 +1774,18 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) return rc; } if (wil->tt_data_set) wmi_set_tt_cfg(wil, &wil->tt_data); wil_collect_fw_info(wil); if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) wil_ps_update(wil, wil->ps_profile); if (wil->tt_data_set) wmi_set_tt_cfg(wil, &wil->tt_data); if (wil->snr_thresh.enabled) wmi_set_snr_thresh(wil, wil->snr_thresh.omni, wil->snr_thresh.direct); if (wil->platform_ops.notify) { rc = wil->platform_ops.notify(wil->platform_handle, WIL_PLATFORM_EVT_FW_RDY); Loading drivers/net/wireless/ath/wil6210/sysfs.c +37 −0 Original line number Diff line number Diff line Loading @@ -253,10 +253,47 @@ fst_link_loss_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(fst_link_loss); static ssize_t snr_thresh_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); ssize_t len = 0; if (wil->snr_thresh.enabled) len = snprintf(buf, PAGE_SIZE, "omni=%d, direct=%d\n", wil->snr_thresh.omni, wil->snr_thresh.direct); return len; } static ssize_t snr_thresh_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); int rc; short omni, direct; /* to disable snr threshold, set both omni and direct to 0 */ if (sscanf(buf, "%hd %hd", &omni, &direct) != 2) return -EINVAL; rc = wmi_set_snr_thresh(wil, omni, direct); if (!rc) rc = count; return rc; } static DEVICE_ATTR_RW(snr_thresh); static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, &dev_attr_snr_thresh.attr, NULL }; Loading drivers/net/wireless/ath/wil6210/wil6210.h +7 −0 Original line number Diff line number Diff line Loading @@ -1039,6 +1039,11 @@ struct wil6210_priv { int fw_calib_result; u8 tt_data_set; struct wmi_tt_data tt_data; struct { u8 enabled; short omni; short direct; } snr_thresh; struct notifier_block pm_notify; Loading Loading @@ -1440,6 +1445,8 @@ int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss); int wmi_set_snr_thresh(struct wil6210_priv *wil, short omni, short direct); int wmi_start_sched_scan(struct wil6210_priv *wil, struct cfg80211_sched_scan_request *request); int wmi_stop_sched_scan(struct wil6210_priv *wil); Loading Loading
drivers/net/wireless/ath/wil6210/ftm.c +37 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ /* initial token to use on non-secure FTM measurement */ #define WIL_TOF_FTM_DEFAULT_INITIAL_TOKEN 2 /* maximum AOA burst period, limited by FW */ #define WIL_AOA_MAX_BURST_PERIOD 255 #define WIL_TOF_FTM_MAX_LCI_LENGTH (240) #define WIL_TOF_FTM_MAX_LCR_LENGTH (240) Loading Loading @@ -53,6 +56,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_AOA_BURST_PERIOD] = { .type = NLA_U16 }, [QCA_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 }, }; Loading Loading @@ -351,6 +355,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, } cmd->session_id = cpu_to_le32(WIL_FTM_FW_SESSION_ID); cmd->aoa_type = request->aoa_type; cmd->num_of_dest = cpu_to_le16(request->n_peers); for (i = 0; i < request->n_peers; i++) { ether_addr_copy(cmd->ftm_dest_info[i].dst_mac, Loading Loading @@ -393,6 +398,8 @@ wil_ftm_cfg80211_start_session(struct wil6210_vif *vif, request->peers[i].params.burst_duration; cmd->ftm_dest_info[i].burst_period = cpu_to_le16(request->peers[i].params.burst_period); cmd->ftm_dest_info[i].num_burst_per_aoa_meas = request->peers[i].aoa_burst_period; } rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, vif->mid, Loading Loading @@ -482,8 +489,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_vif *vif, mutex_lock(&vif->ftm.lock); if (vif->ftm.aoa_started) { wil_err(wil, "AOA measurement already running\n"); if (vif->ftm.aoa_started || vif->ftm.session_started) { wil_err(wil, "AOA or FTM measurement already running\n"); rc = -EAGAIN; goto out; } Loading Loading @@ -525,8 +532,8 @@ void wil_aoa_cfg80211_meas_result(struct wil6210_vif *vif, mutex_lock(&vif->ftm.lock); if (!vif->ftm.aoa_started) { wil_info(wil, "AOA not started, not sending result\n"); if (!vif->ftm.aoa_started && !vif->ftm.session_started) { wil_info(wil, "AOA/FTM not started, not sending result\n"); goto out; } Loading Loading @@ -681,6 +688,10 @@ void wil_aoa_evt_meas(struct wil6210_vif *vif, int data_len = len - offsetof(struct wmi_aoa_meas_event, meas_data); struct wil_aoa_meas_result *res; if (data_len < 0) { wil_err(wil, "AOA event too short (%d)\n", len); return; } data_len = min_t(int, le16_to_cpu(evt->length), data_len); res = kmalloc(sizeof(*res) + data_len, GFP_KERNEL); Loading Loading @@ -753,6 +764,7 @@ 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; u32 aoa_type = 0; if (!test_bit(WMI_FW_CAPABILITY_FTM, wil->fw_capabilities)) return -ENOTSUPP; Loading @@ -774,6 +786,14 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, return -EINVAL; } if (tb[QCA_ATTR_AOA_TYPE]) { aoa_type = nla_get_u32(tb[QCA_ATTR_AOA_TYPE]); if (aoa_type >= QCA_ATTR_AOA_TYPE_MAX) { wil_err(wil, "invalid AOA type: %d\n", aoa_type); return -EINVAL; } } nla_for_each_nested(peer, tb[QCA_ATTR_FTM_MEAS_PEERS], tmp) n_peers++; Loading @@ -797,6 +817,7 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, request->session_cookie = nla_get_u64(tb[QCA_ATTR_FTM_SESSION_COOKIE]); request->aoa_type = aoa_type; request->n_peers = n_peers; nla_for_each_nested(peer, tb[QCA_ATTR_FTM_MEAS_PEERS], tmp) { Loading Loading @@ -825,6 +846,18 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev, if (tb2[QCA_ATTR_FTM_PEER_SEC_TOK_ID]) request->peers[index].secure_token_id = nla_get_u8(tb2[QCA_ATTR_FTM_PEER_SEC_TOK_ID]); if (tb2[QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD]) { request->peers[index].aoa_burst_period = nla_get_u16(tb2[QCA_ATTR_FTM_PEER_AOA_BURST_PERIOD]); if (request->peers[index].aoa_burst_period > WIL_AOA_MAX_BURST_PERIOD) { wil_err(wil, "Invalid AOA burst period at index: %d\n", index); rc = -EINVAL; goto out; } } rc = wil_ftm_parse_meas_params(wil, tb2[QCA_ATTR_FTM_PEER_MEAS_PARAMS], Loading
drivers/net/wireless/ath/wil6210/ftm.h +2 −0 Original line number Diff line number Diff line Loading @@ -421,12 +421,14 @@ struct wil_ftm_meas_peer_info { u32 flags; /* enum qca_attr_ftm_peer_meas_flags */ struct wil_ftm_meas_params params; u8 secure_token_id; u16 aoa_burst_period; /* 0 if no AOA, >0 every <value> bursts */ }; /* session request, passed to wil_ftm_cfg80211_start_session */ struct wil_ftm_session_request { u64 session_cookie; u32 n_peers; u32 aoa_type; /* enum qca_wlan_vendor_attr_aoa_type */ /* keep last, variable size according to n_peers */ struct wil_ftm_meas_peer_info peers[0]; }; Loading
drivers/net/wireless/ath/wil6210/main.c +15 −5 Original line number Diff line number Diff line Loading @@ -1425,8 +1425,14 @@ static int wil_get_otp_info(struct wil6210_priv *wil) } if (!is_valid_ether_addr(mac)) { wil_err(wil, "Invalid MAC %pM\n", mac); return -EINVAL; u8 dummy_mac[ETH_ALEN] = { 0x00, 0xde, 0xad, 0x12, 0x34, 0x56, }; if (!test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) get_random_bytes(dummy_mac + 3, 3); wil_err(wil, "Invalid MAC %pM, using random %pM\n", mac, dummy_mac); ether_addr_copy(mac, dummy_mac); } ether_addr_copy(ndev->perm_addr, mac); Loading Loading @@ -1768,14 +1774,18 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) return rc; } if (wil->tt_data_set) wmi_set_tt_cfg(wil, &wil->tt_data); wil_collect_fw_info(wil); if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) wil_ps_update(wil, wil->ps_profile); if (wil->tt_data_set) wmi_set_tt_cfg(wil, &wil->tt_data); if (wil->snr_thresh.enabled) wmi_set_snr_thresh(wil, wil->snr_thresh.omni, wil->snr_thresh.direct); if (wil->platform_ops.notify) { rc = wil->platform_ops.notify(wil->platform_handle, WIL_PLATFORM_EVT_FW_RDY); Loading
drivers/net/wireless/ath/wil6210/sysfs.c +37 −0 Original line number Diff line number Diff line Loading @@ -253,10 +253,47 @@ fst_link_loss_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(fst_link_loss); static ssize_t snr_thresh_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); ssize_t len = 0; if (wil->snr_thresh.enabled) len = snprintf(buf, PAGE_SIZE, "omni=%d, direct=%d\n", wil->snr_thresh.omni, wil->snr_thresh.direct); return len; } static ssize_t snr_thresh_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); int rc; short omni, direct; /* to disable snr threshold, set both omni and direct to 0 */ if (sscanf(buf, "%hd %hd", &omni, &direct) != 2) return -EINVAL; rc = wmi_set_snr_thresh(wil, omni, direct); if (!rc) rc = count; return rc; } static DEVICE_ATTR_RW(snr_thresh); static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, &dev_attr_snr_thresh.attr, NULL }; Loading
drivers/net/wireless/ath/wil6210/wil6210.h +7 −0 Original line number Diff line number Diff line Loading @@ -1039,6 +1039,11 @@ struct wil6210_priv { int fw_calib_result; u8 tt_data_set; struct wmi_tt_data tt_data; struct { u8 enabled; short omni; short direct; } snr_thresh; struct notifier_block pm_notify; Loading Loading @@ -1440,6 +1445,8 @@ int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss); int wmi_set_snr_thresh(struct wil6210_priv *wil, short omni, short direct); int wmi_start_sched_scan(struct wil6210_priv *wil, struct cfg80211_sched_scan_request *request); int wmi_stop_sched_scan(struct wil6210_priv *wil); Loading