blob: 485b882bbd9ea4b23787e41fcfe81fe9118fb710 [file] [log] [blame]
developer8fb759f2022-02-21 16:39:38 +08001/* Copyright (C) 2021 Mediatek Inc. */
2#define _GNU_SOURCE
3
4#include "mtk_vendor_nl80211.h"
5#include "mt76-vendor.h"
6#include "mwctl.h"
7
8static struct nla_policy
9amnt_ctrl_policy[NUM_MTK_VENDOR_ATTRS_AMNT_CTRL] = {
10 [MTK_VENDOR_ATTR_AMNT_CTRL_SET] = {.type = NLA_NESTED },
11 [MTK_VENDOR_ATTR_AMNT_CTRL_DUMP] = { .type = NLA_NESTED },
12};
13
14static struct nla_policy
15amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
16 [MTK_VENDOR_ATTR_AMNT_DUMP_INDEX] = {.type = NLA_U8 },
17 [MTK_VENDOR_ATTR_AMNT_DUMP_LEN] = { .type = NLA_U8 },
18 [MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
19};
20
21static int mt76_amnt_set_attr(struct nl_msg *msg, int argc, char **argv)
22{
23 void *tb1, *tb2;
24 u8 a[ETH_ALEN], idx;
25 int i = 0, matches;
26
27 idx = strtoul(argv[0], NULL, 0);
28 matches = sscanf(argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
29 a, a+1, a+2, a+3, a+4, a+5);
30
31 if (matches != ETH_ALEN)
32 return -EINVAL;
33
34 tb1 = nla_nest_start(msg, MTK_VENDOR_ATTR_AMNT_CTRL_SET | NLA_F_NESTED);
35 if (!tb1)
36 return -ENOMEM;
37
38 nla_put_u8(msg, MTK_VENDOR_ATTR_AMNT_SET_INDEX, idx);
39
40 tb2 = nla_nest_start(msg, MTK_VENDOR_ATTR_AMNT_SET_MACADDR | NLA_F_NESTED);
41 if (!tb2) {
42 nla_nest_end(msg, tb1);
43 return -ENOMEM;
44 }
45
46 for (i = 0; i < ETH_ALEN; i++)
47 nla_put_u8(msg, i, a[i]);
48
49 nla_nest_end(msg, tb2);
50 nla_nest_end(msg, tb1);
51
52 return 0;
53}
54
55int mt76_amnt_set(struct nl_msg *msg, int argc,
56 char **argv, void *ctx)
57{
58 void *data;
59 int ret = 0;
60
61 if (argc < 1)
62 return 1;
63
64 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
65 if (!data)
66 return -ENOMEM;
67
68 mt76_amnt_set_attr(msg, argc, argv);
69
70 nla_nest_end(msg, data);
71
72 return ret;
73}
74
75static int mt76_amnt_dump_cb(struct nl_msg *msg, void *arg)
76{
77 struct nlattr *tb1[NUM_MTK_VENDOR_ATTRS_AMNT_CTRL];
78 struct nlattr *tb2[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP];
79 struct nlattr *attr;
80 struct nlattr *data;
81 struct nlattr *cur;
82 struct amnt_data *res;
83 int len = 0, rem;
84
85 attr = unl_find_attr(&unl, msg, NL80211_ATTR_VENDOR_DATA);
86 if (!attr) {
87 fprintf(stderr, "Testdata attribute not found\n");
88 return NL_SKIP;
89 }
90
91 nla_parse_nested(tb1, MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
92 attr, amnt_ctrl_policy);
93
94 if (!tb1[MTK_VENDOR_ATTR_AMNT_CTRL_DUMP])
95 return NL_SKIP;
96
97 nla_parse_nested(tb2, NUM_MTK_VENDOR_ATTRS_AMNT_DUMP,
98 tb1[MTK_VENDOR_ATTR_AMNT_CTRL_DUMP], amnt_dump_policy);
99
100 if (!tb2[MTK_VENDOR_ATTR_AMNT_DUMP_LEN])
101 return NL_SKIP;
102
103 len = nla_get_u8(tb2[MTK_VENDOR_ATTR_AMNT_DUMP_LEN]);
104 if (!len)
105 return 0;
106
107 if (!tb2[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT])
108 return NL_SKIP;
109
110 data = tb2[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT];
111 nla_for_each_nested(cur,data, rem) {
112 res = (struct amnt_data *) nla_data(cur);
113 printf("[vendor] amnt_idx: %d, addr=%x:%x:%x:%x:%x:%x, rssi=%d/%d/%d/%d, last_seen=%u\n",
114 res->idx,
115 res->addr[0], res->addr[1], res->addr[2],
116 res->addr[3], res->addr[4], res->addr[5],
117 res->rssi[0], res->rssi[1], res->rssi[2],
118 res->rssi[3], res->last_seen);
119 }
120 return 0;
121}
122
123int mt76_amnt_dump (struct nl_msg *msg, int argc,
124 char **argv, void *ctx)
125{
126 void *data, *tb1;
127 u8 amnt_idx;
128
129 if (argc < 1)
130 return 1;
131
132 register_handler(mt76_amnt_dump_cb, NULL);
133
134 data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
135 if (!data)
136 return -EINVAL;
137
138 tb1 = nla_nest_start(msg, MTK_VENDOR_ATTR_AMNT_CTRL_DUMP | NLA_F_NESTED);
139 if (!tb1)
140 return -EINVAL;
141
142 amnt_idx = strtoul(argv[0], NULL, 0);
143 nla_put_u8(msg, MTK_VENDOR_ATTR_AMNT_DUMP_INDEX, amnt_idx);
144
145 nla_nest_end(msg, tb1);
146
147 nla_nest_end(msg, data);
148
149 return 0;
150}
151
152DECLARE_SECTION(dump);
153
154COMMAND(dump, amnt, "",
155 MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL, 0, CIB_NETDEV, mt76_amnt_dump,
156 "dump amnt <index> (0x0~0xf or 0xff)");
157
158DECLARE_SECTION(set);
159
160COMMAND(set, amnt, "<index>(0x0~0xf) <mac addr>(xx:xx:xx:xx:xx:xx)",
161 MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL, 0, CIB_NETDEV, mt76_amnt_set,
162 "set amnt <index>(0x0~0xf) <mac addr>(xx:xx:xx:xx:xx:xx)");
163
164