[][MAC80211][Change MT76 Makefile and add bersa support]

[Description]
Change MT76 Makefile and add bersa support

[Release-log]
N/A

Change-Id: Iecb0e9968c8e212a6ab92698c84d2e3a56dbd65b
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5809192
diff --git a/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tools/main.c b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tools/main.c
new file mode 100644
index 0000000..699a9ee
--- /dev/null
+++ b/autobuild_mac80211_release/mt7986_bersa_mac80211/package/kernel/mt76/src/tools/main.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "mt76-test.h"
+
+struct unl unl;
+static uint32_t tm_changed[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
+static const char *progname;
+
+static int phy_lookup_idx(const char *name)
+{
+	char buf[128];
+	FILE *f;
+	int len;
+
+	snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name);
+	f = fopen(buf, "r");
+	if (!f)
+		return -1;
+
+	len = fread(buf, 1, sizeof(buf) - 1, f);
+	fclose(f);
+
+	if (!len)
+		return -1;
+
+	buf[len] = 0;
+	return atoi(buf);
+}
+
+void usage(void)
+{
+	static const char *const commands[] = {
+		"set <var>=<val> [...]",
+		"dump [stats]",
+		"eeprom file",
+		"eeprom set <addr>=<val> [...]",
+		"eeprom changes",
+		"eeprom reset",
+	};
+	int i;
+
+	fprintf(stderr, "Usage:\n");
+	for (i = 0; i < ARRAY_SIZE(commands); i++)
+		printf("  %s phyX %s\n", progname, commands[i]);
+
+	exit(1);
+}
+
+static int mt76_dump_cb(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *attr;
+
+	attr = unl_find_attr(&unl, msg, NL80211_ATTR_TESTDATA);
+	if (!attr) {
+		fprintf(stderr, "Testdata attribute not found\n");
+		return NL_SKIP;
+	}
+
+	msg_field.print(&msg_field, attr);
+
+	return NL_SKIP;
+}
+
+static int mt76_dump(int phy, int argc, char **argv)
+{
+	struct nl_msg *msg;
+	void *data;
+
+	msg = unl_genl_msg(&unl, NL80211_CMD_TESTMODE, true);
+	nla_put_u32(msg, NL80211_ATTR_WIPHY, phy);
+
+	data = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+
+	for (; argc > 0; argc--, argv++) {
+		if (!strcmp(argv[0], "stats"))
+			nla_put_flag(msg, MT76_TM_ATTR_STATS);
+	}
+
+	nla_nest_end(msg, data);
+
+	unl_genl_request(&unl, msg, mt76_dump_cb, NULL);
+
+	return 0;
+}
+
+static inline void tm_set_changed(uint32_t id)
+{
+	tm_changed[id / 32] |= (1U << (id % 32));
+}
+
+static inline bool tm_is_changed(uint32_t id)
+{
+	return tm_changed[id / 32] & (1U << (id % 32));
+}
+
+static int mt76_set(int phy, int argc, char **argv)
+{
+	const struct tm_field *fields = msg_field.fields;
+	struct nl_msg *msg;
+	void *data;
+	int i, ret;
+
+	if (argc < 1)
+		return 1;
+
+	msg = unl_genl_msg(&unl, NL80211_CMD_TESTMODE, false);
+	nla_put_u32(msg, NL80211_ATTR_WIPHY, phy);
+
+	data = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
+	for (; argc > 0; argc--, argv++) {
+		char *name = argv[0];
+		char *val = strchr(name, '=');
+
+		if (!val) {
+			fprintf(stderr, "Invalid argument: %s\n", name);
+			return 1;
+		}
+
+		*(val++) = 0;
+
+		for (i = 0; i < msg_field.len; i++) {
+			if (!fields[i].parse)
+				continue;
+
+			if (!strcmp(fields[i].name, name))
+				break;
+		}
+
+		if (i == msg_field.len) {
+			fprintf(stderr, "Unknown field: %s\n", name);
+			return 1;
+		}
+
+		if (tm_is_changed(i)) {
+			fprintf(stderr, "Duplicate field '%s'\n", name);
+			return 1;
+		}
+
+		if (!fields[i].parse(&fields[i], i, msg, val))
+			return 1;
+
+		tm_set_changed(i);
+	}
+
+	nla_nest_end(msg, data);
+
+	ret = unl_genl_request(&unl, msg, NULL, NULL);
+	if (ret)
+		fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
+
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	const char *cmd, *phyname;
+	int phy;
+	int ret = 0;
+
+	progname = argv[0];
+	if (argc < 3)
+		usage();
+
+	if (unl_genl_init(&unl, "nl80211") < 0) {
+		fprintf(stderr, "Failed to connect to nl80211\n");
+		return 2;
+	}
+
+	phyname = argv[1];
+	phy = phy_lookup_idx(phyname);
+	if (phy < 0) {
+		fprintf(stderr, "Could not find phy '%s'\n", argv[1]);
+		return 2;
+	}
+
+	cmd = argv[2];
+	argv += 3;
+	argc -= 3;
+
+	if (!strcmp(cmd, "dump"))
+		ret = mt76_dump(phy, argc, argv);
+	else if (!strcmp(cmd, "set"))
+		ret = mt76_set(phy, argc, argv);
+	else if (!strcmp(cmd, "eeprom"))
+		ret = mt76_eeprom(phy, argc, argv);
+	else if (!strcmp(cmd, "fwlog"))
+		ret = mt76_fwlog(phyname, argc, argv);
+	else
+		usage();
+
+	unl_free(&unl);
+
+	return ret;
+}