Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 105dd0f1 authored by Hamad Kadmany's avatar Hamad Kadmany Committed by Maya Erez
Browse files

wil6210: add sysfs file for enable/disable fst link loss



The new "fst_link_loss" sysfs can be used to enable/disable the fst
link loss behavior for specific connection.

Change-Id: I7afcf86a575ca3add581c8823a3d5567483abcb0
Signed-off-by: default avatarHamad Kadmany <hkadmany@codeaurora.org>
parent 82047212
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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++) {
+65 −0
Original line number Diff line number Diff line
@@ -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
};

+5 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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__ */
+55 −0
Original line number Diff line number Diff line
@@ -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)
{