Loading drivers/net/wireless/ath/wil6210/main.c +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) break; } sta->status = wil_sta_unused; sta->fst_link_loss = false; } /* reorder buffers */ for (i = 0; i < WIL_STA_TID_NUM; i++) { Loading drivers/net/wireless/ath/wil6210/sysfs.c +65 −0 Original line number Diff line number Diff line Loading @@ -204,9 +204,74 @@ wil_tt_sysfs_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(thermal_throttling, 0644, wil_tt_sysfs_show, wil_tt_sysfs_store); static ssize_t wil_fst_link_loss_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); ssize_t len = 0; int i; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) if (wil->sta[i].status == wil_sta_connected) len += snprintf(buf + len, PAGE_SIZE - len, "[%d] %pM %s\n", i, wil->sta[i].addr, wil->sta[i].fst_link_loss ? "On" : "Off"); return len; } static ssize_t wil_fst_link_loss_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); u8 addr[ETH_ALEN]; char *token, *dupbuf, *tmp; int rc = -EINVAL; bool fst_link_loss; tmp = kmemdup(buf, count + 1, GFP_KERNEL); if (!tmp) return -ENOMEM; tmp[count] = '\0'; dupbuf = tmp; token = strsep(&dupbuf, " "); if (!token) goto out; /* mac address */ if (sscanf(token, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) goto out; /* On/Off */ if (strtobool(dupbuf, &fst_link_loss)) goto out; wil_dbg_misc(wil, "set [%pM] with %d\n", addr, fst_link_loss); rc = wmi_link_maintain_cfg_write(wil, addr, fst_link_loss); if (!rc) rc = count; out: kfree(tmp); return rc; } static DEVICE_ATTR(fst_link_loss, 0644, wil_fst_link_loss_sysfs_show, wil_fst_link_loss_sysfs_store); static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, NULL }; Loading drivers/net/wireless/ath/wil6210/wil6210.h +5 −0 Original line number Diff line number Diff line Loading @@ -531,6 +531,7 @@ struct wil_sta_info { struct wil_tid_crypto_rx tid_crypto_rx[WIL_STA_TID_NUM]; struct wil_tid_crypto_rx group_crypto_rx; u8 aid; /* 1-254; 0 if unknown/not reported */ bool fst_link_loss; }; enum { Loading Loading @@ -987,5 +988,9 @@ void wil_ftm_evt_per_dest_res(struct wil6210_priv *wil, void wil_aoa_evt_meas(struct wil6210_priv *wil, struct wmi_aoa_meas_event *evt, int len); /* link loss */ int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss); #endif /* __WIL6210_H__ */ drivers/net/wireless/ath/wil6210/wmi.c +55 −0 Original line number Diff line number Diff line Loading @@ -1847,6 +1847,61 @@ void wmi_event_flush(struct wil6210_priv *wil) spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); } int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss) { int rc; int cid = wil_find_cid(wil, addr); u32 cfg_type; struct wmi_link_maintain_cfg_write_cmd cmd; struct { struct wmi_cmd_hdr wmi; struct wmi_link_maintain_cfg_write_done_event evt; } __packed reply; if (cid < 0) return cid; switch (wil->wdev->iftype) { case NL80211_IFTYPE_STATION: cfg_type = fst_link_loss ? WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_STA : WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_STA; break; case NL80211_IFTYPE_AP: cfg_type = fst_link_loss ? WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_AP : WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_AP; break; default: wil_err(wil, "Unsupported for iftype %d", wil->wdev->iftype); return -EINVAL; } wil_dbg_misc(wil, "Setting cid:%d with cfg_type:%d\n", cid, cfg_type); cmd.cfg_type = cpu_to_le32(cfg_type); cmd.cid = cpu_to_le32(cid); reply.evt.status = cpu_to_le32(WMI_FW_STATUS_FAILURE); rc = wmi_call(wil, WMI_LINK_MAINTAIN_CFG_WRITE_CMDID, &cmd, sizeof(cmd), WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID, &reply, sizeof(reply), 250); if (rc) { wil_err(wil, "Failed to %s FST link loss", fst_link_loss ? "enable" : "disable"); } else if (reply.evt.status == WMI_FW_STATUS_SUCCESS) { wil->sta[cid].fst_link_loss = fst_link_loss; } else { wil_err(wil, "WMI_LINK_MAINTAIN_CFG_WRITE_CMDID returned status %d", reply.evt.status); rc = -EINVAL; } return rc; } static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, void *d, int len) { Loading Loading
drivers/net/wireless/ath/wil6210/main.c +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) break; } sta->status = wil_sta_unused; sta->fst_link_loss = false; } /* reorder buffers */ for (i = 0; i < WIL_STA_TID_NUM; i++) { Loading
drivers/net/wireless/ath/wil6210/sysfs.c +65 −0 Original line number Diff line number Diff line Loading @@ -204,9 +204,74 @@ wil_tt_sysfs_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(thermal_throttling, 0644, wil_tt_sysfs_show, wil_tt_sysfs_store); static ssize_t wil_fst_link_loss_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wil6210_priv *wil = dev_get_drvdata(dev); ssize_t len = 0; int i; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) if (wil->sta[i].status == wil_sta_connected) len += snprintf(buf + len, PAGE_SIZE - len, "[%d] %pM %s\n", i, wil->sta[i].addr, wil->sta[i].fst_link_loss ? "On" : "Off"); return len; } static ssize_t wil_fst_link_loss_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wil6210_priv *wil = dev_get_drvdata(dev); u8 addr[ETH_ALEN]; char *token, *dupbuf, *tmp; int rc = -EINVAL; bool fst_link_loss; tmp = kmemdup(buf, count + 1, GFP_KERNEL); if (!tmp) return -ENOMEM; tmp[count] = '\0'; dupbuf = tmp; token = strsep(&dupbuf, " "); if (!token) goto out; /* mac address */ if (sscanf(token, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) goto out; /* On/Off */ if (strtobool(dupbuf, &fst_link_loss)) goto out; wil_dbg_misc(wil, "set [%pM] with %d\n", addr, fst_link_loss); rc = wmi_link_maintain_cfg_write(wil, addr, fst_link_loss); if (!rc) rc = count; out: kfree(tmp); return rc; } static DEVICE_ATTR(fst_link_loss, 0644, wil_fst_link_loss_sysfs_show, wil_fst_link_loss_sysfs_store); static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_ftm_txrx_offset.attr, &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, NULL }; Loading
drivers/net/wireless/ath/wil6210/wil6210.h +5 −0 Original line number Diff line number Diff line Loading @@ -531,6 +531,7 @@ struct wil_sta_info { struct wil_tid_crypto_rx tid_crypto_rx[WIL_STA_TID_NUM]; struct wil_tid_crypto_rx group_crypto_rx; u8 aid; /* 1-254; 0 if unknown/not reported */ bool fst_link_loss; }; enum { Loading Loading @@ -987,5 +988,9 @@ void wil_ftm_evt_per_dest_res(struct wil6210_priv *wil, void wil_aoa_evt_meas(struct wil6210_priv *wil, struct wmi_aoa_meas_event *evt, int len); /* link loss */ int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss); #endif /* __WIL6210_H__ */
drivers/net/wireless/ath/wil6210/wmi.c +55 −0 Original line number Diff line number Diff line Loading @@ -1847,6 +1847,61 @@ void wmi_event_flush(struct wil6210_priv *wil) spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); } int wmi_link_maintain_cfg_write(struct wil6210_priv *wil, const u8 *addr, bool fst_link_loss) { int rc; int cid = wil_find_cid(wil, addr); u32 cfg_type; struct wmi_link_maintain_cfg_write_cmd cmd; struct { struct wmi_cmd_hdr wmi; struct wmi_link_maintain_cfg_write_done_event evt; } __packed reply; if (cid < 0) return cid; switch (wil->wdev->iftype) { case NL80211_IFTYPE_STATION: cfg_type = fst_link_loss ? WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_STA : WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_STA; break; case NL80211_IFTYPE_AP: cfg_type = fst_link_loss ? WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_AP : WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_AP; break; default: wil_err(wil, "Unsupported for iftype %d", wil->wdev->iftype); return -EINVAL; } wil_dbg_misc(wil, "Setting cid:%d with cfg_type:%d\n", cid, cfg_type); cmd.cfg_type = cpu_to_le32(cfg_type); cmd.cid = cpu_to_le32(cid); reply.evt.status = cpu_to_le32(WMI_FW_STATUS_FAILURE); rc = wmi_call(wil, WMI_LINK_MAINTAIN_CFG_WRITE_CMDID, &cmd, sizeof(cmd), WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID, &reply, sizeof(reply), 250); if (rc) { wil_err(wil, "Failed to %s FST link loss", fst_link_loss ? "enable" : "disable"); } else if (reply.evt.status == WMI_FW_STATUS_SUCCESS) { wil->sta[cid].fst_link_loss = fst_link_loss; } else { wil_err(wil, "WMI_LINK_MAINTAIN_CFG_WRITE_CMDID returned status %d", reply.evt.status); rc = -EINVAL; } return rc; } static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, void *d, int len) { Loading