#include <stdbool.h>
#include <errno.h>
#include <strings.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.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"

struct channels_ctx {
	int last_band;
	bool width_40;
	bool width_80;
	bool width_160;
};

static char *dfs_state_name(enum nl80211_dfs_state state)
{
	switch (state) {
	case NL80211_DFS_USABLE:
		return "usable";
	case NL80211_DFS_AVAILABLE:
		return "available";
	case NL80211_DFS_UNAVAILABLE:
		return "unavailable";
	default:
		return "unknown";
	}
}

static int print_channels_handler(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct channels_ctx *ctx = arg;
	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
	struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
	struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
	struct nlattr *nl_band;
	struct nlattr *nl_freq;
	int rem_band, rem_freq;

	nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);

	if (tb_msg[NL80211_ATTR_WIPHY_BANDS]) {
		nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
			if (ctx->last_band != nl_band->nla_type) {
				printf("Band %d:\n", nl_band->nla_type + 1);
				ctx->width_40 = false;
				ctx->width_80 = false;
				ctx->width_160 = false;
				ctx->last_band = nl_band->nla_type;
			}

			nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), nla_len(nl_band), NULL);

			if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
				__u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]);

				if (cap & BIT(1))
					ctx->width_40 = true;
			}

			if (tb_band[NL80211_BAND_ATTR_VHT_CAPA]) {
				__u32 capa;

				ctx->width_80 = true;

				capa = nla_get_u32(tb_band[NL80211_BAND_ATTR_VHT_CAPA]);
				switch ((capa >> 2) & 3) {
				case 2:
					/* width_80p80 = true; */
					/* fall through */
				case 1:
					ctx->width_160 = true;
				break;
				}
			}

			if (tb_band[NL80211_BAND_ATTR_FREQS]) {
				nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
					uint32_t freq;

					nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq), nla_len(nl_freq), NULL);

					if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
						continue;
					freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
					printf("\t* %d MHz [%d] ", freq, ieee80211_frequency_to_channel(freq));

					if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) {
						printf("(disabled)\n");
						continue;
					}
					printf("\n");

					if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])
						printf("\t  Maximum TX power: %.1f dBm\n", 0.01 * nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]));

					/* If both flags are set assume an new kernel */
					if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR] && tb_freq[__NL80211_FREQUENCY_ATTR_NO_IBSS]) {
						printf("\t  No IR\n");
					} else if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) {
						printf("\t  Passive scan\n");
					} else if (tb_freq[__NL80211_FREQUENCY_ATTR_NO_IBSS]){
						printf("\t  No IBSS\n");
					}

					if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
						printf("\t  Radar detection\n");

					printf("\t  Channel widths:");
					if (!tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
						printf(" 20MHz");
					if (ctx->width_40 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
						printf(" HT40-");
					if (ctx->width_40 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
						printf(" HT40+");
					if (ctx->width_80 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
						printf(" VHT80");
					if (ctx->width_160 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
						printf(" VHT160");
					printf("\n");

					if (!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED] && tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
						enum nl80211_dfs_state state = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
						unsigned long time;

						printf("\t  DFS state: %s", dfs_state_name(state));
						if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]) {
							time = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]);
							printf(" (for %lu sec)", time / 1000);
						}
						printf("\n");
						if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME])
							printf("\t  DFS CAC time: %u ms\n",
							       nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]));
					}
				}
			}
		}
	}

	return NL_SKIP;
}

static int handle_channels(struct nl80211_state *state, struct nl_msg *msg,
			   int argc, char **argv, enum id_input id)
{
	static struct channels_ctx ctx = {
		.last_band = -1,
	};

	nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
	nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP;

	register_handler(print_channels_handler, &ctx);

	return 0;
}
TOPLEVEL(channels, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_channels, "Show available channels.");

static int handle_name(struct nl80211_state *state,
		       struct nl_msg *msg,
		       int argc, char **argv,
		       enum id_input id)
{
	if (argc != 1)
		return 1;

	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, *argv);

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name,
	"Rename this wireless device.");

static int handle_freq(struct nl80211_state *state, struct nl_msg *msg,
		       int argc, char **argv,
		       enum id_input id)
{
	struct chandef chandef;
	int res;

	res = parse_freqchan(&chandef, false, argc, argv, NULL);
	if (res)
		return res;

	return put_chandef(msg, &chandef);
}

COMMAND(set, freq,
	"<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	"<control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq,
	"Set frequency/channel the hardware is using, including HT\n"
	"configuration.");
COMMAND(set, freq,
	"<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	"<control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
	NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL);

static int handle_chan(struct nl80211_state *state, struct nl_msg *msg,
		       int argc, char **argv,
		       enum id_input id)
{
	struct chandef chandef;
	int res;

	res = parse_freqchan(&chandef, true, argc, argv, NULL);
	if (res)
		return res;

	return put_chandef(msg, &chandef);
}
COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan, NULL);
COMMAND(set, channel, "<channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]",
	NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL);


struct cac_event {
	int ret;
	uint32_t freq;
};

static int print_cac_event(struct nl_msg *msg, void *arg)
{
	struct nlattr *tb[NL80211_ATTR_MAX + 1];
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	enum nl80211_radar_event event_type;
	struct cac_event *cac_event = arg;
	uint32_t freq;

	if (gnlh->cmd != NL80211_CMD_RADAR_DETECT)
		return NL_SKIP;

	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);

	if (!tb[NL80211_ATTR_RADAR_EVENT] || !tb[NL80211_ATTR_WIPHY_FREQ])
		return NL_SKIP;

	freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
	event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
	if (freq != cac_event->freq)
		return NL_SKIP;

	switch (event_type) {
	case NL80211_RADAR_DETECTED:
		printf("%d MHz: radar detected\n", freq);
		break;
	case NL80211_RADAR_CAC_FINISHED:
		printf("%d MHz: CAC finished\n", freq);
		break;
	case NL80211_RADAR_CAC_ABORTED:
		printf("%d MHz: CAC was aborted\n", freq);
		break;
	case NL80211_RADAR_NOP_FINISHED:
		printf("%d MHz: NOP finished\n", freq);
		break;
	default:
		printf("%d MHz: unknown radar event\n", freq);
	}
	cac_event->ret = 0;

	return NL_SKIP;
}

static int handle_cac_trigger(struct nl80211_state *state,
			    struct nl_msg *msg,
			    int argc, char **argv,
			    enum id_input id)
{
	struct chandef chandef;
	int res;

	if (argc < 2)
		return 1;

	if (strcmp(argv[0], "channel") == 0) {
		res = parse_freqchan(&chandef, true, argc - 1, argv + 1, NULL);
	} else if (strcmp(argv[0], "freq") == 0) {
		res = parse_freqchan(&chandef, false, argc - 1, argv + 1, NULL);
	} else {
		return 1;
	}

	if (res)
		return res;

	return put_chandef(msg, &chandef);
}

static int no_seq_check(struct nl_msg *msg, void *arg)
{
	return NL_OK;
}

static int handle_cac(struct nl80211_state *state,
		      struct nl_msg *msg,
		      int argc, char **argv,
		      enum id_input id)
{
	int err;
	struct nl_cb *radar_cb;
	struct chandef chandef;
	struct cac_event cac_event;
	char **cac_trigger_argv = NULL;

	radar_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!radar_cb)
		return 1;

	if (argc < 3)
		return 1;

	if (strcmp(argv[2], "channel") == 0) {
		err = parse_freqchan(&chandef, true, argc - 3, argv + 3, NULL);
	} else if (strcmp(argv[2], "freq") == 0) {
		err = parse_freqchan(&chandef, false, argc - 3, argv + 3, NULL);
	} else {
		return 1;
	}

	cac_trigger_argv = calloc(argc + 1, sizeof(char*));
	if (!cac_trigger_argv)
		return -ENOMEM;

	cac_trigger_argv[0] = argv[0];
	cac_trigger_argv[1] = "cac";
	cac_trigger_argv[2] = "trigger";
	memcpy(&cac_trigger_argv[3], &argv[2], (argc - 2) * sizeof(char*));

	err = handle_cmd(state, id, argc + 1, cac_trigger_argv);
	free(cac_trigger_argv);
	if (err)
		return err;

	cac_event.ret = 1;
	cac_event.freq = chandef.control_freq;

	__prepare_listen_events(state);
	nl_socket_set_cb(state->nl_sock, radar_cb);

	/* need to turn off sequence number checking */
	nl_cb_set(radar_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
	nl_cb_set(radar_cb, NL_CB_VALID, NL_CB_CUSTOM, print_cac_event, &cac_event);
	while (cac_event.ret > 0)
		nl_recvmsgs(state->nl_sock, radar_cb);

	return 0;
}
TOPLEVEL(cac, "channel <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	      "freq <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	      "freq <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
	 0, 0, CIB_NETDEV, handle_cac, NULL);
COMMAND(cac, trigger,
	"channel <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	"freq <frequency> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
	"freq <frequency> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
	NL80211_CMD_RADAR_DETECT, 0, CIB_NETDEV, handle_cac_trigger,
	"Start or trigger a channel availability check (CAC) looking to look for\n"
	"radars on the given channel.");

static int handle_fragmentation(struct nl80211_state *state,
				struct nl_msg *msg,
				int argc, char **argv,
				enum id_input id)
{
	unsigned int frag;

	if (argc != 1)
		return 1;

	if (strcmp("off", argv[0]) == 0)
		frag = -1;
	else {
		char *end;

		if (!*argv[0])
			return 1;
		frag = strtoul(argv[0], &end, 10);
		if (*end != '\0')
			return 1;
	}

	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, frag);

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, frag, "<fragmentation threshold|off>",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_fragmentation,
	"Set fragmentation threshold.");

static int handle_rts(struct nl80211_state *state,
		      struct nl_msg *msg,
		      int argc, char **argv,
		      enum id_input id)
{
	unsigned int rts;

	if (argc != 1)
		return 1;

	if (strcmp("off", argv[0]) == 0)
		rts = -1;
	else {
		char *end;

		if (!*argv[0])
			return 1;
		rts = strtoul(argv[0], &end, 10);
		if (*end != '\0')
			return 1;
	}

	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, rts);

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, rts, "<rts threshold|off>",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_rts,
	"Set rts threshold.");

static int handle_retry(struct nl80211_state *state,
			struct nl_msg *msg,
			int argc, char **argv, enum id_input id)
{
	unsigned int retry_short = 0, retry_long = 0;
	bool have_retry_s = false, have_retry_l = false;
	int i;
	enum {
		S_NONE,
		S_SHORT,
		S_LONG,
	} parser_state = S_NONE;

	if (!argc || (argc != 2 && argc != 4))
		return 1;

	for (i = 0; i < argc; i++) {
		char *end;
		unsigned int tmpul;

		if (strcmp(argv[i], "short") == 0) {
			if (have_retry_s)
				return 1;
			parser_state = S_SHORT;
			have_retry_s = true;
		} else if (strcmp(argv[i], "long") == 0) {
			if (have_retry_l)
				return 1;
			parser_state = S_LONG;
			have_retry_l = true;
		} else {
			tmpul = strtoul(argv[i], &end, 10);
			if (*end != '\0')
				return 1;
			if (!tmpul || tmpul > 255)
				return -EINVAL;
			switch (parser_state) {
			case S_SHORT:
				retry_short = tmpul;
				break;
			case S_LONG:
				retry_long = tmpul;
				break;
			default:
				return 1;
			}
		}
	}

	if (!have_retry_s && !have_retry_l)
		return 1;
	if (have_retry_s)
		NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, retry_short);
	if (have_retry_l)
		NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, retry_long);

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, retry, "[short <limit>] [long <limit>]",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_retry,
	"Set retry limit.");

#ifndef NETNS_RUN_DIR
#define NETNS_RUN_DIR "/var/run/netns"
#endif
static int netns_get_fd(const char *name)
{
	char pathbuf[MAXPATHLEN];
	const char *path, *ptr;

	path = name;
	ptr = strchr(name, '/');
	if (!ptr) {
		snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
			NETNS_RUN_DIR, name );
		path = pathbuf;
	}
	return open(path, O_RDONLY);
}

static int handle_netns(struct nl80211_state *state,
			struct nl_msg *msg,
			int argc, char **argv,
			enum id_input id)
{
	char *end;
	int fd;

	if (argc < 1 || !*argv[0])
		return 1;

	if (argc == 1) {
		NLA_PUT_U32(msg, NL80211_ATTR_PID,
				strtoul(argv[0], &end, 10));
		if (*end != '\0') {
			printf("Invalid parameter: pid(%s)\n", argv[0]);
			return 1;
		}
		return 0;
	}

	if (argc != 2 || strcmp(argv[0], "name"))
		return 1;

	if ((fd = netns_get_fd(argv[1])) >= 0) {
		NLA_PUT_U32(msg, NL80211_ATTR_NETNS_FD, fd);
		return 0;
	} else {
		printf("Invalid parameter: nsname(%s)\n", argv[0]);
	}

	return 1;

 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, netns, "{ <pid> | name <nsname> }",
	NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns,
	"Put this wireless device into a different network namespace:\n"
	"    <pid>    - change network namespace by process id\n"
	"    <nsname> - change network namespace by name from "NETNS_RUN_DIR"\n"
	"               or by absolute path (man ip-netns)\n");

static int handle_coverage(struct nl80211_state *state,
			struct nl_msg *msg,
			int argc, char **argv,
			enum id_input id)
{
	char *end;
	unsigned int coverage;

	if (argc != 1)
		return 1;

	if (!*argv[0])
		return 1;
	coverage = strtoul(argv[0], &end, 10);
	if (coverage > 255)
		return 1;

	if (*end)
		return 1;

	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage);

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, coverage, "<coverage class>",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_coverage,
	"Set coverage class (1 for every 3 usec of air propagation time).\n"
	"Valid values: 0 - 255.");

static int handle_distance(struct nl80211_state *state,
			struct nl_msg *msg,
			int argc, char **argv,
			enum id_input id)
{
	if (argc != 1)
		return 1;

	if (!*argv[0])
		return 1;

	if (strcmp("auto", argv[0]) == 0) {
		NLA_PUT_FLAG(msg, NL80211_ATTR_WIPHY_DYN_ACK);
	} else {
		char *end;
		unsigned int distance, coverage;

		distance = strtoul(argv[0], &end, 10);

		if (*end)
			return 1;

		/*
		 * Divide double the distance by the speed of light
		 * in m/usec (300) to get round-trip time in microseconds
		 * and then divide the result by three to get coverage class
		 * as specified in IEEE 802.11-2007 table 7-27.
		 * Values are rounded upwards.
		 */
		coverage = (distance + 449) / 450;
		if (coverage > 255)
			return 1;

		NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage);
	}

	return 0;
 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, distance, "<auto|distance>",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_distance,
	"Enable ACK timeout estimation algorithm (dynack) or set appropriate\n"
	"coverage class for given link distance in meters.\n"
	"To disable dynack set valid value for coverage class.\n"
	"Valid values: 0 - 114750");

static int handle_txpower(struct nl80211_state *state,
			  struct nl_msg *msg,
			  int argc, char **argv,
			  enum id_input id)
{
	enum nl80211_tx_power_setting type;
	int mbm;

	/* get the required args */
	if (argc != 1 && argc != 2)
		return 1;

	if (!strcmp(argv[0], "auto"))
		type = NL80211_TX_POWER_AUTOMATIC;
	else if (!strcmp(argv[0], "fixed"))
		type = NL80211_TX_POWER_FIXED;
	else if (!strcmp(argv[0], "limit"))
		type = NL80211_TX_POWER_LIMITED;
	else {
		printf("Invalid parameter: %s\n", argv[0]);
		return 2;
	}

	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, type);

	if (type != NL80211_TX_POWER_AUTOMATIC) {
		char *endptr;
		if (argc != 2) {
			printf("Missing TX power level argument.\n");
			return 2;
		}

		mbm = strtol(argv[1], &endptr, 10);
		if (*endptr)
			return 2;
		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm);
	} else if (argc != 1)
		return 1;

	return 0;

 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_txpower,
	"Specify transmit power level and setting type.");
COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
	NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower,
	"Specify transmit power level and setting type.");

static int handle_antenna(struct nl80211_state *state,
			  struct nl_msg *msg,
			  int argc, char **argv,
			  enum id_input id)
{
	char *end;
	uint32_t tx_ant = 0, rx_ant = 0;

	if (argc == 1 && strcmp(argv[0], "all") == 0) {
		tx_ant = 0xffffffff;
		rx_ant = 0xffffffff;
	} else if (argc == 1) {
		tx_ant = rx_ant = strtoul(argv[0], &end, 0);
		if (*end)
			return 1;
	}
	else if (argc == 2) {
		tx_ant = strtoul(argv[0], &end, 0);
		if (*end)
			return 1;
		rx_ant = strtoul(argv[1], &end, 0);
		if (*end)
			return 1;
	} else
		return 1;

	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);

	return 0;

 nla_put_failure:
	return -ENOBUFS;
}
COMMAND(set, antenna, "<bitmap> | all | <tx bitmap> <rx bitmap>",
	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna,
	"Set a bitmap of allowed antennas to use for TX and RX.\n"
	"The driver may reject antenna configurations it cannot support.");
