Example #1
0
/* block ack control, write:
 * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA
 * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side
 * - "del_rx <CID> <TID> <reason>" to trigger DELBA for Rx side
 */
static ssize_t wil_write_back(struct file *file, const char __user *buf,
			      size_t len, loff_t *ppos)
{
	struct wil6210_priv *wil = file->private_data;
	int rc;
	char *kbuf = kmalloc(len + 1, GFP_KERNEL);
	char cmd[9];
	int p1, p2, p3;

	if (!kbuf)
		return -ENOMEM;

	rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
	if (rc != len) {
		kfree(kbuf);
		return rc >= 0 ? -EIO : rc;
	}

	kbuf[len] = '\0';
	rc = sscanf(kbuf, "%8s %d %d %d", cmd, &p1, &p2, &p3);
	kfree(kbuf);

	if (rc < 0)
		return rc;
	if (rc < 2)
		return -EINVAL;

	if (0 == strcmp(cmd, "add")) {
		if (rc < 3) {
			wil_err(wil, "BACK: add require at least 2 params\n");
			return -EINVAL;
		}
		if (rc < 4)
			p3 = 0;
		wmi_addba(wil, p1, p2, p3);
	} else if (0 == strcmp(cmd, "del_tx")) {
		if (rc < 3)
			p2 = WLAN_REASON_QSTA_LEAVE_QBSS;
		wmi_delba_tx(wil, p1, p2);
	} else if (0 == strcmp(cmd, "del_rx")) {
		if (rc < 3) {
			wil_err(wil,
				"BACK: del_rx require at least 2 params\n");
			return -EINVAL;
		}
		if (rc < 4)
			p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
		wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3);
	} else {
		wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
		return -EINVAL;
	}

	return len;
}
Example #2
0
/* block ack control, write:
 * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA
 * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side
 * - "del_rx <CID> <TID> <reason>" to trigger DELBA for Rx side
 */
static ssize_t wil_write_back(struct file *file, const char __user *buf,
			      size_t len, loff_t *ppos)
{
	struct wil6210_priv *wil = file->private_data;
	int rc;
	char *kbuf = kmalloc(len + 1, GFP_KERNEL);
	char cmd[9];
	int p1, p2, p3;

	if (!kbuf)
		return -ENOMEM;

	rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
	if (rc != len) {
		kfree(kbuf);
		return rc >= 0 ? -EIO : rc;
	}

	kbuf[len] = '\0';
	rc = sscanf(kbuf, "%8s %d %d %d", cmd, &p1, &p2, &p3);
	kfree(kbuf);

	if (rc < 0)
		return rc;
	if (rc < 2)
		return -EINVAL;

	if ((strcmp(cmd, "add") == 0) ||
	    (strcmp(cmd, "del_tx") == 0)) {
		struct vring_tx_data *txdata;

		if (p1 < 0 || p1 >= WIL6210_MAX_TX_RINGS) {
			wil_err(wil, "BACK: invalid ring id %d\n", p1);
			return -EINVAL;
		}
		txdata = &wil->vring_tx_data[p1];
		if (strcmp(cmd, "add") == 0) {
			if (rc < 3) {
				wil_err(wil, "BACK: add require at least 2 params\n");
				return -EINVAL;
			}
			if (rc < 4)
				p3 = 0;
			wmi_addba(wil, txdata->mid, p1, p2, p3);
		} else {
			if (rc < 3)
				p2 = WLAN_REASON_QSTA_LEAVE_QBSS;
			wmi_delba_tx(wil, txdata->mid, p1, p2);
		}
	} else if (strcmp(cmd, "del_rx") == 0) {
		struct wil_sta_info *sta;

		if (rc < 3) {
			wil_err(wil,
				"BACK: del_rx require at least 2 params\n");
			return -EINVAL;
		}
		if (p1 < 0 || p1 >= WIL6210_MAX_CID) {
			wil_err(wil, "BACK: invalid CID %d\n", p1);
			return -EINVAL;
		}
		if (rc < 4)
			p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
		sta = &wil->sta[p1];
		wmi_delba_rx(wil, sta->mid, mk_cidxtid(p1, p2), p3);
	} else {
		wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
		return -EINVAL;
	}

	return len;
}