1 #include <stdbool.h>
2 #include <errno.h>
3 #include <net/if.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/ioctl.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <sys/mman.h>
10 #include "calibrator.h"
11 #include "plt.h"
12 #include "ini.h"
13 #include "nvs.h"
15 SECTION(get);
16 SECTION(set);
18 static int get_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
19 struct nl_msg *msg, int argc, char **argv)
20 {
21 unsigned char mac_buff[12];
22 char *fname;
23 int fd;
25 argc -= 2;
26 argv += 2;
28 fname = get_opt_nvsinfile(argc, argv);
29 if (!fname)
30 return 1;
32 fd = open(fname, O_RDONLY);
33 if (fd < 0) {
34 perror("Error opening file for reading");
35 return 1;
36 }
38 read(fd, mac_buff, 12);
40 printf("MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n",
41 mac_buff[11], mac_buff[10], mac_buff[6],
42 mac_buff[5], mac_buff[4], mac_buff[3]);
44 close(fd);
46 return 0;
47 }
49 COMMAND(get, nvs_mac, "[<nvs filename>]", 0, 0, CIB_NONE, get_nvs_mac,
50 "Get MAC addr from NVS file (offline)");
52 /*
53 * Sets MAC address in NVS.
54 * The default value for MAC is random where 1 byte zero.
55 */
56 static int set_nvs_mac(struct nl80211_state *state, struct nl_cb *cb,
57 struct nl_msg *msg, int argc, char **argv)
58 {
59 argc -= 2;
60 argv += 2;
62 if ((argc != 2) || (strlen(argv[1]) != 17))
63 return 1;
65 nvs_set_mac(argv[0], argv[1]);
66 return 0;
67 }
69 COMMAND(set, nvs_mac, "<nvs file> <mac addr>", 0, 0, CIB_NONE, set_nvs_mac,
70 "Set MAC addr in NVS file (offline), like XX:XX:XX:XX:XX:XX");
72 static int set_ref_nvs(struct nl80211_state *state, struct nl_cb *cb,
73 struct nl_msg *msg, int argc, char **argv)
74 {
75 struct wl12xx_common cmn = {
76 .arch = UNKNOWN_ARCH,
77 .parse_ops = NULL
78 };
80 argc -= 2;
81 argv += 2;
83 if (argc < 1 || argc > 2)
84 return 1;
86 if (read_ini(*argv, &cmn)) {
87 fprintf(stderr, "Fail to read ini file\n");
88 return 1;
89 }
90 argv++;
91 argc--;
93 cfg_nvs_ops(&cmn);
95 cmn.nvs_name = get_opt_nvsoutfile(argc, argv);
96 if (create_nvs_file(&cmn)) {
97 fprintf(stderr, "Fail to create reference NVS file\n");
98 return 1;
99 }
101 printf("%04X\n", cmn.arch);
103 return 0;
104 }
106 COMMAND(set, ref_nvs, "<ini file> [<nvs file>]", 0, 0, CIB_NONE, set_ref_nvs,
107 "Create reference NVS file");
109 static int set_upd_nvs(struct nl80211_state *state, struct nl_cb *cb,
110 struct nl_msg *msg, int argc, char **argv)
111 {
112 char *infname = NULL, *outfname = NULL;
113 struct wl12xx_common cmn = {
114 .arch = UNKNOWN_ARCH,
115 .parse_ops = NULL
116 };
118 argc -= 2;
119 argv += 2;
121 if (argc < 1)
122 return 1;
124 if (read_ini(*argv, &cmn)) {
125 fprintf(stderr, "Fail to read ini file\n");
126 return 1;
127 }
128 argc--;
129 argv++;
131 infname = get_opt_nvsinfile(argc, argv);
132 if (!infname)
133 return 1;
135 if (argc) {
136 argc--;
137 argv++;
138 }
139 outfname = get_opt_nvsoutfile(argc, argv);
140 if (!outfname)
141 return 1;
143 cfg_nvs_ops(&cmn);
145 if (update_nvs_file(infname, outfname, &cmn)) {
146 fprintf(stderr, "Fail to update NVS file\n");
147 return 1;
148 }
149 #if 0
150 printf("\n\tThe updated NVS file (%s) is ready\n\tCopy it to %s and "
151 "reboot the system\n\n", NEW_NVS_NAME, CURRENT_NVS_NAME);
152 #endif
153 return 0;
154 }
156 COMMAND(set, upd_nvs, "<ini file> [<nvs infile>] [<nvs_outfile>]", 0, 0, CIB_NONE, set_upd_nvs,
157 "Update values of a NVS from INI file");
159 static int get_dump_nvs(struct nl80211_state *state, struct nl_cb *cb,
160 struct nl_msg *msg, int argc, char **argv)
161 {
162 char *fname = NULL;
164 argc -= 2;
165 argv += 2;
167 fname = get_opt_nvsinfile(argc, argv);
168 if (!fname)
169 return 1;
171 if (dump_nvs_file(fname)) {
172 fprintf(stderr, "Fail to dump NVS file\n");
173 return 1;
174 }
176 return 0;
177 }
179 COMMAND(get, dump_nvs, "[<nvs file>]", 0, 0, CIB_NONE, get_dump_nvs,
180 "Dump NVS file, specified by option or current");
182 static int get_info_nvs(struct nl80211_state *state, struct nl_cb *cb,
183 struct nl_msg *msg, int argc, char **argv)
184 {
185 char *fname;
187 argc -= 2;
188 argv += 2;
190 fname = get_opt_nvsinfile(argc, argv);
191 if(!fname)
192 return 1;
194 if (info_nvs_file(fname)) {
195 fprintf(stderr, "Fail to read info from NVS file\n");
196 return 1;
197 }
199 return 0;
200 }
202 COMMAND(get, info_nvs, "[<nvs file>]", 0, 0, CIB_NONE, get_info_nvs,
203 "Print information from nvs file");
205 static int set_autofem(struct nl80211_state *state, struct nl_cb *cb,
206 struct nl_msg *msg, int argc, char **argv)
207 {
208 char *fname = NULL;
209 int res;
210 unsigned int val;
211 struct wl12xx_common cmn = {
212 .arch = UNKNOWN_ARCH,
213 .parse_ops = NULL
214 };
216 argc -= 2;
217 argv += 2;
219 if (argc < 1) {
220 fprintf(stderr, "Missing argument\n");
221 return 2;
222 }
224 res = sscanf(argv[0], "%x", &val);
225 if (res != 1 || val > 1) {
226 fprintf(stderr, "Invalid argument\n");
227 return 1;
228 }
229 argv++;
230 argc--;
232 fname = get_opt_nvsinfile(argc, argv);
234 if (set_nvs_file_autofem(fname, val, &cmn)) {
235 fprintf(stderr, "Fail to set AutoFEM\n");
236 return 1;
237 }
239 return 0;
240 }
242 COMMAND(set, autofem, "<0-manual|1-auto> [<nvs file>]", 0, 0, CIB_NONE, set_autofem,
243 "Set Auto FEM detection, where 0 - manual, 1 - auto detection");
245 static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb,
246 struct nl_msg *msg, int argc, char **argv)
247 {
248 char *fname = NULL;
249 int res;
250 unsigned int val;
251 struct wl12xx_common cmn = {
252 .arch = UNKNOWN_ARCH,
253 .parse_ops = NULL
254 };
256 argc -= 2;
257 argv += 2;
259 if (argc < 1) {
260 fprintf(stderr, "Missing argument\n");
261 return 2;
262 }
263 res = sscanf(argv[0], "%x", &val);
264 if(res != 1 || val >= WL1271_INI_FEM_MODULE_COUNT) {
265 fprintf(stderr, "Invalid argument\n");
266 return 1;
267 }
268 argv++;
269 argc--;
271 fname = get_opt_nvsinfile(argc, argv);
273 if (set_nvs_file_fem_manuf(fname, val, &cmn)) {
274 fprintf(stderr, "Fail to set AutoFEM\n");
275 return 1;
276 }
278 return 0;
279 }
281 COMMAND(set, fem_manuf, "<0|1|2|3> [<nvs file>]", 0, 0, CIB_NONE, set_fem_manuf,
282 "Set FEM manufacturer");
284 static int get_drv_info(struct nl80211_state *state, struct nl_cb *cb,
285 struct nl_msg *msg, int argc, char **argv)
286 {
287 argc -= 2;
288 argv += 2;
290 if (argc < 1) {
291 fprintf(stderr, "Missing argument (device name)\n");
292 return 2;
293 }
295 return do_get_drv_info(argv[0], NULL, NULL);
296 }
298 COMMAND(get, drv_info, "<device name>", 0, 0, CIB_NONE, get_drv_info,
299 "Get driver information: PG version");
301 static int get_hw_version(struct nl80211_state *state, struct nl_cb *cb,
302 struct nl_msg *msg, int argc, char **argv)
303 {
304 int ret, chip_id = 0;
306 argc -= 2;
307 argv += 2;
309 if (argc < 1) {
310 fprintf(stderr, "Missing argument (device name)\n");
311 return 2;
312 }
314 ret = do_get_drv_info(argv[0], &chip_id, NULL);
315 if (!ret)
316 printf("%08X\n", chip_id);
318 return ret;
319 }
321 COMMAND(get, hw_version, "<device name>", 0, 0, CIB_NONE, get_hw_version,
322 "Get HW version (chip id)");