diff --git a/Makefile b/Makefile
index 33aaf6a..ecb5df8 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ OBJS = iw.o genl.o event.o info.o phy.o \
 	reason.o status.o connect.o link.o offch.o ps.o cqm.o \
 	bitrate.o wowlan.o coalesce.o roc.o p2p.o vendor.o mgmt.o \
 	ap.o sha256.o nan.o bloom.o \
-	measurements.o ftm.o
+	measurements.o ftm.o tid_config.o
 OBJS += sections.o
 
 OBJS-$(HWSIM) += hwsim.o
diff --git a/bitrate.c b/bitrate.c
index 4a026a4..e287b13 100644
--- a/bitrate.c
+++ b/bitrate.c
@@ -76,10 +76,9 @@ static int setup_vht(struct nl80211_txrate_vht *txrate_vht,
 
 #define VHT_ARGC_MAX	100
 
-static int handle_bitrates(struct nl80211_state *state,
-			   struct nl_msg *msg,
-			   int argc, char **argv,
-			   enum id_input id)
+int set_bitrates(struct nl_msg *msg,
+		 int argc, char **argv,
+		 int arg_idx, enum nl80211_attrs attr)
 {
 	struct nlattr *nl_rates, *nl_band;
 	int i;
@@ -110,7 +109,7 @@ static int handle_bitrates(struct nl80211_state *state,
 		S_GI,
 	} parser_state = S_NONE;
 
-	for (i = 0; i < argc; i++) {
+	for (i = arg_idx; i < argc; i++) {
 		char *end;
 		double tmpd;
 		long tmpl;
@@ -195,10 +194,14 @@ static int handle_bitrates(struct nl80211_state *state,
 		case S_GI:
 			break;
 		default:
+			if (attr != NL80211_ATTR_TX_RATES)
+				goto next;
+
 			return 1;
 		}
 	}
 
+next:
 	if (have_vht_mcs_24)
 		if(!setup_vht(&txrate_vht_24, vht_argc_24, vht_argv_24))
 			return -EINVAL;
@@ -213,7 +216,7 @@ static int handle_bitrates(struct nl80211_state *state,
 	if (sgi_24 && lgi_24)
 		return 1;
 
-	nl_rates = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
+	nl_rates = nla_nest_start(msg, attr);
 	if (!nl_rates)
 		goto nla_put_failure;
 
@@ -253,11 +256,34 @@ static int handle_bitrates(struct nl80211_state *state,
 
 	nla_nest_end(msg, nl_rates);
 
-	return 0;
+	return i;
  nla_put_failure:
 	return -ENOBUFS;
 }
 
+static int handle_bitrates(struct nl80211_state *state,
+			   struct nl_msg *msg,
+			   int argc, char **argv,
+			   enum id_input id)
+{
+	int ret;
+	struct nl_msg *rate;
+
+	rate = nlmsg_alloc();
+	if (!rate) {
+		ret = -ENOMEM;
+		goto nla_put_failure;
+	}
+
+	ret = set_bitrates(rate, argc, argv, 0, NL80211_ATTR_TX_RATES);
+	if (ret < argc)
+		return 1;
+
+	return 0;
+nla_put_failure:
+	return -ENOBUFS;
+}
+
 #define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]"
 #define DESCR DESCR_LEGACY " [ht-mcs-<2.4|5> <MCS index>*] [vht-mcs-<2.4|5> <NSS:MCSx,MCSy... | NSS:MCSx-MCSy>*] [sgi-2.4|lgi-2.4] [sgi-5|lgi-5]"
 
diff --git a/iw.h b/iw.h
index 16ff076..274f02c 100644
--- a/iw.h
+++ b/iw.h
@@ -242,4 +242,7 @@ void nan_bf(uint8_t idx, uint8_t *bf, uint16_t bf_len, const uint8_t *buf,
 
 char *hex2bin(const char *hex, char *buf);
 
+int set_bitrates(struct nl_msg *msg, int argc, char **argv, int arg_idx,
+		 enum nl80211_attrs attr);
+
 #endif /* __IW_H */
diff --git a/tid_config.c b/tid_config.c
new file mode 100644
index 0000000..4b225c6
--- /dev/null
+++ b/tid_config.c
@@ -0,0 +1,230 @@
+#include <errno.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+static int handle_tid_config(struct nl80211_state *state,
+			     struct nl_msg *msg,
+			     int argc, char **argv,
+			     enum id_input id)
+{
+	struct nl_msg *tid;
+	struct nlattr *nl_tid;
+	unsigned char mac_addr[ETH_ALEN];
+	bool have_retry = false, have_ampdu = false;
+	bool have_noack = false, have_rtscts = false, have_bitrate = false;
+	int retry_short = -1, retry_long = -1;
+	bool nest_start = true;
+	uint8_t ampdu = 0, rtscts = 0, noack = 0;
+	enum nl80211_tx_rate_setting type = 0;
+	int tid_no = -1, i = 0;
+	char *end;
+	int ret = -ENOSPC;
+
+	if (argc < 4)
+		return 1;
+
+	tid = nlmsg_alloc();
+	if (!tid)
+		return -ENOMEM;
+
+	while (argc) {
+		if (strcmp(argv[0], "tid") == 0) {
+			if (argc < 2)
+				return 1;
+
+			tid_no = strtoul(argv[1], &end, 16);
+			if (*end)
+				return 1;
+
+			goto next;
+		} else if (strcmp(argv[0], "peer") == 0) {
+			if (argc < 2)
+				return 1;
+
+			if (mac_addr_a2n(mac_addr, argv[1])) {
+				fprintf(stderr, "invalid mac address\n");
+				return 2;
+			}
+
+			NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+			goto next;
+		} else if (strcmp(argv[0], "retry_count") == 0) {
+			have_retry = true;
+			argv++;
+			argc--;
+			if (argc) {
+				if (strcmp(argv[0], "short") == 0) {
+					if (argc < 2)
+						return 1;
+
+					retry_short = strtoul(argv[1], &end, 0);
+					if (*end)
+						return 1;
+					argv += 2;
+					argc -= 2;
+				}
+				if (argc && strcmp(argv[0], "long") == 0) {
+					if (argc < 2)
+						return 1;
+					retry_long = strtoul(argv[1], &end, 0);
+					if (*end)
+						return 1;
+				}
+			}
+		} else if (strcmp(argv[0], "rtscts") == 0) {
+			have_rtscts = true;
+			if (argc < 2) {
+				argc--;
+				argv++;
+				rtscts = NL80211_TID_CONFIG_DEFAULT;
+			} else {
+				if (strcmp(argv[1], "enable") == 0)
+					rtscts = NL80211_TID_CONFIG_ENABLE;
+				else if (strcmp(argv[1], "disable") == 0)
+					rtscts = NL80211_TID_CONFIG_DISABLE;
+				else
+					rtscts = NL80211_TID_CONFIG_DEFAULT;
+			}
+		} else if (strcmp(argv[0], "ampdu") == 0) {
+			have_ampdu = true;
+			if (argc < 2) {
+				argc--;
+				argv++;
+				ampdu = NL80211_TID_CONFIG_DEFAULT;
+			} else {
+				if (strcmp(argv[1], "enable") == 0)
+					ampdu = NL80211_TID_CONFIG_ENABLE;
+				else if (strcmp(argv[1], "disable") == 0)
+					ampdu = NL80211_TID_CONFIG_DISABLE;
+				else
+					ampdu = NL80211_TID_CONFIG_DEFAULT;
+			}
+		} else if (strcmp(argv[0], "noack") == 0) {
+			have_noack = true;
+			if (argc < 2) {
+				argc--;
+				argv++;
+				noack = NL80211_TID_CONFIG_DEFAULT;
+			} else {
+				if (strcmp(argv[1], "enable") == 0)
+					noack = NL80211_TID_CONFIG_ENABLE;
+				else if (strcmp(argv[1], "disable") == 0)
+					noack = NL80211_TID_CONFIG_DISABLE;
+				else
+					noack = NL80211_TID_CONFIG_DEFAULT;
+			}
+		} else if (strcmp(argv[0], "bitrates") == 0) {
+			have_bitrate = true;
+			if (argc < 2)
+				return 1;
+			if (!strcmp(argv[1], "auto"))
+				type = NL80211_TX_RATE_AUTOMATIC;
+			else if (!strcmp(argv[1], "fixed"))
+				type = NL80211_TX_RATE_FIXED;
+			else if (!strcmp(argv[1], "limit"))
+				type = NL80211_TX_RATE_LIMITED;
+			else {
+				printf("Invalid parameter: %s\n", argv[i]);
+				return 2;
+			}
+			argc -= 2;
+			argv += 2;
+		} else {
+			return 1;
+		}
+
+		if (tid_no == -1)
+			return 1;
+		if (have_retry || have_rtscts || have_bitrate || have_ampdu ||
+		    have_noack) {
+			nl_tid = nla_nest_start(tid, i);
+			if (!nl_tid) {
+				ret = -ENOBUFS;
+				goto nla_put_failure;
+			}
+			nest_start = true;
+			NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_TID, tid_no);
+		} else {
+			goto next;
+		}
+
+		if (have_retry) {
+			NLA_PUT_FLAG(tid, NL80211_ATTR_TID_CONFIG_RETRY);
+			if (retry_short != -1) {
+				NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_RETRY_SHORT,
+					   retry_short);
+			}
+			if (retry_long != -1) {
+				NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_RETRY_LONG,
+					   retry_long);
+			}
+
+			retry_short = retry_long = -1;
+			have_retry = false;
+		}
+
+		if (have_rtscts) {
+			NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_RTSCTS_CTRL,
+				   rtscts);
+			rtscts = 0;
+			have_rtscts = false;
+		}
+
+		if (have_ampdu) {
+			NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_AMPDU_CTRL,
+				   ampdu);
+			ampdu = 0;
+			have_ampdu = false;
+		}
+
+		if (have_noack) {
+			NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_NOACK, noack);
+			noack = 0;
+			have_noack = false;
+		}
+
+		if (have_bitrate) {
+			NLA_PUT_U8(tid, NL80211_ATTR_TID_CONFIG_TX_RATES_TYPE, type);
+			if (type != NL80211_TX_RATE_AUTOMATIC) {
+				ret = set_bitrates(tid, argc, argv, 0,
+						   NL80211_ATTR_TID_CONFIG_TX_RATES);
+				if (ret < 2)
+					return 1;
+
+				argc -= (ret - 2);
+				argv += (ret - 2);
+			}
+			have_bitrate = false;
+			type = 0;
+		}
+
+		if (nest_start) {
+			nla_nest_end(tid, nl_tid);
+			nest_start = false;
+		}
+next:
+		if (argc) {
+			argc -= 2;
+			argv += 2;
+		}
+	}
+
+	nla_put_nested(msg, NL80211_ATTR_TID_CONFIG, tid);
+
+	ret = 0;
+
+nla_put_failure:
+	return ret;
+}
+COMMAND(set, tid_config, "tid <tid> [peer <MAC address>] [<retry_count> short <limit> long <limit>] [rtscts enable|disable] [ampdu enable|disable] [noack enable|disable] bitrates <[auto] [fixed] [limited]> [peer <addr>] [legacy-<2.4|5> <legacy rate in Mbps>*] [ht-mcs-<2.4|5> <MCS index>] [vht-mcs-<2.4|5> <NSS:MCSx]",
+	NL80211_CMD_SET_TID_CONFIG, 0, CIB_NETDEV, handle_tid_config,
+	"Set the retry count for the TIDs ");
