blob: f6e683bfe2badf341f0959a416c29310b06a1fce [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));
developer5f18e6c2021-07-28 11:55:08 +0800103 }
104
105 return 0;
106}
107
108int mt76_ap_wireless_set(int idx, int argc, char **argv)
109{
110 struct nl_msg *msg;
111 void *data;
112 int ret;
113
114 if (argc < 1)
115 return 1;
116
117 if (unl_genl_init(&unl, "nl80211") < 0) {
118 fprintf(stderr, "Failed to connect to nl80211\n");
119 return 2;
120 }
121
122 msg = unl_genl_msg(&unl, NL80211_CMD_VENDOR, false);
123
124 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, idx) ||
125 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
126 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
127 return false;
128
129 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
developer0497a7b2021-10-04 10:00:27 +0800130 if (!data)
131 return -ENOMEM;
developer5f18e6c2021-07-28 11:55:08 +0800132
133 mt76_ap_wireless_set_attr(msg, argc, argv);
134
135 nla_nest_end(msg, data);
136
137 ret = unl_genl_request(&unl, msg, NULL, NULL);
138 if (ret)
139 fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
140
141 unl_free(&unl);
142
143 return ret;
144}