blob: 99a2d4d5ec21fcd3ea794b6b40b87713be0a763a [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{
developer951bbeb2021-11-15 16:48:31 +08008 char *val, *s1, *s2, *cur;
developer13aaa772021-09-27 18:09:26 +08009 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 data = nla_nest_start(msg,
24 MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG | NLA_F_NESTED);
developer951bbeb2021-11-15 16:48:31 +080025 if (!data)
26 return -ENOMEM;
developer13aaa772021-09-27 18:09:26 +080027
developer951bbeb2021-11-15 16:48:31 +080028 s1 = s2 = strdup(val);
developer13aaa772021-09-27 18:09:26 +080029 while ((cur = strsep(&s1, ",")) != NULL)
30 nla_put_u8(msg, idx++, strtoul(cur, NULL, 0));
31
32 nla_nest_end(msg, data);
developer951bbeb2021-11-15 16:48:31 +080033
34 free(s2);
developer31b1a282021-08-04 14:13:00 +080035 } else if (!strncmp(argv[0], "ack_policy", 10)) {
36 nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY, strtoul(val, NULL, 0));
developer5f18e6c2021-07-28 11:55:08 +080037 }
38
39 return 0;
40}
41
42int mt76_ap_rfeatures_set(int idx, int argc, char **argv)
43{
44 struct nl_msg *msg;
45 void *data;
46 int ret;
47
48 if (argc < 1)
49 return 1;
50
51 if (unl_genl_init(&unl, "nl80211") < 0) {
52 fprintf(stderr, "Failed to connect to nl80211\n");
53 return 2;
54 }
55
56 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
57
58 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
59 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
60 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
61 return false;
62
63 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
developer0497a7b2021-10-04 10:00:27 +080064 if (!data)
65 return -ENOMEM;
developer5f18e6c2021-07-28 11:55:08 +080066
67 mt76_ap_rfeatures_set_attr(msg, argc, argv);
68
69 nla_nest_end(msg, data);
70
71 ret = unl_genl_request(&unl, msg, NULL, NULL);
72 if (ret)
73 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
74
75 unl_free(&unl);
76
77 return ret;
78}
79
80static int mt76_ap_wireless_set_attr(struct nl_msg *msg, int argc, char **argv)
81{
82 char *val;
83
84 val = strchr(argv[0], '=');
developer6f8cffd2021-09-29 19:48:25 +080085 if (!val)
86 return -EINVAL;
87
88 *(val++) = 0;
developer5f18e6c2021-07-28 11:55:08 +080089
90 if (!strncmp(argv[0], "fixed_mcs", 9)) {
91 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS, strtoul(val, NULL, 0));
developer507ff0c2021-07-30 14:51:55 +080092 } else if (!strncmp(argv[0], "ofdma", 5)) {
93 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA, strtoul(val, NULL, 0));
developerb72be592021-08-16 10:58:59 +080094 } else if (!strncmp(argv[0], "ppdu_type", 9)) {
95 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE, strtoul(val, NULL, 0));
96 } else if (!strncmp(argv[0], "nusers_ofdma", 12)) {
97 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA, strtoul(val, NULL, 0));
developer786d9292021-09-22 11:03:21 +080098 } else if (!strncmp(argv[0], "add_ba_req_bufsize", 18)) {
99 nla_put_u16(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
100 strtoul(val, NULL, 0));
101 } else if (!strncmp(argv[0], "mimo", 4)) {
102 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO, strtoul(val, NULL, 0));
developer3a5765c2021-09-23 16:19:12 +0800103 } else if (!strncmp(argv[0], "ampdu", 5)) {
104 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU, strtoul(val, NULL, 0));
105 } else if (!strncmp(argv[0], "amsdu", 5)) {
106 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU, strtoul(val, NULL, 0));
developer07ede8d2021-11-16 18:31:21 +0800107 } else if (!strncmp(argv[0], "cert", 4)) {
108 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT, strtoul(val, NULL, 0));
developer5f18e6c2021-07-28 11:55:08 +0800109 }
110
111 return 0;
112}
113
114int mt76_ap_wireless_set(int idx, int argc, char **argv)
115{
116 struct nl_msg *msg;
117 void *data;
118 int ret;
119
120 if (argc < 1)
121 return 1;
122
123 if (unl_genl_init(&unl, "nl80211") < 0) {
124 fprintf(stderr, "Failed to connect to nl80211\n");
125 return 2;
126 }
127
128 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
129
130 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
131 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
132 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
133 return false;
134
135 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
developer0497a7b2021-10-04 10:00:27 +0800136 if (!data)
137 return -ENOMEM;
developer5f18e6c2021-07-28 11:55:08 +0800138
139 mt76_ap_wireless_set_attr(msg, argc, argv);
140
141 nla_nest_end(msg, data);
142
143 ret = unl_genl_request(&unl, msg, NULL, NULL);
144 if (ret)
145 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
146
147 unl_free(&unl);
148
149 return ret;
150}