| /* |
| * PLT utility for wireless chip supported by TI's driver wl12xx |
| * |
| * See README and COPYING for more details. |
| */ |
| |
| #include <sys/ioctl.h> |
| #include <errno.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdbool.h> |
| #include <netinet/in.h> |
| |
| #include <netlink/netlink.h> |
| #include <netlink/msg.h> |
| #include <netlink/attr.h> |
| #include <linux/wireless.h> |
| #include "nl80211.h" |
| |
| #include "calibrator.h" |
| #include "plt.h" |
| #include "ini.h" |
| /* 2048 - it should be enough for any chip, until... 22dec2010 */ |
| #define BUF_SIZE_4_NVS_FILE 2048 |
| |
| static const char if_name_fmt[] = "wlan%d"; |
| |
| int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) |
| { |
| int size; |
| struct wl1271_ini *gp; |
| |
| if (ini) { |
| gp = &ini->ini1271; |
| } |
| |
| size = sizeof(struct wl1271_ini); |
| |
| if (ini) { /* for reference NVS */ |
| unsigned char *c = (unsigned char *)gp; |
| int i; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| } else { |
| char *p = buf + 0x1D4; |
| write(fd, (const void *)p, size); |
| } |
| |
| return 0; |
| } |
| |
| static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf) |
| { |
| int size; |
| struct wl128x_ini *gp = &ini->ini128x; |
| |
| size = sizeof(struct wl128x_ini); |
| |
| if (ini) { /* for reference NVS */ |
| unsigned char *c = (unsigned char *)gp; |
| int i; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| |
| } else { |
| char *p = buf + 0x1D4; |
| write(fd, p, size); |
| } |
| |
| return 0; |
| } |
| |
| int nvs_set_autofem(int fd, char *buf, unsigned char val) |
| { |
| int size; |
| struct wl1271_ini *gp; |
| unsigned char *c; |
| int i; |
| |
| if (buf == NULL) { |
| return 1; |
| } |
| |
| gp = (struct wl1271_ini *)(buf+0x1d4); |
| gp->general_params.tx_bip_fem_auto_detect = val; |
| |
| size = sizeof(struct wl1271_ini); |
| |
| c = (unsigned char *)gp; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| |
| return 0; |
| } |
| |
| int nvs_set_autofem_128x(int fd, char *buf, unsigned char val) |
| { |
| int size; |
| struct wl128x_ini *gp; |
| unsigned char *c; |
| int i; |
| |
| if (buf == NULL) { |
| return 1; |
| } |
| |
| gp = (struct wl128x_ini *)(buf+0x1d4); |
| gp->general_params.tx_bip_fem_auto_detect = val; |
| |
| size = sizeof(struct wl128x_ini); |
| |
| c = (unsigned char *)gp; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| |
| return 0; |
| } |
| |
| int nvs_set_fem_manuf(int fd, char *buf, unsigned char val) |
| { |
| int size; |
| struct wl1271_ini *gp; |
| unsigned char *c; |
| int i; |
| |
| if (buf == NULL) { |
| return 1; |
| } |
| |
| gp = (struct wl1271_ini *)(buf+0x1d4); |
| gp->general_params.tx_bip_fem_manufacturer = val; |
| |
| size = sizeof(struct wl1271_ini); |
| |
| c = (unsigned char *)gp; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| |
| return 0; |
| } |
| |
| int nvs_set_fem_manuf_128x(int fd, char *buf, unsigned char val) |
| { |
| int size; |
| struct wl128x_ini *gp; |
| unsigned char *c; |
| int i; |
| |
| if (buf == NULL) { |
| return 1; |
| } |
| |
| gp = (struct wl128x_ini *)(buf+0x1d4); |
| gp->general_params.tx_bip_fem_manufacturer = val; |
| |
| size = sizeof(struct wl128x_ini); |
| |
| c = (unsigned char *)gp; |
| |
| for (i = 0; i < size; i++) { |
| write(fd, c++, 1); |
| } |
| |
| return 0; |
| } |
| |
| static struct wl12xx_nvs_ops wl1271_nvs_ops = { |
| .nvs_fill_radio_prms = nvs_fill_radio_params, |
| .nvs_set_autofem = nvs_set_autofem, |
| .nvs_set_fem_manuf = nvs_set_fem_manuf, |
| }; |
| |
| static struct wl12xx_nvs_ops wl128x_nvs_ops = { |
| .nvs_fill_radio_prms = nvs_fill_radio_params_128x, |
| .nvs_set_autofem = nvs_set_autofem_128x, |
| .nvs_set_fem_manuf = nvs_set_fem_manuf_128x, |
| }; |
| |
| int get_mac_addr(int ifc_num, unsigned char *mac_addr) |
| { |
| int s; |
| struct ifreq ifr; |
| #if 0 |
| if (ifc_num < 0 || ifc_num >= ETH_DEV_MAX) |
| return 1; |
| #endif |
| s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); |
| if (s < 0) { |
| fprintf(stderr, "unable to socket (%s)\n", strerror(errno)); |
| return 1; |
| } |
| |
| memset(&ifr, 0, sizeof(struct ifreq)); |
| sprintf(ifr.ifr_name, if_name_fmt, ifc_num) ; |
| if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { |
| fprintf(stderr, "unable to ioctl (%s)\n", strerror(errno)); |
| close(s); |
| return 1; |
| } |
| |
| close(s); |
| |
| memcpy(mac_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data[0], 6); |
| |
| return 0; |
| } |
| |
| int file_exist(const char *filename) |
| { |
| struct stat buf; |
| int ret; |
| |
| if (filename == NULL) { |
| fprintf(stderr, "wrong parameter\n"); |
| return -1; |
| } |
| |
| ret = stat(filename, &buf); |
| if (ret != 0) { |
| fprintf(stderr, "fail to stat file %s (%s)\n", filename, |
| strerror(errno)); |
| return -1; |
| } |
| |
| return (int)buf.st_size; |
| } |
| |
| void cfg_nvs_ops(struct wl12xx_common *cmn) |
| { |
| if (cmn->arch == WL1271_ARCH) { |
| cmn->nvs_ops = &wl1271_nvs_ops; |
| } else { |
| cmn->nvs_ops = &wl128x_nvs_ops; |
| } |
| } |
| |
| static int read_from_current_nvs(const char *nvs_file, |
| char *buf, int size, int *nvs_sz) |
| { |
| int curr_nvs, ret; |
| |
| curr_nvs = open(nvs_file, O_RDONLY, S_IRUSR | S_IWUSR); |
| if (curr_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open NVS file for reference " |
| "(%s)\n", __func__, strerror(errno)); |
| return 1; |
| } |
| |
| ret = read(curr_nvs, buf, size); |
| if (ret < 0) { |
| fprintf(stderr, "Fail to read file %s (%s)", nvs_file, |
| strerror(errno)); |
| close(curr_nvs); |
| return 1; |
| } |
| |
| if (nvs_sz) { |
| *nvs_sz = ret; |
| } |
| |
| close(curr_nvs); |
| |
| //printf("Read NVS file (%s) of size %d\n", nvs_file, ret); |
| |
| return 0; |
| } |
| |
| static int read_nvs(const char *nvs_file, char *buf, |
| int size, int *nvs_sz) |
| { |
| int fl_sz; |
| char file2read[FILENAME_MAX]; |
| |
| if (nvs_file == NULL || strlen(nvs_file) < 2) { |
| printf("\nThe path to NVS file not provided, " |
| "use default (%s)\n", CURRENT_NVS_NAME); |
| |
| strncpy(file2read, CURRENT_NVS_NAME, strlen(CURRENT_NVS_NAME)); |
| |
| } else |
| strncpy(file2read, nvs_file, strlen(nvs_file)); |
| |
| fl_sz = file_exist(file2read); |
| if (fl_sz < 0) { |
| fprintf(stderr, "File %s not exists\n", CURRENT_NVS_NAME); |
| return 1; |
| } |
| |
| return read_from_current_nvs(file2read, buf, size, nvs_sz); |
| } |
| |
| static int fill_nvs_def_rx_params(int fd) |
| { |
| unsigned char type = eNVS_RADIO_RX_PARAMETERS; |
| unsigned short length = NVS_RX_PARAM_LENGTH; |
| int i; |
| |
| /* Rx type */ |
| write(fd, &type, 1); |
| |
| /* Rx length */ |
| write(fd, &length, 2); |
| |
| type = DEFAULT_EFUSE_VALUE; /* just reuse of var */ |
| for (i = 0; i < NVS_RX_PARAM_LENGTH; i++) { |
| write(fd, &type, 1); |
| } |
| |
| return 0; |
| } |
| |
| static void nvs_parse_data(const unsigned char *buf, |
| struct wl1271_cmd_cal_p2g *pdata, unsigned int *pver) |
| { |
| #define BUFFER_INDEX (buf_idx + START_PARAM_INDEX + info_idx) |
| unsigned short buf_idx; |
| unsigned char tlv_type; |
| unsigned short tlv_len; |
| unsigned short info_idx; |
| unsigned int nvsTypeInfo; |
| unsigned char nvs_ver_oct_idx; |
| unsigned char shift; |
| |
| for (buf_idx = 0; buf_idx < NVS_TOTAL_LENGTH;) { |
| tlv_type = buf[buf_idx]; |
| |
| /* fill the correct mode to fill the NVS struct buffer */ |
| /* if the tlv_type is the last type break from the loop */ |
| switch (tlv_type) { |
| case eNVS_RADIO_TX_PARAMETERS: |
| nvsTypeInfo = eNVS_RADIO_TX_TYPE_PARAMETERS_INFO; |
| break; |
| case eNVS_RADIO_RX_PARAMETERS: |
| nvsTypeInfo = eNVS_RADIO_RX_TYPE_PARAMETERS_INFO; |
| break; |
| case eNVS_VERSION: |
| for (*pver = 0, nvs_ver_oct_idx = 0; |
| nvs_ver_oct_idx < NVS_VERSION_PARAMETER_LENGTH; |
| nvs_ver_oct_idx++) { |
| shift = 8 * (NVS_VERSION_PARAMETER_LENGTH - |
| 1 - nvs_ver_oct_idx); |
| *pver += ((buf[buf_idx + START_PARAM_INDEX + |
| nvs_ver_oct_idx]) << shift); |
| } |
| break; |
| case eTLV_LAST: |
| default: |
| return; |
| } |
| |
| tlv_len = (buf[buf_idx + START_LENGTH_INDEX + 1] << 8) + |
| buf[buf_idx + START_LENGTH_INDEX]; |
| |
| /* if TLV type is not NVS ver fill the NVS according */ |
| /* to the mode TX/RX */ |
| if ((eNVS_RADIO_TX_PARAMETERS == tlv_type) || |
| (eNVS_RADIO_RX_PARAMETERS == tlv_type)) { |
| pdata[nvsTypeInfo].type = tlv_type; |
| pdata[nvsTypeInfo].len = tlv_len; |
| |
| for (info_idx = 0; (info_idx < tlv_len) && |
| (BUFFER_INDEX < NVS_TOTAL_LENGTH); |
| info_idx++) { |
| pdata[nvsTypeInfo].buf[info_idx] = |
| buf[BUFFER_INDEX]; |
| } |
| } |
| |
| /* increment to the next TLV */ |
| buf_idx += START_PARAM_INDEX + tlv_len; |
| } |
| } |
| |
| static int nvs_fill_version(int fd, unsigned int *pdata) |
| { |
| unsigned char tmp = eNVS_VERSION; |
| unsigned short tmp2 = NVS_VERSION_PARAMETER_LENGTH; |
| |
| write(fd, &tmp, 1); |
| |
| write(fd, &tmp2, 2); |
| |
| tmp = (*pdata >> 16) & 0xff; |
| write(fd, &tmp, 1); |
| |
| tmp = (*pdata >> 8) & 0xff; |
| write(fd, &tmp, 1); |
| |
| tmp = *pdata & 0xff; |
| write(fd, &tmp, 1); |
| |
| return 0; |
| } |
| |
| static int nvs_fill_old_rx_data(int fd, const unsigned char *buf, |
| unsigned short len) |
| { |
| unsigned short idx; |
| unsigned char rx_type; |
| |
| /* RX BiP type */ |
| rx_type = eNVS_RADIO_RX_PARAMETERS; |
| write(fd, &rx_type, 1); |
| |
| /* RX BIP Length */ |
| write(fd, &len, 2); |
| |
| for (idx = 0; idx < len; idx++) { |
| write(fd, &(buf[idx]), 1); |
| } |
| |
| return 0; |
| } |
| |
| static int nvs_upd_nvs_part(int fd, char *buf) |
| { |
| char *p = buf; |
| |
| write(fd, p, 0x1D4); |
| |
| return 0; |
| } |
| |
| static int nvs_fill_nvs_part(int fd) |
| { |
| int i; |
| unsigned char mac_addr[MAC_ADDR_LEN] = { |
| 0x0b, 0xad, 0xde, 0xad, 0xbe, 0xef |
| }; |
| __le16 nvs_tx_sz = NVS_TX_PARAM_LENGTH; |
| __le32 nvs_ver = 0x0; |
| const unsigned char vals[] = { |
| 0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS |
| }; |
| |
| write(fd, &vals[1], 1); |
| write(fd, &vals[2], 1); |
| write(fd, &vals[3], 1); |
| #if 0 |
| if (get_mac_addr(0, mac_addr)) { |
| fprintf(stderr, "%s> Fail to get mac address\n", __func__); |
| return 1; |
| } |
| #endif |
| /* write down MAC address in new NVS file */ |
| write(fd, &mac_addr[5], 1); |
| write(fd, &mac_addr[4], 1); |
| write(fd, &mac_addr[3], 1); |
| write(fd, &mac_addr[2], 1); |
| |
| write(fd, &vals[1], 1); |
| write(fd, &vals[4], 1); |
| write(fd, &vals[3], 1); |
| |
| write(fd, &mac_addr[1], 1); |
| write(fd, &mac_addr[0], 1); |
| |
| write(fd, &vals[0], 1); |
| write(fd, &vals[0], 1); |
| |
| /* fill end burst transaction zeros */ |
| for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) { |
| write(fd, &vals[0], 1); |
| } |
| |
| /* fill zeros to Align TLV start address */ |
| for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) { |
| write(fd, &vals[0], 1); |
| } |
| |
| /* Fill Tx calibration part */ |
| write(fd, &vals[6], 1); |
| write(fd, &nvs_tx_sz, 2); |
| |
| for (i = 0; i < nvs_tx_sz; i++) { |
| write(fd, &vals[0], 1); |
| } |
| |
| /* Fill Rx calibration part */ |
| fill_nvs_def_rx_params(fd); |
| |
| /* fill NVS version */ |
| if (nvs_fill_version(fd, &nvs_ver)) { |
| fprintf(stderr, "Fail to fill version\n"); |
| } |
| |
| /* fill end of NVS */ |
| write(fd, &vals[5], 1); /* eTLV_LAST */ |
| write(fd, &vals[5], 1); /* eTLV_LAST */ |
| write(fd, &vals[0], 1); |
| write(fd, &vals[0], 1); |
| |
| return 0; |
| } |
| |
| int prepare_nvs_file(void *arg, char *file_name) |
| { |
| int new_nvs, i, nvs_size; |
| unsigned char mac_addr[MAC_ADDR_LEN]; |
| struct wl1271_cmd_cal_p2g *pdata; |
| struct wl1271_cmd_cal_p2g old_data[eNUMBER_RADIO_TYPE_PARAMETERS_INFO]; |
| char buf[2048]; |
| unsigned char *p; |
| struct wl12xx_common cmn = { |
| .arch = UNKNOWN_ARCH, |
| .parse_ops = NULL |
| }; |
| |
| const unsigned char vals[] = { |
| 0x0, 0x1, 0x6d, 0x54, 0x71, eTLV_LAST, eNVS_RADIO_TX_PARAMETERS |
| }; |
| |
| if (arg == NULL) { |
| fprintf(stderr, "%s> Missing args\n", __func__); |
| return 1; |
| } |
| |
| if (read_nvs(file_name, buf, BUF_SIZE_4_NVS_FILE, &nvs_size)) { |
| return 1; |
| } |
| |
| switch (nvs_size) { |
| case NVS_FILE_SIZE_127X: |
| cmn.arch = WL1271_ARCH; |
| break; |
| case NVS_FILE_SIZE_128X: |
| cmn.arch = WL128X_ARCH; |
| break; |
| default: |
| fprintf(stderr, "%s> Wrong file size\n", __func__); |
| return 1; |
| } |
| |
| cfg_nvs_ops(&cmn); |
| |
| /* create new NVS file */ |
| new_nvs = open(NEW_NVS_NAME, |
| O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| if (new_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open new NVS file\n", __func__); |
| return 1; |
| } |
| |
| write(new_nvs, &vals[1], 1); |
| write(new_nvs, &vals[2], 1); |
| write(new_nvs, &vals[3], 1); |
| |
| if (get_mac_addr(0, mac_addr)) { |
| fprintf(stderr, "%s> Fail to get mac addr\n", __func__); |
| close(new_nvs); |
| return 1; |
| } |
| |
| /* write down MAC address in new NVS file */ |
| write(new_nvs, &mac_addr[5], 1); |
| write(new_nvs, &mac_addr[4], 1); |
| write(new_nvs, &mac_addr[3], 1); |
| write(new_nvs, &mac_addr[2], 1); |
| |
| write(new_nvs, &vals[1], 1); |
| write(new_nvs, &vals[4], 1); |
| write(new_nvs, &vals[3], 1); |
| |
| write(new_nvs, &mac_addr[1], 1); |
| write(new_nvs, &mac_addr[0], 1); |
| |
| write(new_nvs, &vals[0], 1); |
| write(new_nvs, &vals[0], 1); |
| |
| /* fill end burst transaction zeros */ |
| for (i = 0; i < NVS_END_BURST_TRANSACTION_LENGTH; i++) { |
| write(new_nvs, &vals[0], 1); |
| } |
| |
| /* fill zeros to Align TLV start address */ |
| for (i = 0; i < NVS_ALING_TLV_START_ADDRESS_LENGTH; i++) { |
| write(new_nvs, &vals[0], 1); |
| } |
| |
| /* Fill TxBip */ |
| pdata = (struct wl1271_cmd_cal_p2g *)arg; |
| |
| write(new_nvs, &vals[6], 1); |
| write(new_nvs, &pdata->len, 2); |
| |
| p = (unsigned char *)&(pdata->buf); |
| for (i = 0; i < pdata->len; i++) { |
| write(new_nvs, p++, 1); |
| } |
| |
| { |
| unsigned int old_ver; |
| #if 0 |
| { |
| unsigned char *p = (unsigned char *)buf; |
| for (old_ver = 0; old_ver < 1024; old_ver++) { |
| if (old_ver%16 == 0) |
| printf("\n"); |
| printf("%02x ", *p++); |
| } |
| } |
| #endif |
| memset(old_data, 0, |
| sizeof(struct wl1271_cmd_cal_p2g)* |
| eNUMBER_RADIO_TYPE_PARAMETERS_INFO); |
| nvs_parse_data((const unsigned char *)&buf[NVS_PRE_PARAMETERS_LENGTH], |
| old_data, &old_ver); |
| |
| nvs_fill_old_rx_data(new_nvs, |
| old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].buf, |
| old_data[eNVS_RADIO_RX_TYPE_PARAMETERS_INFO].len); |
| } |
| |
| /* fill NVS version */ |
| if (nvs_fill_version(new_nvs, &pdata->ver)) { |
| fprintf(stderr, "Fail to fill version\n"); |
| } |
| |
| /* fill end of NVS */ |
| write(new_nvs, &vals[5], 1); /* eTLV_LAST */ |
| write(new_nvs, &vals[5], 1); /* eTLV_LAST */ |
| write(new_nvs, &vals[0], 1); |
| write(new_nvs, &vals[0], 1); |
| |
| /* fill radio params */ |
| if (cmn.nvs_ops->nvs_fill_radio_prms(new_nvs, NULL, buf)) { |
| fprintf(stderr, "Fail to fill radio params\n"); |
| } |
| |
| close(new_nvs); |
| |
| return 0; |
| } |
| |
| int create_nvs_file(struct wl12xx_common *cmn) |
| { |
| int new_nvs, res = 0; |
| char buf[2048]; |
| |
| /* create new NVS file */ |
| new_nvs = open(NEW_NVS_NAME, |
| O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| if (new_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open new NVS file\n", __func__); |
| return 1; |
| } |
| |
| /* fill nvs part */ |
| if (nvs_fill_nvs_part(new_nvs)) { |
| fprintf(stderr, "Fail to fill NVS part\n"); |
| res = 1; |
| |
| goto out; |
| } |
| |
| /* fill radio params */ |
| if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) { |
| fprintf(stderr, "Fail to fill radio params\n"); |
| res = 1; |
| } |
| |
| out: |
| close(new_nvs); |
| |
| return res; |
| } |
| |
| int update_nvs_file(const char *nvs_file, struct wl12xx_common *cmn) |
| { |
| int new_nvs, res = 0; |
| char buf[2048]; |
| |
| res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, NULL); |
| if (res) { |
| return 1; |
| } |
| |
| /* create new NVS file */ |
| new_nvs = open(NEW_NVS_NAME, |
| O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| if (new_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open new NVS file\n", __func__); |
| return 1; |
| } |
| |
| /* fill nvs part */ |
| if (nvs_upd_nvs_part(new_nvs, buf)) { |
| fprintf(stderr, "Fail to fill NVS part\n"); |
| res = 1; |
| |
| goto out; |
| } |
| |
| /* fill radio params */ |
| if (cmn->nvs_ops->nvs_fill_radio_prms(new_nvs, &cmn->ini, buf)) { |
| printf("Fail to fill radio params\n"); |
| res = 1; |
| } |
| |
| out: |
| close(new_nvs); |
| |
| return res; |
| } |
| |
| int dump_nvs_file(const char *nvs_file, struct wl12xx_common *cmn) |
| { |
| int sz=0, size; |
| char buf[2048]; |
| unsigned char *p = (unsigned char *)buf; |
| |
| if (read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &size)) { |
| return 1; |
| } |
| |
| printf("\nThe size is %d bytes\n", size); |
| |
| for ( ; sz < size; sz++) { |
| if (sz%16 == 0) { |
| printf("\n %04X ", sz); |
| } |
| printf("%02x ", *p++); |
| } |
| printf("\n"); |
| |
| return 0; |
| } |
| |
| int set_nvs_file_autofem(const char *nvs_file, unsigned char val, |
| struct wl12xx_common *cmn) |
| { |
| int new_nvs, res = 0; |
| char buf[2048]; |
| int nvs_file_sz; |
| |
| res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz); |
| if (res) { |
| return 1; |
| } |
| |
| if (nvs_get_arch(nvs_file_sz, cmn)) { |
| fprintf(stderr, "Fail to define architecture\n"); |
| return 1; |
| } |
| |
| cfg_nvs_ops(cmn); |
| |
| /* create new NVS file */ |
| new_nvs = open(NEW_NVS_NAME, |
| O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| if (new_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open new NVS file\n", __func__); |
| return 1; |
| } |
| |
| /* fill nvs part */ |
| if (nvs_upd_nvs_part(new_nvs, buf)) { |
| fprintf(stderr, "Fail to fill NVS part\n"); |
| res = 1; |
| |
| goto out; |
| } |
| |
| /* fill radio params */ |
| if (cmn->nvs_ops->nvs_set_autofem(new_nvs, buf, val)) { |
| printf("Fail to fill radio params\n"); |
| res = 1; |
| } |
| |
| out: |
| close(new_nvs); |
| |
| return res; |
| } |
| |
| int set_nvs_file_fem_manuf(const char *nvs_file, unsigned char val, |
| struct wl12xx_common *cmn) |
| { |
| int new_nvs, res = 0; |
| char buf[2048]; |
| int nvs_file_sz; |
| |
| res = read_nvs(nvs_file, buf, BUF_SIZE_4_NVS_FILE, &nvs_file_sz); |
| if (res) { |
| return 1; |
| } |
| |
| if (nvs_get_arch(nvs_file_sz, cmn)) { |
| fprintf(stderr, "Fail to define architecture\n"); |
| return 1; |
| } |
| |
| cfg_nvs_ops(cmn); |
| |
| /* create new NVS file */ |
| new_nvs = open(NEW_NVS_NAME, |
| O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| if (new_nvs < 0) { |
| fprintf(stderr, "%s> Unable to open new NVS file\n", __func__); |
| return 1; |
| } |
| |
| /* fill nvs part */ |
| if (nvs_upd_nvs_part(new_nvs, buf)) { |
| fprintf(stderr, "Fail to fill NVS part\n"); |
| res = 1; |
| |
| goto out; |
| } |
| |
| /* fill radio params */ |
| if (cmn->nvs_ops->nvs_set_fem_manuf(new_nvs, buf, val)) { |
| printf("Fail to fill radio params\n"); |
| res = 1; |
| } |
| |
| out: |
| close(new_nvs); |
| |
| return res; |
| } |
| |