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 #include <netinet/in.h>
17
18 #include <netlink/netlink.h>
19 #include <netlink/msg.h>
20 #include <netlink/attr.h>
21 #include <linux/wireless.h>
22 #include "nl80211.h"
23
24 #include "calibrator.h"
25 #include "plt.h"
26 #include "ini.h"
27 /* 2048 - it should be enough for any chip, until... 22dec2010 */
28 #define BUF_SIZE_4_NVS_FILE 2048
29
30 static const char if_name_fmt[] = "wlan%d";
31
nvs_fill_radio_params(int fd,struct wl12xx_ini * ini,char * buf)32 int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf)
33 {
34 int size;
35 struct wl1271_ini *gp;
36
37 if (ini) {
38 gp = &ini->ini1271;
39 }
40
41 size = sizeof(struct wl1271_ini);
42
43 if (ini) { /* for reference NVS */
44 unsigned char *c = (unsigned char *)gp;
45 int i;
46
47 for (i = 0; i < size; i++) {
48 write(fd, c++, 1);
49 }
50 } else {
51 char *p = buf + 0x1D4;
52 write(fd, (const void *)p, size);
53 }
54
55 return 0;
56 }
57
nvs_fill_radio_params_128x(int fd,struct wl12xx_ini * ini,char * buf)58 static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf)
59 {
60 int size;
61 struct wl128x_ini *gp = &ini->ini128x;
62
63 size = sizeof(struct wl128x_ini);
64
65 if (ini) { /* for reference NVS */
66 unsigned char *c = (unsigned char *)gp;
67 int i;
68
69 for (i = 0; i < size; i++) {
70 write(fd, c++, 1);
71 }
72
73 } else {
74 char *p = buf + 0x1D4;
75 write(fd, p, size);
76 }
77
78 return 0;
79 }
80
nvs_set_autofem(int fd,char * buf,unsigned char val)81 int nvs_set_autofem(int fd, char *buf, unsigned char val)
82 {
83 int size;
84 struct wl1271_ini *gp;
85 unsigned char *c;
86 int i;
87
88 if (buf == NULL) {
89 return 1;
90 }
91
92 gp = (struct wl1271_ini *)(buf+0x1d4);
93 gp->general_params.tx_bip_fem_auto_detect = val;
94
95 size = sizeof(struct wl1271_ini);
96
97 c = (unsigned char *)gp;
98
99 for (i = 0; i < size; i++) {
100 write(fd, c++, 1);
101 }
102
103 return 0;
104 }
105
nvs_set_autofem_128x(int fd,char * buf,unsigned char val)106 int nvs_set_autofem_128x(int fd, char *buf, unsigned char val)
107 {
108 int size;
109 struct wl128x_ini *gp;
110 unsigned char *c;
111 int i;
112
113 if (buf == NULL) {
114 return 1;
115 }
116
117 gp = (struct wl128x_ini *)(buf+0x1d4);
118 gp->general_params.tx_bip_fem_auto_detect = val;
119
120 size = sizeof(struct wl128x_ini);
121
122 c = (unsigned char *)gp;
123
124 for (i = 0; i < size; i++) {
125 write(fd, c++, 1);
126 }
127
128 return 0;
129 }
130
nvs_set_fem_manuf(int fd,char * buf,unsigned char val)131 int nvs_set_fem_manuf(int fd, char *buf, unsigned char val)
132 {
133 int size;
134 struct wl1271_ini *gp;
135 unsigned char *c;
136 int i;
137
138 if (buf == NULL) {
139 return 1;
140 }
141
142 gp = (struct wl1271_ini *)(buf+0x1d4);
143 gp->general_params.tx_bip_fem_manufacturer = val;
144
145 size = sizeof(struct wl1271_ini);
146
147 c = (unsigned char *)gp;
148
149 for (i = 0; i < size; i++) {
150 write(fd, c++, 1);
151 }
152
153 return 0;
154 }
155
nvs_set_fem_manuf_128x(int fd,char * buf,unsigned char val)156 int nvs_set_fem_manuf_128x(int fd, char *buf, unsigned char val)
157 {
158 int size;
159 struct wl128x_ini *gp;
160 unsigned char *c;
161 int i;
162
163 if (buf == NULL) {
164 return 1;
165 }
166
167 gp = (struct wl128x_ini *)(buf+0x1d4);
168 gp->general_params.tx_bip_fem_manufacturer = val;
169
170 size = sizeof(struct wl128x_ini);
171
172 c = (unsigned char *)gp;
173
174 for (i = 0; i < size; i++) {
175 write(fd, c++, 1);
176 }
177
178 return 0;
179 }
180
181 static struct wl12xx_nvs_ops wl1271_nvs_ops = {
182 .nvs_fill_radio_prms = nvs_fill_radio_params,
183 .nvs_set_autofem = nvs_set_autofem,
184 .nvs_set_fem_manuf = nvs_set_fem_manuf,
185 };
186
187 static struct wl12xx_nvs_ops wl128x_nvs_ops = {
188 .nvs_fill_radio_prms = nvs_fill_radio_params_128x,
189 .nvs_set_autofem = nvs_set_autofem_128x,
190 .nvs_set_fem_manuf = nvs_set_fem_manuf_128x,
191 };
192
get_mac_addr(int ifc_num,unsigned char * mac_addr)193 int get_mac_addr(int ifc_num, unsigned char *mac_addr)
194 {
195 int s;
196 struct ifreq ifr;
197 #if 0
198 if (ifc_num < 0 || ifc_num >= ETH_DEV_MAX)
199 return 1;
200 #endif
201 s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
202 if (s < 0) {
203 fprintf(stderr, "unable to socket (%s)\n", strerror(errno));
204 return 1;
205 }
206
207 memset(&ifr, 0, sizeof(struct ifreq));
208 sprintf(ifr.ifr_name, if_name_fmt, ifc_num) ;
209 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
210 fprintf(stderr, "unable to ioctl (%s)\n", strerror(errno));
211 close(s);
212 return 1;
213 }
214
215 close(s);
216
217 memcpy(mac_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data[0], 6);
218
219 return 0;
220 }
221
file_exist(const char * filename)222 int file_exist(const char *filename)
223 {
224 struct stat buf;
225 int ret;
226
227 if (filename == NULL) {
228 fprintf(stderr, "wrong parameter\n");
229 return -1;
230 }
231
232 ret = stat(filename, &buf);
233 if (ret != 0) {
234 fprintf(stderr, "fail to stat file %s (%s)\n", filename,
235 strerror(errno));
236 return -1;
237 }
238
239 return (int)buf.st_size;
240 }
241
cfg_nvs_ops(struct wl12xx_common * cmn)242 void cfg_nvs_ops(struct wl12xx_common *cmn)
243 {
244 if (cmn->arch == WL1271_ARCH) {
245 cmn->nvs_ops = &wl1271_nvs_ops;
246 } else {
247 cmn->nvs_ops = &wl128x_nvs_ops;
248 }
249 }
250
read_from_current_nvs(const char * nvs_file,char * buf,int size,int * nvs_sz)251 static int read_from_current_nvs(const char *nvs_file,
252 char *buf, int size, int *nvs_sz)
253 {
254 int curr_nvs, ret;
255
256 curr_nvs = open(nvs_file, O_RDONLY, S_IRUSR | S_IWUSR);
257 if (curr_nvs < 0) {
258 fprintf(stderr, "%s> Unable to open NVS file for reference "
259 "(%s)\n", __func__, strerror(errno));
260 return 1;
261 }
262
263 ret = read(curr_nvs, buf, size);
264 if (ret < 0) {
265 fprintf(stderr, "Fail to read file %s (%s)", nvs_file,
266 strerror(errno));
267 close(curr_nvs);
268 return 1;
269 }
270
271 if (nvs_sz) {
272 *nvs_sz = ret;
273 }
274
275 close(curr_nvs);
276
277 //printf("Read NVS file (%s) of size %d\n", nvs_file, ret);
278
279 return 0;
280 }
281
read_nvs(const char * nvs_file,char * buf,int size,int * nvs_sz)282 static int read_nvs(const char *nvs_file, char *buf,
283 int size, int *nvs_sz)
284 {
285 int fl_sz;
286 char file2read[FILENAME_MAX];
287
288 if (nvs_file == NULL || strlen(nvs_file) < 2) {
289 printf("\nThe path to NVS file not provided, "
290 "use default (%s)\n", CURRENT_NVS_NAME);
291
292 strncpy(file2read, CURRENT_NVS_NAME, strlen(CURRENT_NVS_NAME));
293
294 } else
295 strncpy(file2read, nvs_file, strlen(nvs_file));
296
297 fl_sz = file_exist(file2read);
298 if (fl_sz < 0) {
299 fprintf(stderr, "File %s not exists\n", CURRENT_NVS_NAME);
300 return 1;
301 }
302
303 return read_from_current_nvs(file2read, buf, size, nvs_sz);
304 }
305
fill_nvs_def_rx_params(int fd)306 static int fill_nvs_def_rx_params(int fd)
307 {
308 unsigned char type = eNVS_RADIO_RX_PARAMETERS;
309 unsigned short length = NVS_RX_PARAM_LENGTH;
310 int i;
311
312 /* Rx type */
313 write(fd, &type, 1);
314
315 /* Rx length */
316 write(fd, &length, 2);
317
318 type = DEFAULT_EFUSE_VALUE; /* just reuse of var */
319 for (i = 0; i < NVS_RX_PARAM_LENGTH; i++) {
320 write(fd, &type, 1);
321 }
322
323 return 0;
324 }
325
nvs_parse_data(const unsigned char * buf,struct wl1271_cmd_cal_p2g * pdata,unsigned int * pver)326 static void nvs_parse_data(const unsigned char *buf,
327 struct wl1271_cmd_cal_p2g *pdata, unsigned int *pver)
328 {
329 #define BUFFER_INDEX (buf_idx + START_PARAM_INDEX + info_idx)
330 unsigned short buf_idx;
331 unsigned char tlv_type;
332 unsigned short tlv_len;
333 unsigned short info_idx;
334 unsigned int nvsTypeInfo;
335 unsigned char nvs_ver_oct_idx;
336 unsigned char shift;
337
338 for (buf_idx = 0; buf_idx < NVS_TOTAL_LENGTH;) {
339 tlv_type = buf[buf_idx];
340
341 /* fill the correct mode to fill the NVS struct buffer */
342 /* if the tlv_type is the last type break from the loop */
343 switch (tlv_type) {
344 case eNVS_RADIO_TX_PARAMETERS:
345 nvsTypeInfo = eNVS_RADIO_TX_TYPE_PARAMETERS_INFO;
346 break;
347 case eNVS_RADIO_RX_PARAMETERS:
348 nvsTypeInfo = eNVS_RADIO_RX_TYPE_PARAMETERS_INFO;
349 break;
350 case eNVS_VERSION:
351 for (*pver = 0, nvs_ver_oct_idx = 0;
352 nvs_ver_oct_idx < NVS_VERSION_PARAMETER_LENGTH;
353 nvs_ver_oct_idx++) {
354 shift = 8 * (NVS_VERSION_PARAMETER_LENGTH -
355 1 - nvs_ver_oct_idx);
356 *pver += ((buf[buf_idx + START_PARAM_INDEX +
357 nvs_ver_oct_idx]) << shift);
358 }
359 break;
360 case eTLV_LAST:
361 default:
362 return;
363 }
364
365 tlv_len = (buf[buf_idx + START_LENGTH_INDEX + 1] << 8) +
366 buf[buf_idx + START_LENGTH_INDEX];
367
368 /* if TLV type is not NVS ver fill the NVS according */
369 /* to the mode TX/RX */
370 if ((eNVS_RADIO_TX_PARAMETERS == tlv_type) ||
371 (eNVS_RADIO_RX_PARAMETERS == tlv_type)) {
372 pdata[nvsTypeInfo].type = tlv_type;
373 pdata[nvsTypeInfo].len = tlv_len;
374
375 for (info_idx = 0; (info_idx < tlv_len) &&
376 (BUFFER_INDEX < NVS_TOTAL_LENGTH);
377 info_idx++) {
378 pdata[nvsTypeInfo].buf[info_idx] =
379 buf[BUFFER_INDEX];
380 }
381 }
382
383 /* increment to the next TLV */
384 buf_idx += START_PARAM_INDEX + tlv_len;
385 }
386 }
387
nvs_fill_version(int fd,unsigned int * pdata)388 static int nvs_fill_version(int fd, unsigned int *pdata)
389 {
390 unsigned char tmp = eNVS_VERSION;
391 unsigned short tmp2 = NVS_VERSION_PARAMETER_LENGTH;
392
393 write(fd, &tmp, 1);
394
395 write(fd, &tmp2, 2);
396
397 tmp = (*pdata >> 16) & 0xff;
398 write(fd, &tmp, 1);
399
400 tmp = (*pdata >> 8) & 0xff;
401 write(fd, &tmp, 1);
402
403 tmp = *pdata & 0xff;
404 write(fd, &tmp, 1);
405
406 return 0;
407 }
408
nvs_fill_old_rx_data(int fd,const unsigned char * buf,unsigned short len)409 static int nvs_fill_old_rx_data(int fd, const unsigned char *buf,
410 unsigned short len)
411 {
412 unsigned short idx;
413 unsigned char rx_type;
414
415 /* RX BiP type */
416 rx_type = eNVS_RADIO_RX_PARAMETERS;
417 write(fd, &rx_type, 1);
418
419 /* RX BIP Length */
420 write(fd, &len, 2);
421
422 for (idx = 0; idx < len; idx++) {
423 write(fd, &(buf[idx]), 1);
424 }
425
426 return 0;
427 }
428
nvs_upd_nvs_part(int fd,char * buf)429 static int nvs_upd_nvs_part(int fd, char *buf)
430 {
431 char *p = buf;
432
433 write(fd, p, 0x1D4);
434
435 return 0;
436 }
437
nvs_fill_nvs_part(int fd)438 static int nvs_fill_nvs_part(int fd)
439 {
440 int i;
441 unsigned char mac_addr[MAC_ADDR_LEN] = {
442 0x0b, 0xad, 0xde, 0xad, 0xbe, 0xef
443 };
444 __le16 nvs_tx_sz = NVS_TX_PARAM_LENGTH;
445 __le32 nvs_ver = 0x0;
446 const unsigned char vals[] = {
447 0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS
448 };
449
450 write(fd, &vals[1], 1);
451 write(fd, &vals[2], 1);
452 write(fd, &vals[3], 1);
453 #if 0
454 if (get_mac_addr(0, mac_addr)) {
455 fprintf(stderr, "%s> Fail to get mac address\n", __func__);
456 return 1;
457 }
458 #endif
459 /* write down MAC address in new NVS file */
460 write(fd, &mac_addr[5], 1);
461 write(fd, &mac_addr[4], 1);
462 write(fd, &mac_addr[3], 1);
463 write(fd, &mac_addr[2], 1);
464
465 write(fd, &vals[1], 1);
466 write(fd, &vals[4], 1);
467 write(fd, &vals[3], 1);
468
469 write(fd, &mac_addr[1], 1);
470 write(fd, &mac_addr[0], 1);
471
472 write(fd, &vals[0], 1);
473 write(fd, &vals[0], 1);
474
475 /* fill end burst transaction zeros */
476 for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) {
477 write(fd, &vals[0], 1);
478 }
479
480 /* fill zeros to Align TLV start address */
481 for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) {
482 write(fd, &vals[0], 1);
483 }
484
485 /* Fill Tx calibration part */
486 write(fd, &vals[6], 1);
487 write(fd, &nvs_tx_sz, 2);
488
489 for (i = 0; i < nvs_tx_sz; i++) {
490 write(fd, &vals[0], 1);
491 }
492
493 /* Fill Rx calibration part */
494 fill_nvs_def_rx_params(fd);
495
496 /* fill NVS version */
497 if (nvs_fill_version(fd, &nvs_ver)) {
498 fprintf(stderr, "Fail to fill version\n");
499 }
500
501 /* fill end of NVS */
502 write(fd, &vals[5], 1); /* eTLV_LAST */
503 write(fd, &vals[5], 1); /* eTLV_LAST */
504 write(fd, &vals[0], 1);
505 write(fd, &vals[0], 1);
506
507 return 0;
508 }
509
prepare_nvs_file(void * arg,char * file_name)510 int prepare_nvs_file(void *arg, char *file_name)
511 {
512 int new_nvs, i, nvs_size;
513 unsigned char mac_addr[MAC_ADDR_LEN];
514 struct wl1271_cmd_cal_p2g *pdata;
515 struct wl1271_cmd_cal_p2g old_data[eNUMBER_RADIO_TYPE_PARAMETERS_INFO];
516 char buf[2048];
517 unsigned char *p;
518 struct wl12xx_common cmn = {
519 .arch = UNKNOWN_ARCH,
520 .parse_ops = NULL
521 };
522
523 const unsigned char vals[] = {
524 0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS
525 };
526
527 if (arg == NULL) {
528 fprintf(stderr, "%s> Missing args\n", __func__);
529 return 1;
530 }
531
532 if (read_nvs(file_name, buf, BUF_SIZE_4_NVS_FILE, &nvs_size)) {
533 return 1;
534 }
535
536 switch (nvs_size) {
537 case NVS_FILE_SIZE_127X:
538 cmn.arch = WL1271_ARCH;
539 break;
540 case NVS_FILE_SIZE_128X:
541 cmn.arch = WL128X_ARCH;
542 break;
543 default:
544 fprintf(stderr, "%s> Wrong file size\n", __func__);
545 return 1;
546 }
547
548 cfg_nvs_ops(&cmn);
549
550 /* create new NVS file */
551 new_nvs = open(NEW_NVS_NAME,
552 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
553 if (new_nvs < 0) {
554 fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
555 return 1;
556 }
557
558 write(new_nvs, &vals[1], 1);
559 write(new_nvs, &vals[2], 1);
560 write(new_nvs, &vals[3], 1);
561
562 if (get_mac_addr(0, mac_addr)) {
563 fprintf(stderr, "%s> Fail to get mac addr\n", __func__);
564 close(new_nvs);
565 return 1;
566 }
567
568 /* write down MAC address in new NVS file */
569 write(new_nvs, &mac_addr[5], 1);
570 write(new_nvs, &mac_addr[4], 1);
571 write(new_nvs, &mac_addr[3], 1);
572 write(new_nvs, &mac_addr[2], 1);
573
574 write(new_nvs, &vals[1], 1);
575 write(new_nvs, &vals[4], 1);
576 write(new_nvs, &vals[3], 1);
577
578 write(new_nvs, &mac_addr[1], 1);
579 write(new_nvs, &mac_addr[0], 1);
580
581 write(new_nvs, &vals[0], 1);
582 write(new_nvs, &vals[0], 1);
583
584 /* fill end burst transaction zeros */
585 for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) {
586 write(new_nvs, &vals[0], 1);
587 }
588
589 /* fill zeros to Align TLV start address */
590 for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) {
591 write(new_nvs, &vals[0], 1);
592 }
593
594 /* Fill TxBip */
595 pdata = (struct wl1271_cmd_cal_p2g *)arg;
596
597 write(new_nvs, &vals[6], 1);
598 write(new_nvs, &pdata->len, 2);
599
600 p = (unsigned char *)&(pdata->buf);
601 for (i = 0; i < pdata->len; i++) {
602 write(new_nvs, p++, 1);
603 }
604
605 {
606 unsigned int old_ver;
607 #if 0
608 {
609 unsigned char *p = (unsigned char *)buf;
610 for (old_ver = 0; old_ver < 1024; old_ver++) {
611 if (old_ver%16 == 0)
612 printf("\n");
613 printf("%02x ", *p++);
614 }
615 }
616 #endif
617 memset(old_data, 0,
618 sizeof(struct wl1271_cmd_cal_p2g)*
619 eNUMBER_RADIO_TYPE_PARAMETERS_INFO);
620 nvs_parse_data((const unsigned char *)&buf[NVS_PRE_PARAMETERS_LENGTH],
621 old_data, &old_ver);
622
623 nvs_fill_old_rx_data(new_nvs,
624 old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].buf,
625 old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].len);
626 }
627
628 /* fill NVS version */
629 if (nvs_fill_version(new_nvs, &pdata->ver)) {
630 fprintf(stderr, "Fail to fill version\n");
631 }
632
633 /* fill end of NVS */
634 write(new_nvs, &vals[5], 1); /* eTLV_LAST */
635 write(new_nvs, &vals[5], 1); /* eTLV_LAST */
636 write(new_nvs, &vals[0], 1);
637 write(new_nvs, &vals[0], 1);
638
639 /* fill radio params */
640 if (cmn.nvs_ops->nvs_fill_radio_prms(new_nvs, NULL, buf)) {
641 fprintf(stderr, "Fail to fill radio params\n");
642 }
643
644 close(new_nvs);
645
646 return 0;
647 }
648
create_nvs_file(struct wl12xx_common * cmn)649 int create_nvs_file(struct wl12xx_common *cmn)
650 {
651 int new_nvs, res = 0;
652 char buf[2048];
653
654 /* create new NVS file */
655 new_nvs = open(NEW_NVS_NAME,
656 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
657 if (new_nvs < 0) {
658 fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
659 return 1;
660 }
661
662 /* fill nvs part */
663 if (nvs_fill_nvs_part(new_nvs)) {
664 fprintf(stderr, "Fail to fill NVS part\n");
665 res = 1;
666
667 goto out;
668 }
669
670 /* fill radio params */
671 if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) {
672 fprintf(stderr, "Fail to fill radio params\n");
673 res = 1;
674 }
675
676 out:
677 close(new_nvs);
678
679 return res;
680 }
681
update_nvs_file(const char * nvs_file,struct wl12xx_common * cmn)682 int update_nvs_file(const char *nvs_file, struct wl12xx_common *cmn)
683 {
684 int new_nvs, res = 0;
685 char buf[2048];
686
687 res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, NULL);
688 if (res) {
689 return 1;
690 }
691
692 /* create new NVS file */
693 new_nvs = open(NEW_NVS_NAME,
694 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
695 if (new_nvs < 0) {
696 fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
697 return 1;
698 }
699
700 /* fill nvs part */
701 if (nvs_upd_nvs_part(new_nvs, buf)) {
702 fprintf(stderr, "Fail to fill NVS part\n");
703 res = 1;
704
705 goto out;
706 }
707
708 /* fill radio params */
709 if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) {
710 printf("Fail to fill radio params\n");
711 res = 1;
712 }
713
714 out:
715 close(new_nvs);
716
717 return res;
718 }
719
dump_nvs_file(const char * nvs_file,struct wl12xx_common * cmn)720 int dump_nvs_file(const char *nvs_file, struct wl12xx_common *cmn)
721 {
722 int sz=0, size;
723 char buf[2048];
724 unsigned char *p = (unsigned char *)buf;
725
726 if (read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &size)) {
727 return 1;
728 }
729
730 printf("\nThe size is %d bytes\n", size);
731
732 for ( ; sz < size; sz++) {
733 if (sz%16 == 0) {
734 printf("\n %04X ", sz);
735 }
736 printf("%02x ", *p++);
737 }
738 printf("\n");
739
740 return 0;
741 }
742
set_nvs_file_autofem(const char * nvs_file,unsigned char val,struct wl12xx_common * cmn)743 int set_nvs_file_autofem(const char *nvs_file, unsigned char val,
744 struct wl12xx_common *cmn)
745 {
746 int new_nvs, res = 0;
747 char buf[2048];
748 int nvs_file_sz;
749
750 res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz);
751 if (res) {
752 return 1;
753 }
754
755 if (nvs_get_arch(nvs_file_sz, cmn)) {
756 fprintf(stderr, "Fail to define architecture\n");
757 return 1;
758 }
759
760 cfg_nvs_ops(cmn);
761
762 /* create new NVS file */
763 new_nvs = open(NEW_NVS_NAME,
764 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
765 if (new_nvs < 0) {
766 fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
767 return 1;
768 }
769
770 /* fill nvs part */
771 if (nvs_upd_nvs_part(new_nvs, buf)) {
772 fprintf(stderr, "Fail to fill NVS part\n");
773 res = 1;
774
775 goto out;
776 }
777
778 /* fill radio params */
779 if (cmn->nvs_ops->nvs_set_autofem(new_nvs, buf, val)) {
780 printf("Fail to fill radio params\n");
781 res = 1;
782 }
783
784 out:
785 close(new_nvs);
786
787 return res;
788 }
789
set_nvs_file_fem_manuf(const char * nvs_file,unsigned char val,struct wl12xx_common * cmn)790 int set_nvs_file_fem_manuf(const char *nvs_file, unsigned char val,
791 struct wl12xx_common *cmn)
792 {
793 int new_nvs, res = 0;
794 char buf[2048];
795 int nvs_file_sz;
796
797 res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz);
798 if (res) {
799 return 1;
800 }
801
802 if (nvs_get_arch(nvs_file_sz, cmn)) {
803 fprintf(stderr, "Fail to define architecture\n");
804 return 1;
805 }
806
807 cfg_nvs_ops(cmn);
808
809 /* create new NVS file */
810 new_nvs = open(NEW_NVS_NAME,
811 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
812 if (new_nvs < 0) {
813 fprintf(stderr, "%s> Unable to open new NVS file\n", __func__);
814 return 1;
815 }
816
817 /* fill nvs part */
818 if (nvs_upd_nvs_part(new_nvs, buf)) {
819 fprintf(stderr, "Fail to fill NVS part\n");
820 res = 1;
821
822 goto out;
823 }
824
825 /* fill radio params */
826 if (cmn->nvs_ops->nvs_set_fem_manuf(new_nvs, buf, val)) {
827 printf("Fail to fill radio params\n");
828 res = 1;
829 }
830
831 out:
832 close(new_nvs);
833
834 return res;
835 }
836
837