• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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