blob: 30ae16209ffec7d7413af5869ddd89af8f3d3ee0 [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);
developer0497a7b2021-10-04 10:00:27 +080060 if (!data)
61 return -ENOMEM;
developer5f18e6c2021-07-28 11:55:08 +080062
63 mt76_ap_rfeatures_set_attr(msg, argc, argv);
64
65 nla_nest_end(msg, data);
66
67 ret = unl_genl_request(&unl, msg, NULL, NULL);
68 if (ret)
69 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
70
71 unl_free(&unl);
72
73 return ret;
74}
75
76static int mt76_ap_wireless_set_attr(struct nl_msg *msg, int argc, char **argv)
77{
78 char *val;
79
80 val = strchr(argv[0], '=');
developer6f8cffd2021-09-29 19:48:25 +080081 if (!val)
82 return -EINVAL;
83
84 *(val++) = 0;
developer5f18e6c2021-07-28 11:55:08 +080085
86 if (!strncmp(argv[0], "fixed_mcs", 9)) {
87 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS, strtoul(val, NULL, 0));
developer507ff0c2021-07-30 14:51:55 +080088 } else if (!strncmp(argv[0], "ofdma", 5)) {
89 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA, strtoul(val, NULL, 0));
developerb72be592021-08-16 10:58:59 +080090 } else if (!strncmp(argv[0], "ppdu_type", 9)) {
91 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE, strtoul(val, NULL, 0));
92 } else if (!strncmp(argv[0], "nusers_ofdma", 12)) {
93 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA, strtoul(val, NULL, 0));
developer786d9292021-09-22 11:03:21 +080094 } else if (!strncmp(argv[0], "add_ba_req_bufsize", 18)) {
95 nla_put_u16(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
96 strtoul(val, NULL, 0));
97 } else if (!strncmp(argv[0], "mimo", 4)) {
98 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO, strtoul(val, NULL, 0));
developer3a5765c2021-09-23 16:19:12 +080099 } else if (!strncmp(argv[0], "ampdu", 5)) {
100 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU, strtoul(val, NULL, 0));
101 } else if (!strncmp(argv[0], "amsdu", 5)) {
102 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU, strtoul(val, NULL, 0));
developer07ede8d2021-11-16 18:31:21 +0800103 } else if (!strncmp(argv[0], "cert", 4)) {
104 nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT, strtoul(val, NULL, 0));
developer5f18e6c2021-07-28 11:55:08 +0800105 }
106
107 return 0;
108}
109
110int mt76_ap_wireless_set(int idx, int argc, char **argv)
111{
112 struct nl_msg *msg;
113 void *data;
114 int ret;
115
116 if (argc < 1)
117 return 1;
118
119 if (unl_genl_init(&unl, "nl80211") < 0) {
120 fprintf(stderr, "Failed to connect to nl80211\n");
121 return 2;
122 }
123
124 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
125
126 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
127 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
128 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
129 return false;
130
131 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
developer0497a7b2021-10-04 10:00:27 +0800132 if (!data)
133 return -ENOMEM;
developer5f18e6c2021-07-28 11:55:08 +0800134
135 mt76_ap_wireless_set_attr(msg, argc, argv);
136
137 nla_nest_end(msg, data);
138
139 ret = unl_genl_request(&unl, msg, NULL, NULL);
140 if (ret)
141 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
142
143 unl_free(&unl);
144
145 return ret;
146}