linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
To: linux-wireless@vger.kernel.org
Cc: Tamizh Chelvam <tamizhr@codeaurora.org>,
	Johannes Berg <johannes@sipsolutions.net>,
	Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Subject: [RFC PATCH v2 5/5] iw: add TID specific configuration command
Date: Fri, 24 Apr 2020 14:29:05 +0300	[thread overview]
Message-ID: <20200424112905.26770-6-sergey.matyukevich.os@quantenna.com> (raw)
In-Reply-To: <20200424112905.26770-1-sergey.matyukevich.os@quantenna.com>

Use command NL80211_CMD_SET_TID_CONFIG to perform per-node TID specific
configuration. If peer is not specified, then configuration is applied
to all the peers. Currently kernel supports configuration of the
following parameters:
- short/long retry
- mpdu/msdu aggregation on/off
- rts/cts on/off
- noack on/off

Examples:
Apply configuration for specific peer and TIDs:
$ iw dev wlan0 set tidconf peer 1:2:3:4:5:6 tids 0x3 ampdu off tids 0x2 sretry 10 lretry 100
$ iw dev wlan0 set tidconf peer 1:2:3:4:5:6 tids 0x1 override ampdu off amsdu off

Apply configuration for all peers and all TIDs:
$ iw dev wlan0 set tidconf tids 0xff ampdu off amsdu off sretry 10 lretry 100 noack off

Apply configuration for all peers and specific TIDs:
$ iw dev wlan0 set tidconf peer 0xff:0xff:0xff:0xff:0xff:0xff tids 0x1 ampdu off amsdu off

Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
---
 interface.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 229 insertions(+)

diff --git a/interface.c b/interface.c
index 6a44304..df96bed 100644
--- a/interface.c
+++ b/interface.c
@@ -727,3 +727,232 @@ COMMAND(switch, freq,
 	"Switch the operating channel by sending a channel switch announcement (CSA).");
 COMMAND(switch, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [beacons <count>] [block-tx]",
 	NL80211_CMD_CHANNEL_SWITCH, 0, CIB_NETDEV, handle_chan, NULL);
+
+
+static int toggle_tid_param(const char *argv0, const char *argv1,
+			    struct nl_msg *msg, uint32_t attr)
+{
+	uint8_t val;
+
+	if (strcmp(argv1, "on") == 0) {
+		val = NL80211_TID_CONFIG_ENABLE;
+	} else if (strcmp(argv1, "off") == 0) {
+		val = NL80211_TID_CONFIG_DISABLE;
+	} else {
+		fprintf(stderr, "Invalid %s parameter: %s\n", argv0, argv1);
+		return 2;
+	}
+
+	NLA_PUT_U8(msg, attr, val);
+	return 0;
+
+ nla_put_failure:
+	return -ENOBUFS;
+}
+
+static int handle_tid_config(struct nl80211_state *state,
+			     struct nl_msg *msg,
+			     int argc, char **argv,
+			     enum id_input id)
+{
+	struct nlattr *tids_array = NULL;
+	struct nlattr *tids_entry = NULL;
+	unsigned char peer[ETH_ALEN];
+	int tids_num = 0;
+	char *end;
+	int ret;
+	enum {
+		PS_ADDR,
+		PS_TIDS,
+		PS_CONF,
+	} parse_state = PS_ADDR;
+
+	while (argc) {
+		switch (parse_state) {
+		case PS_ADDR:
+			if (strcmp(argv[0], "peer") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "Not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				if (mac_addr_a2n(peer, argv[1])) {
+					fprintf(stderr, "Invalid MAC address\n");
+					return 2;
+				}
+
+				NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
+
+				argc -= 2;
+				argv += 2;
+				parse_state = PS_TIDS;
+
+			} else if (strcmp(argv[0], "tids") == 0) {
+				parse_state = PS_TIDS;
+			} else {
+				fprintf(stderr, "Peer MAC address expected\n");
+				return HANDLER_RET_USAGE;
+			}
+
+			break;
+		case PS_TIDS:
+			if (strcmp(argv[0], "tids") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				if (!tids_array) {
+					tids_array = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
+					if (!tids_array)
+						return -ENOBUFS;
+				}
+
+				if (tids_entry) {
+					nla_nest_end(msg, tids_entry);
+					tids_num++;
+				}
+
+				tids_entry = nla_nest_start(msg, tids_num);
+				if (!tids_entry)
+					return -ENOBUFS;
+
+				NLA_PUT_U16(msg, NL80211_TID_CONFIG_ATTR_TIDS, strtol(argv[1], &end, 0));
+				if (*end) {
+					fprintf(stderr, "Invalid TID mask value: %s\n", argv[1]);
+					return 2;
+				}
+
+				argc -= 2;
+				argv += 2;
+				parse_state = PS_CONF;
+			} else {
+				fprintf(stderr, "TID mask expected\n");
+				return HANDLER_RET_USAGE;
+			}
+
+			break;
+		case PS_CONF:
+			if (strcmp(argv[0], "tids") == 0) {
+				parse_state = PS_TIDS;
+			} else if (strcmp(argv[0], "override") == 0) {
+				NLA_PUT_FLAG(msg, NL80211_TID_CONFIG_ATTR_OVERRIDE);
+
+				argc -= 1;
+				argv += 1;
+			} else if (strcmp(argv[0], "ampdu") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				ret = toggle_tid_param(argv[0], argv[1], msg,
+						       NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
+				if (ret)
+					return ret;
+
+				argc -= 2;
+				argv += 2;
+			} else if (strcmp(argv[0], "amsdu") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				ret = toggle_tid_param(argv[0], argv[1], msg,
+						       NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
+				if (ret)
+					return ret;
+
+				argc -= 2;
+				argv += 2;
+			} else if (strcmp(argv[0], "noack") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				ret = toggle_tid_param(argv[0], argv[1], msg,
+						       NL80211_TID_CONFIG_ATTR_NOACK);
+				if (ret)
+					return ret;
+
+				argc -= 2;
+				argv += 2;
+			} else if (strcmp(argv[0], "rtscts") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				ret = toggle_tid_param(argv[0], argv[1], msg,
+						       NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
+				if (ret)
+					return ret;
+
+				argc -= 2;
+				argv += 2;
+			} else if (strcmp(argv[0], "sretry") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				NLA_PUT_U8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT, strtol(argv[1], &end, 0));
+				if (*end) {
+					fprintf(stderr, "Invalid short_retry value: %s\n", argv[1]);
+					return 2;
+				}
+
+				argc -= 2;
+				argv += 2;
+			} else if (strcmp(argv[0], "lretry") == 0) {
+				if (argc < 2) {
+					fprintf(stderr, "not enough args for %s\n", argv[0]);
+					return HANDLER_RET_USAGE;
+				}
+
+				NLA_PUT_U8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG, strtol(argv[1], &end, 0));
+				if (*end) {
+					fprintf(stderr, "Invalid long_retry value: %s\n", argv[1]);
+					return 2;
+				}
+
+				argc -= 2;
+				argv += 2;
+			} else {
+				fprintf(stderr, "Unknown parameter: %s\n", argv[0]);
+				return HANDLER_RET_USAGE;
+			}
+
+			break;
+		default:
+			fprintf(stderr, "Failed to parse: internal failure\n");
+			return HANDLER_RET_USAGE;
+		}
+	}
+
+	if (tids_entry)
+		nla_nest_end(msg, tids_entry);
+
+	if (tids_array)
+		nla_nest_end(msg, tids_array);
+
+	return 0;
+
+nla_put_failure:
+	return -ENOBUFS;
+}
+
+COMMAND(set, tidconf, "[peer <MAC address>] tids <mask> [override] [sretry <num>] [lretry <num>] "
+	"[ampdu [on|off]] [amsdu [on|off]] [noack [on|off]] [rtscts [on|off]]",
+	NL80211_CMD_SET_TID_CONFIG, 0, CIB_NETDEV, handle_tid_config,
+	"Setup per-node TID specific configuration for TIDs selected by bitmask.\n"
+	"If MAC address is not specified, then supplied TID configuration\n"
+	"applied to all the peers.\n"
+	"Examples:\n"
+	"  $ iw dev wlan0 tids 0x1 ampdu off\n"
+	"  $ iw dev wlan0 tids 0x5 ampdu off amsdu off rtscts on\n"
+	"  $ iw dev wlan0 tids 0x3 override ampdu on noack on rtscts on\n"
+	"  $ iw dev wlan0 peer xx:xx:xx:xx:xx:xx tids 0x1 ampdu off tids 0x3 amsdu off rtscts on\n"
+	);
-- 
2.11.0


  parent reply	other threads:[~2020-04-24 11:30 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-24 11:29 [RFC PATCH v2 0/5] cfg80211: updates and fixes for TID specific configuration Sergey Matyukevich
2020-04-24 11:29 ` [RFC PATCH v2 1/5] cfg80211: fix mask type in cfg80211_tid_cfg structure Sergey Matyukevich
2020-04-24 11:29 ` [RFC PATCH v2 2/5] mac80211: fix variable names in TID config methods Sergey Matyukevich
2020-04-24 11:29 ` [RFC PATCH v2 3/5] cfg80211: add support for TID specific AMSDU configuration Sergey Matyukevich
2020-04-24 11:29 ` [RFC PATCH v2 4/5] nl80211: simplify peer specific TID configuration Sergey Matyukevich
2020-04-24 11:29 ` Sergey Matyukevich [this message]
2020-04-27 17:48 ` [RFC PATCH v2 0/5] cfg80211: updates and fixes for TID specific configuration tamizhr

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200424112905.26770-6-sergey.matyukevich.os@quantenna.com \
    --to=sergey.matyukevich.os@quantenna.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=tamizhr@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).