[][MAC80211][app][add mt76-vendor muru onoff command]
[Description]
Add mt76-vendor muru_onoff command
[Release-log]
N/A
Usage:
mt76-vendor wlanX set hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
bit 0 1 2 3
ru_dl ru_ul mu_dl mu_ul
Change-Id: I59c325cfea1d16b1fc110f2965004769642873b5
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6038795
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1008-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1008-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
new file mode 100755
index 0000000..18be9d3
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1008-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
@@ -0,0 +1,130 @@
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index d547cf6..bec0cd0 100755
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -3871,6 +3871,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ if (val == 0)
+ dev->dbg.muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
+ break;
++ case RATE_PARAM_AUTO_HEMU:
++ if (val < 0 || val > 15) {
++ printk("Wrong value! The value is between 0-15.\n");
++ break;
++ }
++ dev->dbg.muru_onoff = val;
++ break;
+ }
+ }
+
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index af939c4..fc382cd 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -431,6 +431,7 @@ enum {
+ #ifdef CONFIG_MTK_VENDOR
+ RATE_PARAM_FIXED_MIMO = 30,
+ RATE_PARAM_FIXED_OFDMA = 31,
++ RATE_PARAM_AUTO_HEMU = 32,
+ #endif
+ };
+
+diff --git a/mt7915/vendor.c b/mt7915/vendor.c
+index 7456c57..cb5b60f 100644
+--- a/mt7915/vendor.c
++++ b/mt7915/vendor.c
+@@ -34,6 +34,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
+ };
+
++static const struct nla_policy
++hemu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_HEMU_CTRL] = {
++ [MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF] = {.type = NLA_U8 },
++};
++
+ static const struct nla_policy
+ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
+@@ -942,6 +947,35 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+ return 0;
+ }
+
++static int mt7915_vendor_hemu_ctrl(struct wiphy *wiphy,
++ struct wireless_dev *wdev,
++ const void *data,
++ int data_len)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct mt7915_phy *phy = mt7915_hw_phy(hw);
++ struct mt7915_dev *dev = phy->dev;
++ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_HEMU_CTRL];
++ int err;
++ u8 val8;
++ u32 val32 = 0;
++
++ err = nla_parse(tb, MTK_VENDOR_ATTR_HEMU_CTRL_MAX, data, data_len,
++ hemu_ctrl_policy, NULL);
++ if (err)
++ return err;
++
++ if (tb[MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF]) {
++ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF]);
++ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_HEMU) |
++ FIELD_PREP(RATE_CFG_VAL, val8);
++ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
++ mt7915_set_wireless_vif, &val32);
++ }
++
++ return 0;
++}
++
+ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+ {
+ .info = {
+@@ -988,6 +1022,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+ .doit = mt7915_vendor_wireless_ctrl,
+ .policy = wireless_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
++ },
++ {
++ .info = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL,
++ },
++ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++ WIPHY_VENDOR_CMD_NEED_RUNNING,
++ .doit = mt7915_vendor_hemu_ctrl,
++ .policy = hemu_ctrl_policy,
++ .maxattr = MTK_VENDOR_ATTR_HEMU_CTRL_MAX,
+ }
+ };
+
+diff --git a/mt7915/vendor.h b/mt7915/vendor.h
+index 1b08321..b5c1420 100644
+--- a/mt7915/vendor.h
++++ b/mt7915/vendor.h
+@@ -8,6 +8,7 @@ enum mtk_nl80211_vendor_subcmds {
+ MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
+ MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
+ MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
++ MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL = 0xc5,
+ };
+
+ enum mtk_capi_control_changed {
+@@ -33,6 +34,17 @@ enum mtk_vendor_attr_wireless_ctrl {
+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
+ };
+
++enum mtk_vendor_attr_hemu_ctrl {
++ MTK_VENDOR_ATTR_HEMU_CTRL_UNSPEC,
++
++ MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL,
++ MTK_VENDOR_ATTR_HEMU_CTRL_MAX =
++ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL - 1
++};
++
+ enum mtk_vendor_attr_rfeature_ctrl {
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+
diff --git a/feed/mt76-vendor/src/CMakeLists.txt b/feed/mt76-vendor/src/CMakeLists.txt
index db006b7..f5e1d51 100644
--- a/feed/mt76-vendor/src/CMakeLists.txt
+++ b/feed/mt76-vendor/src/CMakeLists.txt
@@ -3,7 +3,7 @@
PROJECT(mt76-vendor C)
ADD_DEFINITIONS(-Os -Wall --std=gnu99 -g3)
-ADD_EXECUTABLE(mt76-vendor main.c csi.c amnt.c capi.c)
+ADD_EXECUTABLE(mt76-vendor main.c csi.c amnt.c capi.c hemu.c)
TARGET_LINK_LIBRARIES(mt76-vendor nl-tiny)
SET(CMAKE_INSTALL_PREFIX /usr)
diff --git a/feed/mt76-vendor/src/hemu.c b/feed/mt76-vendor/src/hemu.c
new file mode 100755
index 0000000..ec1cea0
--- /dev/null
+++ b/feed/mt76-vendor/src/hemu.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 2021 Mediatek Inc. */
+#define _GNU_SOURCE
+
+#include "mt76-vendor.h"
+
+static int mt76_hemu_onoff_set_attr(struct nl_msg *msg, int argc, char **argv)
+{
+ char *val;
+
+ val = strchr(argv[0], '=');
+ if (!val)
+ return -EINVAL;
+
+ *(val++) = 0;
+
+ if (!strncmp(argv[0], "onoff", 5))
+ nla_put_u8(msg, MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF, strtoul(val, NULL, 0));
+
+ return 0;
+}
+
+int mt76_hemu_onoff_set(int idx, int argc, char **argv)
+{
+ struct nl_msg *msg;
+ void *data;
+ int ret;
+
+ if (argc < 1)
+ return 1;
+
+ if (unl_genl_init(&unl, "nl80211") < 0) {
+ fprintf(stderr, "Failed to connect to nl80211\n");
+ return 2;
+ }
+
+ msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
+
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL))
+ return false;
+
+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
+ if (!data)
+ return -ENOMEM;
+
+ mt76_hemu_onoff_set_attr(msg, argc, argv);
+
+ nla_nest_end(msg, data);
+
+ ret = unl_genl_request(&unl, msg, NULL, NULL);
+ if (ret)
+ fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
+
+ unl_free(&unl);
+
+ return ret;
+}
\ No newline at end of file
diff --git a/feed/mt76-vendor/src/main.c b/feed/mt76-vendor/src/main.c
index c95b3f2..64e8b57 100644
--- a/feed/mt76-vendor/src/main.c
+++ b/feed/mt76-vendor/src/main.c
@@ -31,6 +31,8 @@
"set ap_wireless ampdu=<enable>",
"set ap_wireless amsdu=<enable>",
"set ap_wireless cert=<enable>",
+
+ "set hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))",
};
int i;
@@ -75,6 +77,8 @@
ret = mt76_ap_rfeatures_set(if_idx, argc, argv);
else if (!strncmp(subcmd, "ap_wireless", 11))
ret = mt76_ap_wireless_set(if_idx, argc, argv);
+ else if (!strncmp(subcmd, "hemu", 4))
+ ret = mt76_hemu_onoff_set(if_idx, argc, argv);
} else {
usage();
}
diff --git a/feed/mt76-vendor/src/mt76-vendor.h b/feed/mt76-vendor/src/mt76-vendor.h
index 7db01d4..c72a0bb 100644
--- a/feed/mt76-vendor/src/mt76-vendor.h
+++ b/feed/mt76-vendor/src/mt76-vendor.h
@@ -38,6 +38,7 @@
MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
+ MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL = 0xc5,
};
enum mtk_vendor_attr_csi_ctrl {
@@ -145,6 +146,17 @@
NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
};
+enum mtk_vendor_attr_hemu_ctrl {
+ MTK_VENDOR_ATTR_HEMU_CTRL_UNSPEC,
+
+ MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF,
+
+ /* keep last */
+ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL,
+ MTK_VENDOR_ATTR_HEMU_CTRL_MAX =
+ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL - 1
+};
+
enum mtk_vendor_attr_rfeature_ctrl {
MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
@@ -197,4 +209,6 @@
int mt76_ap_rfeatures_set(int idx, int argc, char **argv);
int mt76_ap_wireless_set(int idx, int argc, char **argv);
+
+int mt76_hemu_onoff_set(int idx, int argc, char **argv);
#endif