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

Commit d4b75b56 authored by Alexei Avshalom Lazar's avatar Alexei Avshalom Lazar Committed by Maya Erez
Browse files

wil6210: Add support for setting RBUFCAP configuration



RBUFCAP support added in FW.
The RBUFCAP feature is amendment to the block ack mechanism to
prevent overloading of the recipient’s memory space, which may
happen in case the link speed is higher than STA’s capability
to process or consume incoming data.
The block ack policy (ba_policy) is now controlled by FW so driver
should ignore this field.
Add new debugfs "rbufcap" to configure RBUFCAP.

Change-Id: Id3b83c607c8b4d61926718862cdf4f4931303e38
Signed-off-by: default avatarAlexei Avshalom Lazar <ailizaro@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Git-commit: c5b3a6582b1e9fad0fb0b8658855387c0cbcc576
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git


[merez@codeaurora.org: trivial merge conflicts]
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent d69f27c7
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -810,6 +810,44 @@ static const struct file_operations fops_rxon = {
	.open  = simple_open,
};

static ssize_t wil_write_file_rbufcap(struct file *file,
				      const char __user *buf,
				      size_t count, loff_t *ppos)
{
	struct wil6210_priv *wil = file->private_data;
	int val;
	int rc;

	rc = kstrtoint_from_user(buf, count, 0, &val);
	if (rc) {
		wil_err(wil, "Invalid argument\n");
		return rc;
	}
	/* input value: negative to disable, 0 to use system default,
	 * 1..ring size to set descriptor threshold
	 */
	wil_info(wil, "%s RBUFCAP, descriptors threshold - %d\n",
		 val < 0 ? "Disabling" : "Enabling", val);

	if (!wil->ring_rx.va || val > wil->ring_rx.size) {
		wil_err(wil, "Invalid descriptors threshold, %d\n", val);
		return -EINVAL;
	}

	rc = wmi_rbufcap_cfg(wil, val < 0 ? 0 : 1, val < 0 ? 0 : val);
	if (rc) {
		wil_err(wil, "RBUFCAP config failed: %d\n", rc);
		return rc;
	}

	return count;
}

static const struct file_operations fops_rbufcap = {
	.write = wil_write_file_rbufcap,
	.open  = simple_open,
};

/* block ack control, write:
 * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA
 * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side
@@ -2508,6 +2546,7 @@ static const struct {
	{"tx_latency",	0644,		&fops_tx_latency},
	{"link_stats",	0644,		&fops_link_stats},
	{"link_stats_global",	0644,	&fops_link_stats_global},
	{"rbufcap",	0244,		&fops_rbufcap},
};

static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
+11 −20
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
	u16 agg_timeout = le16_to_cpu(ba_timeout);
	u16 seq_ctrl = le16_to_cpu(ba_seq_ctrl);
	struct wil_sta_info *sta;
	u16 agg_wsize = 0;
	u16 agg_wsize;
	/* bit 0: A-MSDU supported
	 * bit 1: policy (should be 0 for us)
	 * bits 2..5: TID
@@ -317,7 +317,6 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
		test_bit(WMI_FW_CAPABILITY_AMSDU, wil->fw_capabilities) &&
		wil->amsdu_en && (param_set & BIT(0));
	int ba_policy = param_set & BIT(1);
	u16 status = WLAN_STATUS_SUCCESS;
	u16 ssn = seq_ctrl >> 4;
	struct wil_tid_ampdu_rx *r;
	int rc = 0;
@@ -344,27 +343,19 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
		    agg_amsdu ? "+" : "-", !!ba_policy, dialog_token, ssn);

	/* apply policies */
	if (ba_policy) {
		wil_err(wil, "BACK requested unsupported ba_policy == 1\n");
		status = WLAN_STATUS_INVALID_QOS_PARAM;
	}
	if (status == WLAN_STATUS_SUCCESS) {
	if (req_agg_wsize == 0) {
		wil_dbg_misc(wil, "Suggest BACK wsize %d\n",
			     wil->max_agg_wsize);
		agg_wsize = wil->max_agg_wsize;
	} else {
			agg_wsize = min_t(u16,
					  wil->max_agg_wsize, req_agg_wsize);
		}
		agg_wsize = min_t(u16, wil->max_agg_wsize, req_agg_wsize);
	}

	rc = wil->txrx_ops.wmi_addba_rx_resp(wil, mid, cid, tid, dialog_token,
					     status, agg_amsdu, agg_wsize,
					     agg_timeout);
	if (rc || (status != WLAN_STATUS_SUCCESS)) {
		wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc,
			status);
					     WLAN_STATUS_SUCCESS, agg_amsdu,
					     agg_wsize, agg_timeout);
	if (rc) {
		wil_err(wil, "do not apply ba, rc(%d)\n", rc);
		goto out;
	}

+1 −0
Original line number Diff line number Diff line
@@ -1466,6 +1466,7 @@ int wmi_stop_sched_scan(struct wil6210_priv *wil);
int wmi_mgmt_tx(struct wil6210_vif *vif, const u8 *buf, size_t len);
int wmi_mgmt_tx_ext(struct wil6210_vif *vif, const u8 *buf, size_t len,
		    u8 channel, u16 duration_ms);
int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold);

int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch);
int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch);
+37 −2
Original line number Diff line number Diff line
@@ -480,6 +480,8 @@ static const char *cmdid2name(u16 cmdid)
		return "WMI_SET_VR_PROFILE_CMD";
	case WMI_RESET_SPI_SLAVE_CMDID:
		return "WMI_RESET_SPI_SLAVE_CMD";
	case WMI_RBUFCAP_CFG_CMDID:
		return "WMI_RBUFCAP_CFG_CMD";
	default:
		return "Untracked CMD";
	}
@@ -628,6 +630,8 @@ static const char *eventid2name(u16 eventid)
		return "WMI_SET_VR_PROFILE_EVENT";
	case WMI_RESET_SPI_SLAVE_EVENTID:
		return "WMI_RESET_SPI_SLAVE_EVENT";
	case WMI_RBUFCAP_CFG_EVENTID:
		return "WMI_RBUFCAP_CFG_EVENT";
	default:
		return "Untracked EVENT";
	}
@@ -2201,6 +2205,37 @@ int wmi_led_cfg(struct wil6210_priv *wil, bool enable)
	return rc;
}

int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold)
{
	struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
	int rc;

	struct wmi_rbufcap_cfg_cmd cmd = {
		.enable = enable,
		.rx_desc_threshold = cpu_to_le16(threshold),
	};
	struct {
		struct wmi_cmd_hdr wmi;
		struct wmi_rbufcap_cfg_event evt;
	} __packed reply = {
		.evt = {.status = WMI_FW_STATUS_FAILURE},
	};

	rc = wmi_call(wil, WMI_RBUFCAP_CFG_CMDID, vif->mid, &cmd, sizeof(cmd),
		      WMI_RBUFCAP_CFG_EVENTID, &reply, sizeof(reply),
		      WIL_WMI_CALL_GENERAL_TO_MS);
	if (rc)
		return rc;

	if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
		wil_err(wil, "RBUFCAP_CFG failed. status %d\n",
			reply.evt.status);
		rc = -EINVAL;
	}

	return rc;
}

int wmi_pcp_start(struct wil6210_vif *vif,
		  int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go)
{
@@ -2805,7 +2840,7 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil,
		.dialog_token = token,
		.status_code = cpu_to_le16(status),
		/* bit 0: A-MSDU supported
		 * bit 1: policy (should be 0 for us)
		 * bit 1: policy (controlled by FW)
		 * bits 2..5: TID
		 * bits 6..15: buffer size
		 */
@@ -2859,7 +2894,7 @@ int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid,
		.dialog_token = token,
		.status_code = cpu_to_le16(status),
		/* bit 0: A-MSDU supported
		 * bit 1: policy (should be 0 for us)
		 * bit 1: policy (controlled by FW)
		 * bits 2..5: TID
		 * bits 6..15: buffer size
		 */