mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
Merge "wil6210: allow flashless boot when OTP is empty"
This commit is contained in:
commit
6ee52846b9
7 changed files with 140 additions and 25 deletions
|
|
@ -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)
|
||||
|
||||
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
@ -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++;
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -253,10 +253,47 @@ out:
|
|||
|
||||
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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -826,7 +826,7 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
|
|||
s32 signal;
|
||||
__le16 fc;
|
||||
u32 d_len;
|
||||
u16 d_status;
|
||||
s16 snr;
|
||||
|
||||
if (flen < 0) {
|
||||
wil_err(wil, "MGMT Rx: short event, len %d\n", len);
|
||||
|
|
@ -848,13 +848,13 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
|
|||
signal = 100 * data->info.rssi;
|
||||
else
|
||||
signal = data->info.sqi;
|
||||
d_status = le16_to_cpu(data->info.status);
|
||||
snr = le16_to_cpu(data->info.snr); /* 1/4 dB units */
|
||||
fc = rx_mgmt_frame->frame_control;
|
||||
|
||||
wil_dbg_wmi(wil, "MGMT Rx: channel %d MCS %d RSSI %d SQI %d%%\n",
|
||||
data->info.channel, data->info.mcs, data->info.rssi,
|
||||
data->info.sqi);
|
||||
wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len,
|
||||
wil_dbg_wmi(wil, "snr %ddB len %d fc 0x%04x\n", snr / 4, d_len,
|
||||
le16_to_cpu(fc));
|
||||
wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
|
||||
data->info.qid, data->info.mid, data->info.cid);
|
||||
|
|
@ -888,6 +888,11 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
|
|||
|
||||
wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
|
||||
|
||||
if (wil->snr_thresh.enabled && snr < wil->snr_thresh.omni) {
|
||||
wil_dbg_wmi(wil, "snr below threshold. dropping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data,
|
||||
rx_mgmt_frame,
|
||||
d_len, GFP_KERNEL);
|
||||
|
|
@ -3579,6 +3584,37 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int wmi_set_snr_thresh(struct wil6210_priv *wil, short omni, short direct)
|
||||
{
|
||||
struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
|
||||
int rc;
|
||||
struct wmi_set_connect_snr_thr_cmd cmd = {
|
||||
.enable = true,
|
||||
.omni_snr_thr = cpu_to_le16(omni),
|
||||
.direct_snr_thr = cpu_to_le16(direct),
|
||||
};
|
||||
|
||||
if (!test_bit(WMI_FW_CAPABILITY_CONNECT_SNR_THR, wil->fw_capabilities))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (omni == 0 && direct == 0)
|
||||
cmd.enable = false;
|
||||
|
||||
wil_dbg_wmi(wil, "%s snr thresh omni=%d, direct=%d (1/4 dB units)\n",
|
||||
cmd.enable ? "enable" : "disable", omni, direct);
|
||||
|
||||
rc = wmi_send(wil, WMI_SET_CONNECT_SNR_THR_CMDID, vif->mid,
|
||||
&cmd, sizeof(cmd));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
wil->snr_thresh.enabled = cmd.enable;
|
||||
wil->snr_thresh.omni = omni;
|
||||
wil->snr_thresh.direct = direct;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
wmi_sched_scan_set_ssids(struct wil6210_priv *wil,
|
||||
struct wmi_start_sched_scan_cmd *cmd,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2006-2012 Wilocity
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -97,6 +86,7 @@ enum wmi_fw_capability {
|
|||
WMI_FW_CAPABILITY_SET_SILENT_RSSI_TABLE = 13,
|
||||
WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP = 14,
|
||||
WMI_FW_CAPABILITY_PNO = 15,
|
||||
WMI_FW_CAPABILITY_CONNECT_SNR_THR = 16,
|
||||
WMI_FW_CAPABILITY_CHANNEL_BONDING = 17,
|
||||
WMI_FW_CAPABILITY_REF_CLOCK_CONTROL = 18,
|
||||
WMI_FW_CAPABILITY_AP_SME_OFFLOAD_NONE = 19,
|
||||
|
|
@ -2436,7 +2426,7 @@ struct wmi_rx_mgmt_info {
|
|||
u8 range;
|
||||
u8 sqi;
|
||||
__le16 stype;
|
||||
__le16 status;
|
||||
__le16 snr;
|
||||
__le32 len;
|
||||
/* Not resolved when == 0xFFFFFFFF == > Broadcast to all MIDS */
|
||||
u8 qid;
|
||||
|
|
|
|||
Loading…
Reference in a new issue