blob: efdd1d094855c6afa7b50e9b57cfab0863702edf [file] [log] [blame]
developer5f18e6c2021-07-28 11:55:08 +08001/* Copyright (C) 2021 Mediatek Inc. */
2#define _GNU_SOURCE
3
4#include "mt76-vendor.h"
5
6static int mt76_ap_rfeatures_set_attr(struct nl_msg *msg, int argc, char **argv)
7{
developer13aaa772021-09-27 18:09:26 +08008 char *val,*s1,*cur;
9 void *data;
10 int idx = MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN;
developer5f18e6c2021-07-28 11:55:08 +080011
12 val = strchr(argv[0], '=');
developer6f8cffd2021-09-29 19:48:25 +080013 if (!val)
14 return -EINVAL;
15
16 *(val++) = 0;
developer5f18e6c2021-07-28 11:55:08 +080017
18 if (!strncmp(argv[0], "he_gi", 5)) {
19 nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI, strtoul(val, NULL, 0));
20 } else if (!strncmp(argv[0], "he_ltf", 6)) {
21 nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF, strtoul(val, NULL, 0));
developer31b1a282021-08-04 14:13:00 +080022 } else if (!strncmp(argv[0], "trig_type", 9)) {
developer13aaa772021-09-27 18:09:26 +080023 s1 = strdup(val);
24 data = nla_nest_start(msg,
25 MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG | NLA_F_NESTED);
26
27 while ((cur = strsep(&s1, ",")) != NULL)
28 nla_put_u8(msg, idx++, strtoul(cur, NULL, 0));
29
30 nla_nest_end(msg, data);
developer31b1a282021-08-04 14:13:00 +080031 } else if (!strncmp(argv[0], "ack_policy", 10)) {
32 nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY, strtoul(val, NULL, 0));
developer5f18e6c2021-07-28 11:55:08 +080033 }
34
35 return 0;
36}
37
38int mt76_ap_rfeatures_set(int idx, int argc, char **argv)
39{
40 struct nl_msg *msg;
41 void *data;
42 int ret;
43
44 if (argc < 1)
45 return 1;
46
47 if (unl_genl_init(&unl, "nl80211") < 0) {
48 fprintf(stderr, "Failed to connect to nl80211\n");
49 return 2;
50 }
51
52 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
53
54 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
55 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
56 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
57 return false;
58
59 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
60
61 mt76_ap_rfeatures_set_attr(msg, argc, argv);
62
63 nla_nest_end(msg, data);
64
65 ret = unl_genl_request(&unl, msg, NULL, NULL);
66 if (ret)
67 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
68
69 unl_free(&unl);
70
71 return ret;
72}
73
74static int mt76_ap_wireless_set_attr(struct nl_msg *msg, int argc, char **argv)
75{
76 char *val;
77
78 val = strchr(argv[0], '=');
developer6f8cffd2021-09-29 19:48:25 +080079 if (!val)
80 return -EINVAL;
81
82 *(val++) = 0;
developer5f18e6c2021-07-28 11:55:08 +080083
84 if (!strncmp(argv[0], "fixed_mcs", 9)) {
85 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS, strtoul(val, NULL, 0));
developer507ff0c2021-07-30 14:51:55 +080086 } else if (!strncmp(argv[0], "ofdma", 5)) {
87 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA, strtoul(val, NULL, 0));
developerb72be592021-08-16 10:58:59 +080088 } else if (!strncmp(argv[0], "ppdu_type", 9)) {
89 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE, strtoul(val, NULL, 0));
90 } else if (!strncmp(argv[0], "nusers_ofdma", 12)) {
91 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA, strtoul(val, NULL, 0));
developer786d9292021-09-22 11:03:21 +080092 } else if (!strncmp(argv[0], "add_ba_req_bufsize", 18)) {
93 nla_put_u16(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
94 strtoul(val, NULL, 0));
95 } else if (!strncmp(argv[0], "mimo", 4)) {
96 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO, strtoul(val, NULL, 0));
developer3a5765c2021-09-23 16:19:12 +080097 } else if (!strncmp(argv[0], "ampdu", 5)) {
98 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU, strtoul(val, NULL, 0));
99 } else if (!strncmp(argv[0], "amsdu", 5)) {
100 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU, strtoul(val, NULL, 0));
developer5f18e6c2021-07-28 11:55:08 +0800101 }
102
103 return 0;
104}
105
106int mt76_ap_wireless_set(int idx, int argc, char **argv)
107{
108 struct nl_msg *msg;
109 void *data;
110 int ret;
111
112 if (argc < 1)
113 return 1;
114
115 if (unl_genl_init(&unl, "nl80211") < 0) {
116 fprintf(stderr, "Failed to connect to nl80211\n");
117 return 2;
118 }
119
120 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
121
122 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
123 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
124 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
125 return false;
126
127 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
128
129 mt76_ap_wireless_set_attr(msg, argc, argv);
130
131 nla_nest_end(msg, data);
132
133 ret = unl_genl_request(&unl, msg, NULL, NULL);
134 if (ret)
135 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
136
137 unl_free(&unl);
138
139 return ret;
140}