1 /*
2 * PLT utility for wireless chip supported by TI's driver wl12xx
3 *
4 * See README and COPYING for more details.
5 */
6
7 #include <sys/ioctl.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <stdbool.h>
16
17 #include <netlink/genl/genl.h>
18 #include <netlink/genl/family.h>
19 #include <netlink/genl/ctrl.h>
20 #include <netlink/msg.h>
21 #include <netlink/attr.h>
22 #include <linux/wireless.h>
23 #include "nl80211.h"
24
25 #include "calibrator.h"
26 #include "plt.h"
27 #include "ini.h"
28 #include "nvs.h"
29
30 SECTION(plt);
31
str2mac(unsigned char * pmac,char * pch)32 static void str2mac(unsigned char *pmac, char *pch)
33 {
34 int i;
35
36 for (i = 0; i < MAC_ADDR_LEN; i++) {
37 pmac[i] = (unsigned char)strtoul(pch, &pch, 16);
38 pch++;
39 }
40 }
41
plt_power_mode(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)42 static int plt_power_mode(struct nl80211_state *state, struct nl_cb *cb,
43 struct nl_msg *msg, int argc, char **argv)
44 {
45 struct nlattr *key;
46 unsigned int pmode;
47
48 if (argc != 1) {
49 fprintf(stderr, "%s> Missing arguments\n", __func__);
50 return 2;
51 }
52
53 if (strcmp(argv[0], "on") == 0) {
54 pmode = 1;
55 } else if (strcmp(argv[0], "off") == 0) {
56 pmode = 0;
57 } else {
58 fprintf(stderr, "%s> Invalid parameter\n", __func__);
59 return 2;
60 }
61
62 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
63 if (!key) {
64 fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
65 return 1;
66 }
67
68 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_SET_PLT_MODE);
69 NLA_PUT_U32(msg, WL1271_TM_ATTR_PLT_MODE, pmode);
70
71 nla_nest_end(msg, key);
72
73 return 0;
74
75 nla_put_failure:
76 fprintf(stderr, "%s> building message failed\n", __func__);
77 return 2;
78 }
79
80 COMMAND(plt, power_mode, "<on|off>",
81 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_power_mode,
82 "Set PLT power mode\n");
83
plt_tune_channel(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)84 static int plt_tune_channel(struct nl80211_state *state, struct nl_cb *cb,
85 struct nl_msg *msg, int argc, char **argv)
86 {
87 struct nlattr *key;
88 struct wl1271_cmd_cal_channel_tune prms;
89
90 if (argc < 1 || argc > 2) {
91 return 1;
92 }
93
94 prms.test.id = TEST_CMD_CHANNEL_TUNE;
95 prms.band = (unsigned char)atoi(argv[0]);
96 prms.channel = (unsigned char)atoi(argv[1]);
97
98 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
99 if (!key) {
100 fprintf(stderr, "fail to nla_nest_start()\n");
101 return 1;
102 }
103
104 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
105 NLA_PUT(msg, WL1271_TM_ATTR_DATA,
106 sizeof(struct wl1271_cmd_cal_channel_tune),
107 &prms);
108
109 nla_nest_end(msg, key);
110
111 return 0;
112
113 nla_put_failure:
114 fprintf(stderr, "%s> building message failed\n", __func__);
115 return 2;
116 }
117
118 COMMAND(plt, tune_channel, "<band> <channel>",
119 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tune_channel,
120 "Set band and channel for PLT\n");
121
plt_ref_point(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)122 static int plt_ref_point(struct nl80211_state *state, struct nl_cb *cb,
123 struct nl_msg *msg, int argc, char **argv)
124 {
125 struct nlattr *key;
126 struct wl1271_cmd_cal_update_ref_point prms;
127
128 if (argc < 1 || argc > 3){
129 return 1;
130 }
131
132 prms.test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
133 prms.ref_detector = atoi(argv[0]);
134 prms.ref_power = atoi(argv[1]);
135 prms.sub_band = atoi(argv[2]);
136
137 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
138 if (!key) {
139 fprintf(stderr, "fail to nla_nest_start()\n");
140 return 1;
141 }
142
143 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
144 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
145
146 nla_nest_end(msg, key);
147
148 return 0;
149
150 nla_put_failure:
151 fprintf(stderr, "%s> building message failed\n", __func__);
152 return 2;
153 }
154
155 COMMAND(plt, ref_point, "<voltage> <power> <subband>",
156 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_ref_point,
157 "Set reference point for PLT\n");
158
calib_valid_handler(struct nl_msg * msg,void * arg)159 static int calib_valid_handler(struct nl_msg *msg, void *arg)
160 {
161 struct nlattr *tb[NL80211_ATTR_MAX + 1];
162 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
163 struct nlattr *td[WL1271_TM_ATTR_MAX + 1];
164 struct wl1271_cmd_cal_p2g *prms;
165 #if 0
166 int i; unsigned char *pc;
167 #endif
168 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
169 genlmsg_attrlen(gnlh, 0), NULL);
170
171 if (!tb[NL80211_ATTR_TESTDATA]) {
172 fprintf(stderr, "no data!\n");
173 return NL_SKIP;
174 }
175
176 nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]),
177 nla_len(tb[NL80211_ATTR_TESTDATA]), NULL);
178
179 prms = (struct wl1271_cmd_cal_p2g *)nla_data(td[WL1271_TM_ATTR_DATA]);
180
181 if (prms->radio_status) {
182 fprintf(stderr, "Fail to calibrate ith radio status (%d)\n",
183 (signed short)prms->radio_status);
184 return 2;
185 }
186 #if 0
187 printf("%s> id %04x status %04x\ntest id %02x ver %08x len %04x=%d\n",
188 __func__,
189 prms->header.id, prms->header.status, prms->test.id,
190 prms->ver, prms->len, prms->len);
191
192 pc = (unsigned char *)prms->buf;
193 printf("++++++++++++++++++++++++\n");
194 for (i = 0; i < prms->len; i++) {
195 if (i%0xf == 0)
196 printf("\n");
197
198 printf("%02x ", *(unsigned char *)pc);
199 pc += 1;
200 }
201 printf("++++++++++++++++++++++++\n");
202 #endif
203 if (prepare_nvs_file(prms, arg)) {
204 fprintf(stderr, "Fail to prepare calibrated NVS file\n");
205 return 2;
206 }
207 #if 0
208 printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and "
209 "reboot the system\n\n",
210 NEW_NVS_NAME, CURRENT_NVS_NAME);
211 #endif
212 return NL_SKIP;
213 }
214
plt_tx_bip(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)215 static int plt_tx_bip(struct nl80211_state *state, struct nl_cb *cb,
216 struct nl_msg *msg, int argc, char **argv)
217 {
218 struct nlattr *key;
219 struct wl1271_cmd_cal_p2g prms;
220 int i;
221 char nvs_path[PATH_MAX];
222
223 if (argc < 8) {
224 fprintf(stderr, "%s> Missing arguments\n", __func__);
225 return 2;
226 }
227
228 if (argc > 8) {
229 strncpy(nvs_path, argv[8], strlen(argv[8]));
230 } else {
231 nvs_path[0] = '\0';
232 }
233
234 memset(&prms, 0, sizeof(struct wl1271_cmd_cal_p2g));
235
236 prms.test.id = TEST_CMD_P2G_CAL;
237 for (i = 0; i < 8; i++) {
238 prms.sub_band_mask |= (atoi(argv[i]) & 0x1)<<i;
239 }
240
241 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
242 if (!key) {
243 fprintf(stderr, "fail to nla_nest_start()\n");
244 return 1;
245 }
246
247 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
248 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
249 NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1);
250
251 nla_nest_end(msg, key);
252
253 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, calib_valid_handler, nvs_path);
254
255 return 0;
256
257 nla_put_failure:
258 fprintf(stderr, "%s> building message failed\n", __func__);
259 return 2;
260 }
261
262 COMMAND(plt, tx_bip,
263 "<0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> <0|1> [<nvs file>]",
264 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_bip,
265 "Do calibrate\n");
266
plt_tx_tone(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)267 static int plt_tx_tone(struct nl80211_state *state, struct nl_cb *cb,
268 struct nl_msg *msg, int argc, char **argv)
269 {
270 struct nlattr *key;
271 struct wl1271_cmd_cal_tx_tone prms;
272
273 if (argc < 2) {
274 fprintf(stderr, "%s> Missing arguments\n", __func__);
275 return 2;
276 }
277
278 memset(&prms, 0, sizeof(struct wl1271_cmd_cal_tx_tone));
279
280 prms.test.id = TEST_CMD_TELEC;
281 prms.power = atoi(argv[0]);
282 prms.tone_type = atoi(argv[1]);
283
284 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
285 if (!key) {
286 fprintf(stderr, "fail to nla_nest_start()\n");
287 return 1;
288 }
289
290 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
291 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
292
293 nla_nest_end(msg, key);
294
295 return 0;
296
297 nla_put_failure:
298 fprintf(stderr, "%s> building message failed\n", __func__);
299 return 2;
300 }
301
302 COMMAND(plt, tx_tone, "<power> <tone type>",
303 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_tone,
304 "Do command tx_tone to transmit a tone\n");
305
plt_tx_cont(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)306 static int plt_tx_cont(struct nl80211_state *state, struct nl_cb *cb,
307 struct nl_msg *msg, int argc, char **argv)
308 {
309 struct nlattr *key;
310 struct wl1271_cmd_pkt_params prms = {
311 .src_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
312 };
313
314 if (argc != 15) {
315 return 1;
316 }
317 #if 0
318 printf("%s> delay (%d) rate (%08x) size (%d) amount (%d) power (%d) "
319 "seed (%d) pkt_mode (%d) DCF (%d) GI (%d) preamble (%d) type "
320 "(%d) scramble (%d) CLPC (%d), SeqNbrMode (%d) DestMAC (%s)\n",
321 __func__,
322 atoi(argv[0]), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]),
323 atoi(argv[4]), atoi(argv[5]), atoi(argv[6]), atoi(argv[7]),
324 atoi(argv[8]), atoi(argv[9]), atoi(argv[10]), atoi(argv[11]),
325 atoi(argv[12]), atoi(argv[13]), argv[14]
326 );
327 #endif
328 memset((void *)&prms, 0, sizeof(struct wl1271_cmd_pkt_params));
329
330 prms.test.id = TEST_CMD_FCC;
331 prms.delay = atoi(argv[0]);
332 prms.rate = atoi(argv[1]);
333 prms.size = (unsigned short)atoi(argv[2]);
334 prms.amount = (unsigned short)atoi(argv[3]);
335 prms.power = atoi(argv[4]);
336 prms.seed = (unsigned short)atoi(argv[5]);
337 prms.pkt_mode = (unsigned char)atoi(argv[6]);
338 prms.dcf_enable = (unsigned char)atoi(argv[7]);
339 prms.g_interval = (unsigned char)atoi(argv[8]);
340 prms.preamble = (unsigned char)atoi(argv[9]);
341 prms.type = (unsigned char)atoi(argv[10]);
342 prms.scramble = (unsigned char)atoi(argv[11]);
343 prms.clpc_enable = (unsigned char)atoi(argv[12]);
344 prms.seq_nbr_mode = (unsigned char)atoi(argv[13]);
345 str2mac(prms.dst_mac, argv[14]);
346
347 if (get_mac_addr(0, prms.src_mac)) {
348 fprintf(stderr, "fail to get MAC addr\n");
349 }
350
351 printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
352 prms.src_mac[0], prms.src_mac[1], prms.src_mac[2],
353 prms.src_mac[3], prms.src_mac[4], prms.src_mac[5]);
354
355 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
356 if (!key) {
357 fprintf(stderr, "fail to nla_nest_start()\n");
358 return 1;
359 }
360
361 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
362 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
363
364 nla_nest_end(msg, key);
365
366 return 0;
367
368 nla_put_failure:
369 fprintf(stderr, "%s> building message failed\n", __func__);
370 return 2;
371 }
372
373 COMMAND(plt, tx_cont, "<delay> <rate> <size> <amount> <power>\n\t\t<seed> "
374 "<pkt mode> <DC on/off> <gi> <preamble>\n\t\t<type> <scramble> "
375 "<clpc> <seq nbr mode> <dest mac>",
376 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_cont,
377 "Start Tx Cont\n");
378
plt_tx_stop(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)379 static int plt_tx_stop(struct nl80211_state *state, struct nl_cb *cb,
380 struct nl_msg *msg, int argc, char **argv)
381 {
382 struct nlattr *key;
383 struct wl1271_cmd_pkt_params prms;
384
385 prms.test.id = TEST_CMD_STOP_TX;
386
387 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
388 if (!key) {
389 fprintf(stderr, "fail to nla_nest_start()\n");
390 return 1;
391 }
392
393 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
394 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
395
396 nla_nest_end(msg, key);
397
398 return 0;
399
400 nla_put_failure:
401 fprintf(stderr, "%s> building message failed\n", __func__);
402 return 2;
403 }
404
405 COMMAND(plt, tx_stop, NULL,
406 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_tx_stop,
407 "Stop Tx Cont\n");
408
plt_start_rx_statcs(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)409 static int plt_start_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
410 struct nl_msg *msg, int argc, char **argv)
411 {
412 struct nlattr *key;
413 struct wl1271_cmd_pkt_params prms;
414
415 prms.test.id = TEST_CMD_RX_STAT_START;
416
417 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
418 if (!key) {
419 fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
420 return 1;
421 }
422
423 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
424 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
425
426 nla_nest_end(msg, key);
427
428 return 0;
429
430 nla_put_failure:
431 fprintf(stderr, "%s> building message failed\n", __func__);
432 return 2;
433 }
434
435 COMMAND(plt, start_rx_statcs, NULL,
436 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_start_rx_statcs,
437 "Start Rx statistics collection\n");
438
plt_stop_rx_statcs(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)439 static int plt_stop_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
440 struct nl_msg *msg, int argc, char **argv)
441 {
442 struct nlattr *key;
443 struct wl1271_cmd_pkt_params prms;
444
445 prms.test.id = TEST_CMD_RX_STAT_STOP;
446
447 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
448 if (!key) {
449 fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
450 return 1;
451 }
452
453 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
454 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
455
456 nla_nest_end(msg, key);
457
458 return 0;
459
460 nla_put_failure:
461 fprintf(stderr, "%s> building message failed\n", __func__);
462 return 2;
463 }
464
465 COMMAND(plt, stop_rx_statcs, NULL,
466 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_stop_rx_statcs,
467 "Stop Rx statistics collection\n");
468
plt_reset_rx_statcs(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)469 static int plt_reset_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
470 struct nl_msg *msg, int argc, char **argv)
471 {
472 struct nlattr *key;
473 struct wl1271_cmd_pkt_params prms;
474
475 prms.test.id = TEST_CMD_RX_STAT_RESET;
476
477 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
478 if (!key) {
479 fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
480 return 1;
481 }
482
483 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
484 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
485
486 nla_nest_end(msg, key);
487
488 return 0;
489
490 nla_put_failure:
491 fprintf(stderr, "%s> building message failed\n", __func__);
492 return 2;
493 }
494
495 COMMAND(plt, reset_rx_statcs, NULL,
496 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_reset_rx_statcs,
497 "Reset Rx statistics collection\n");
498
display_rx_statcs(struct nl_msg * msg,void * arg)499 static int display_rx_statcs(struct nl_msg *msg, void *arg)
500 {
501 struct nlattr *tb[NL80211_ATTR_MAX + 1];
502 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
503 struct nlattr *td[WL1271_TM_ATTR_MAX + 1];
504 struct wl1271_radio_rx_statcs *prms;
505
506 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
507 genlmsg_attrlen(gnlh, 0), NULL);
508
509 if (!tb[NL80211_ATTR_TESTDATA]) {
510 fprintf(stderr, "no data!\n");
511 return NL_SKIP;
512 }
513
514 nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]),
515 nla_len(tb[NL80211_ATTR_TESTDATA]), NULL);
516
517 prms =
518 (struct wl1271_radio_rx_statcs *)
519 nla_data(td[WL1271_TM_ATTR_DATA]);
520
521 printf("\n\tTotal number of pkts\t- %d\n\tAccepted pkts\t\t- %d\n\t"
522 "FCS error pkts\t\t- %d\n\tAddress mismatch pkts\t- %d\n\t"
523 "Average SNR\t\t- % d dBm\n\tAverage RSSI\t\t- % d dBm\n\n",
524 prms->base_pkt_id, prms->rx_path_statcs.nbr_rx_valid_pkts,
525 prms->rx_path_statcs.nbr_rx_fcs_err_pkts,
526 prms->rx_path_statcs.nbr_rx_plcp_err_pkts,
527 (signed short)prms->rx_path_statcs.ave_snr/8,
528 (signed short)prms->rx_path_statcs.ave_rssi/8);
529
530 return NL_SKIP;
531 }
532
plt_get_rx_statcs(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)533 static int plt_get_rx_statcs(struct nl80211_state *state, struct nl_cb *cb,
534 struct nl_msg *msg, int argc, char **argv)
535 {
536 struct nlattr *key;
537 struct wl1271_radio_rx_statcs prms;
538
539 prms.test.id = TEST_CMD_RX_STAT_GET;
540
541 key = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
542 if (!key) {
543 fprintf(stderr, "%s> fail to nla_nest_start()\n", __func__);
544 return 1;
545 }
546
547 NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST);
548 NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms);
549 NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1);
550
551 nla_nest_end(msg, key);
552
553 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, display_rx_statcs, NULL);
554
555 /* Important: needed gap between tx_start and tx_get */
556 sleep(2);
557
558 return 0;
559
560 nla_put_failure:
561 fprintf(stderr, "%s> building message failed\n", __func__);
562 return 2;
563 }
564
565 COMMAND(plt, get_rx_statcs, NULL,
566 NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_get_rx_statcs,
567 "Get Rx statistics\n");
568
plt_rx_statistics(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)569 static int plt_rx_statistics(struct nl80211_state *state, struct nl_cb *cb,
570 struct nl_msg *msg, int argc, char **argv)
571 {
572 int ret;
573
574 /* power mode on */
575 {
576 char *prms[4] = { "wlan0", "plt", "power_mode", "on" };
577
578 ret = handle_cmd(state, II_NETDEV, 4, prms);
579 if (ret < 0) {
580 fprintf(stderr, "Fail to set PLT power mode on\n");
581 return 1;
582 }
583 }
584
585 /* start_rx_statcs */
586 {
587 char *prms[3] = { "wlan0", "plt", "start_rx_statcs" };
588
589 ret = handle_cmd(state, II_NETDEV, 3, prms);
590 if (ret < 0) {
591 fprintf(stderr, "Fail to start Rx statistics\n");
592 goto fail_out;
593 }
594 }
595
596 /* get_rx_statcs */
597 {
598 int err;
599 char *prms[3] = { "wlan0", "plt", "get_rx_statcs" };
600
601 err = handle_cmd(state, II_NETDEV, 3, prms);
602 if (err < 0) {
603 fprintf(stderr, "Fail to get Rx statistics\n");
604 ret = err;
605 }
606 }
607
608
609 /* stop_rx_statcs */
610 {
611 int err;
612 char *prms[3] = { "wlan0", "plt", "stop_rx_statcs" };
613
614 err = handle_cmd(state, II_NETDEV, 3, prms);
615 if (err < 0) {
616 fprintf(stderr, "Fail to stop Rx statistics\n");
617 ret = err;
618 }
619 }
620
621 fail_out:
622 /* power mode off */
623 {
624 int err;
625 char *prms[4] = { "wlan0", "plt", "power_mode", "off"};
626
627 err = handle_cmd(state, II_NETDEV, 4, prms);
628 if (err < 0) {
629 fprintf(stderr, "Fail to set PLT power mode on\n");
630 return 1;
631 }
632 }
633
634 if (ret < 0) {
635 return 1;
636 }
637
638 return 0;
639 }
640
641 COMMAND(plt, rx_statistics, NULL, 0, 0, CIB_NONE, plt_rx_statistics,
642 "Get Rx statistics\n");
643
plt_calibrate(struct nl80211_state * state,struct nl_cb * cb,struct nl_msg * msg,int argc,char ** argv)644 static int plt_calibrate(struct nl80211_state *state, struct nl_cb *cb,
645 struct nl_msg *msg, int argc, char **argv)
646 {
647 int ret = 0, err;
648 int single_dual = 0;
649
650 if (argc > 2 && (strncmp(argv[2], "dual", 4) == 0)) {
651 single_dual = 1; /* going for dual band calibration */
652 } else {
653 single_dual = 0; /* going for single band calibration */
654 }
655
656 /* power mode on */
657 {
658 char *pm_on[4] = { "wlan0", "plt", "power_mode", "on" };
659
660 err = handle_cmd(state, II_NETDEV, 4, pm_on);
661 if (err < 0) {
662 fprintf(stderr, "Fail to set PLT power mode on\n");
663 ret = err;
664 goto fail_out_final;
665 }
666 }
667
668 /* tune channel */
669 {
670 char *pm_on[5] = {
671 "wlan0", "plt", "tune_channel", "0", "7"
672 };
673
674 err = handle_cmd(state, II_NETDEV, 5, pm_on);
675 if (err < 0) {
676 fprintf(stderr, "Fail to tune channel\n");
677 ret = err;
678 goto fail_out;
679 }
680 }
681
682 /* calibrate it */
683 {
684 char *prms[11] = {
685 "wlan0", "plt", "tx_bip", "1", "0", "0", "0",
686 "0", "0", "0", "0"
687 };
688
689 /* set flags in case of dual band */
690 if (single_dual) {
691 prms[4] = prms[5] = prms[6] = prms[7] = prms[8] =
692 prms[9] = prms[10] = "1";
693 }
694
695 err = handle_cmd(state, II_NETDEV, 11, prms);
696 if (err < 0) {
697 fprintf(stderr, "Fail to calibrate\n");
698 ret = err;
699 }
700 }
701
702 fail_out:
703 /* power mode off */
704 {
705 char *prms[4] = { "wlan0", "plt", "power_mode", "off"};
706
707 err = handle_cmd(state, II_NETDEV, 4, prms);
708 if (err < 0) {
709 fprintf(stderr, "Fail to set PLT power mode on\n");
710 ret = err;
711 }
712 }
713
714 fail_out_final:
715 if (ret < 0) {
716 return 1;
717 }
718
719 return 0;
720 }
721
722 COMMAND(plt, calibrate, "[<single|dual>]", 0, 0, CIB_NONE,
723 plt_calibrate, "Do calibrate for single or dual band chip\n");
724