blob: 18be9d301099f9c9244e9b9813dfd9861853f407 [file] [log] [blame]
developer7f1a58f2022-05-26 16:00:32 -07001diff --git a/mt7915/mcu.c b/mt7915/mcu.c
2index d547cf6..bec0cd0 100755
3--- a/mt7915/mcu.c
4+++ b/mt7915/mcu.c
5@@ -3871,6 +3871,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
6 if (val == 0)
7 dev->dbg.muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
8 break;
9+ case RATE_PARAM_AUTO_HEMU:
10+ if (val < 0 || val > 15) {
11+ printk("Wrong value! The value is between 0-15.\n");
12+ break;
13+ }
14+ dev->dbg.muru_onoff = val;
15+ break;
16 }
17 }
18
19diff --git a/mt7915/mcu.h b/mt7915/mcu.h
20index af939c4..fc382cd 100644
21--- a/mt7915/mcu.h
22+++ b/mt7915/mcu.h
23@@ -431,6 +431,7 @@ enum {
24 #ifdef CONFIG_MTK_VENDOR
25 RATE_PARAM_FIXED_MIMO = 30,
26 RATE_PARAM_FIXED_OFDMA = 31,
27+ RATE_PARAM_AUTO_HEMU = 32,
28 #endif
29 };
30
31diff --git a/mt7915/vendor.c b/mt7915/vendor.c
32index 7456c57..cb5b60f 100644
33--- a/mt7915/vendor.c
34+++ b/mt7915/vendor.c
35@@ -34,6 +34,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
36 [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
37 };
38
39+static const struct nla_policy
40+hemu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_HEMU_CTRL] = {
41+ [MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF] = {.type = NLA_U8 },
42+};
43+
44 static const struct nla_policy
45 rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
46 [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
47@@ -942,6 +947,35 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
48 return 0;
49 }
50
51+static int mt7915_vendor_hemu_ctrl(struct wiphy *wiphy,
52+ struct wireless_dev *wdev,
53+ const void *data,
54+ int data_len)
55+{
56+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
57+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
58+ struct mt7915_dev *dev = phy->dev;
59+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_HEMU_CTRL];
60+ int err;
61+ u8 val8;
62+ u32 val32 = 0;
63+
64+ err = nla_parse(tb, MTK_VENDOR_ATTR_HEMU_CTRL_MAX, data, data_len,
65+ hemu_ctrl_policy, NULL);
66+ if (err)
67+ return err;
68+
69+ if (tb[MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF]) {
70+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF]);
71+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_HEMU) |
72+ FIELD_PREP(RATE_CFG_VAL, val8);
73+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
74+ mt7915_set_wireless_vif, &val32);
75+ }
76+
77+ return 0;
78+}
79+
80 static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
81 {
82 .info = {
83@@ -988,6 +1022,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
84 .doit = mt7915_vendor_wireless_ctrl,
85 .policy = wireless_ctrl_policy,
86 .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
87+ },
88+ {
89+ .info = {
90+ .vendor_id = MTK_NL80211_VENDOR_ID,
91+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL,
92+ },
93+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
94+ WIPHY_VENDOR_CMD_NEED_RUNNING,
95+ .doit = mt7915_vendor_hemu_ctrl,
96+ .policy = hemu_ctrl_policy,
97+ .maxattr = MTK_VENDOR_ATTR_HEMU_CTRL_MAX,
98 }
99 };
100
101diff --git a/mt7915/vendor.h b/mt7915/vendor.h
102index 1b08321..b5c1420 100644
103--- a/mt7915/vendor.h
104+++ b/mt7915/vendor.h
105@@ -8,6 +8,7 @@ enum mtk_nl80211_vendor_subcmds {
106 MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
107 MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
108 MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
109+ MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL = 0xc5,
110 };
111
112 enum mtk_capi_control_changed {
113@@ -33,6 +34,17 @@ enum mtk_vendor_attr_wireless_ctrl {
114 NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
115 };
116
117+enum mtk_vendor_attr_hemu_ctrl {
118+ MTK_VENDOR_ATTR_HEMU_CTRL_UNSPEC,
119+
120+ MTK_VENDOR_ATTR_HEMU_CTRL_ONOFF,
121+
122+ /* keep last */
123+ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL,
124+ MTK_VENDOR_ATTR_HEMU_CTRL_MAX =
125+ NUM_MTK_VENDOR_ATTRS_HEMU_CTRL - 1
126+};
127+
128 enum mtk_vendor_attr_rfeature_ctrl {
129 MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
130