diff options
Diffstat (limited to 'mac80211/ti-utils/misc_cmds.c')
-rw-r--r-- | mac80211/ti-utils/misc_cmds.c | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/mac80211/ti-utils/misc_cmds.c b/mac80211/ti-utils/misc_cmds.c new file mode 100644 index 00000000..ac2ebc65 --- /dev/null +++ b/mac80211/ti-utils/misc_cmds.c @@ -0,0 +1,442 @@ +#include <stdbool.h> +#include <errno.h> +#include <time.h> +#include <net/if.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include "calibrator.h" +#include "plt.h" +#include "ini.h" +#include "nvs.h" + +SECTION(get); +SECTION(set); + +static int handle_push_nvs(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + void *map = MAP_FAILED; + int fd, retval = 0; + struct nlattr *key; + struct stat filestat; + + if (argc != 1) { + return 1; + } + + fd = open(argv[0], O_RDONLY); + if (fd < 0) { + perror("Error opening file for reading"); + return 1; + } + + if (fstat(fd, &filestat) < 0) { + perror("Error stating file"); + return 1; + } + + map = mmap(0, filestat.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + perror("Error mmapping the file"); + goto nla_put_failure; + } + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + goto nla_put_failure; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, filestat.st_size, map); + + nla_nest_end(msg, key); + + goto cleanup; + +nla_put_failure: + retval = -ENOBUFS; + +cleanup: + if (map != MAP_FAILED) { + munmap(map, filestat.st_size); + } + + close(fd); + + return retval; +} + +COMMAND(set, push_nvs, "<nvs filename>", + NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_push_nvs, + "Push NVS file into the system"); + +#if 0 +static int handle_fetch_nvs(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + void *map = MAP_FAILED; + int fd, retval = 0; + struct nlattr *key; + struct stat filestat; + + if (argc != 0) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) + goto nla_put_failure; + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_NVS_PUSH); + NLA_PUT_U32(msg, WL1271_TM_ATTR_IE_ID, WL1271_TM_CMD_NVS_PUSH); + + nla_nest_end(msg, key); + + goto cleanup; + +nla_put_failure: + retval = -ENOBUFS; + +cleanup: + if (map != MAP_FAILED) + munmap(map, filestat.st_size); + + close(fd); + + return retval; +} + +COMMAND(set, fetch_nvs, NULL, + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_fetch_nvs, + "Send command to fetch NVS file"); +#endif +static int get_nvs_mac(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + unsigned char mac_buff[12]; + int fd; + + argc -= 2; + argv += 2; + + if (argc != 1) { + return 2; + } + + fd = open(argv[0], O_RDONLY); + if (fd < 0) { + perror("Error opening file for reading"); + return 1; + } + + read(fd, mac_buff, 12); + + printf("MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac_buff[11], mac_buff[10], mac_buff[6], + mac_buff[5], mac_buff[4], mac_buff[3]); + + close(fd); + + return 0; +} + +COMMAND(get, nvs_mac, "<nvs filename>", 0, 0, CIB_NONE, get_nvs_mac, + "Get MAC addr from NVS file (offline)"); + +/* + * Sets MAC address in NVS. + * The default value for MAC is random where 1 byte zero. + */ +static int set_nvs_mac(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + unsigned char mac_buff[12]; + unsigned char in_mac[6]; + int fd; + + argc -= 2; + argv += 2; + + if (argc < 1 || (argc == 2 && (strlen(argv[1]) != 17))) { + return 2; + } + + if (argc == 2) { + sscanf(argv[1], "%2x:%2x:%2x:%2x:%2x:%2x", + (unsigned int *)&in_mac[0], (unsigned int *)&in_mac[1], + (unsigned int *)&in_mac[2], (unsigned int *)&in_mac[3], + (unsigned int *)&in_mac[4], (unsigned int *)&in_mac[5]); + } else { + srand((unsigned)time(NULL)); + + in_mac[0] = 0x0; + in_mac[1] = rand()%256; + in_mac[2] = rand()%256; + in_mac[3] = rand()%256; + in_mac[4] = rand()%256; + in_mac[5] = rand()%256; + } + + fd = open(argv[0], O_RDWR); + if (fd < 0) { + perror("Error opening file for reading"); + return 1; + } + + read(fd, mac_buff, 12); +#if 0 + printf("Got MAC addr for NVS: %02x:%02x:%02x:%02x:%02x:%02x\n", + in_mac[0], in_mac[1], in_mac[2], + in_mac[3], in_mac[4], in_mac[5]); + + printf("Got MAC addr from NVS: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac_buff[11], mac_buff[10], mac_buff[6], + mac_buff[5], mac_buff[4], mac_buff[3]); +#endif + mac_buff[11] = in_mac[0]; + mac_buff[10] = in_mac[1]; + mac_buff[6] = in_mac[2]; + mac_buff[5] = in_mac[3]; + mac_buff[4] = in_mac[4]; + mac_buff[3] = in_mac[5]; + + lseek(fd, 0L, 0); + + write(fd, mac_buff, 12); + + close(fd); + + return 0; +} + +COMMAND(set, nvs_mac, "<nvs file> [<mac addr>]", 0, 0, CIB_NONE, set_nvs_mac, + "Set MAC addr in NVS file (offline), like XX:XX:XX:XX:XX:XX"); + +static int set_ref_nvs(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL, + .dual_mode = DUAL_MODE_UNSET, + .done_fem = NO_FEM_PARSED + }; + + argc -= 2; + argv += 2; + + if (argc != 1) { + return 1; + } + + if (read_ini(*argv, &cmn)) { + fprintf(stderr, "Fail to read ini file\n"); + return 1; + } + + cfg_nvs_ops(&cmn); + + if (create_nvs_file(&cmn)) { + fprintf(stderr, "Fail to create reference NVS file\n"); + return 1; + } +#if 0 + printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and " + "reboot the system\n\n", + NEW_NVS_NAME, CURRENT_NVS_NAME); +#endif + return 0; +} + +COMMAND(set, ref_nvs, "<ini file>", 0, 0, CIB_NONE, set_ref_nvs, + "Create reference NVS file"); + +static int set_ref_nvs2(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL, + .dual_mode = DUAL_MODE_UNSET, + .done_fem = NO_FEM_PARSED + }; + + argc -= 2; + argv += 2; + + if (argc != 2) { + return 1; + } + + if (read_ini(*argv, &cmn)) { + return 1; + } + + argv++; + if (read_ini(*argv, &cmn)) { + return 1; + } + + cfg_nvs_ops(&cmn); + + if (create_nvs_file(&cmn)) { + fprintf(stderr, "Fail to create reference NVS file\n"); + return 1; + } +#if 0 + printf("\n\tThe NVS file (%s) is ready\n\tCopy it to %s and " + "reboot the system\n\n", + NEW_NVS_NAME, CURRENT_NVS_NAME); +#endif + return 0; +} + +COMMAND(set, ref_nvs2, "<ini file> <ini file>", 0, 0, CIB_NONE, set_ref_nvs2, + "Create reference NVS file for 2 FEMs"); + +static int set_upd_nvs(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *fname = NULL; + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL + }; + + argc -= 2; + argv += 2; + + if (argc < 1) { + return 1; + } + + if (read_ini(*argv, &cmn)) { + fprintf(stderr, "Fail to read ini file\n"); + return 1; + } + + cfg_nvs_ops(&cmn); + + if (argc == 2) { + fname = *++argv; + } + + if (update_nvs_file(fname, &cmn)) { + fprintf(stderr, "Fail to update NVS file\n"); + return 1; + } +#if 0 + printf("\n\tThe updated NVS file (%s) is ready\n\tCopy it to %s and " + "reboot the system\n\n", NEW_NVS_NAME, CURRENT_NVS_NAME); +#endif + return 0; +} + +COMMAND(set, upd_nvs, "<ini file> [<nvs file>]", 0, 0, CIB_NONE, set_upd_nvs, + "Update values of a NVS from INI file"); + +static int get_dump_nvs(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *fname = NULL; + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL + }; + + argc -= 2; + argv += 2; + + if (argc > 0) { + fname = *argv; + } + + if (dump_nvs_file(fname, &cmn)) { + fprintf(stderr, "Fail to dump NVS file\n"); + return 1; + } + + return 0; +} + +COMMAND(get, dump_nvs, "[<nvs file>]", 0, 0, CIB_NONE, get_dump_nvs, + "Dump NVS file, specified by option or current"); + +static int set_autofem(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *fname = NULL; + unsigned char val; + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL + }; + + argc -= 2; + argv += 2; + + if (argc < 1) { + fprintf(stderr, "Missing argument\n"); + return 2; + } + + sscanf(argv[0], "%2x", (unsigned int *)&val); + + if (argc == 2) { + fname = argv[1]; + } + + if (set_nvs_file_autofem(fname, val, &cmn)) { + fprintf(stderr, "Fail to set AutoFEM\n"); + return 1; + } + + return 0; +} + +COMMAND(set, autofem, "<0-manual|1-auto> [<nvs file>]", 0, 0, CIB_NONE, set_autofem, + "Set Auto FEM detection, where 0 - manual, 1 - auto detection"); + +static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *fname = NULL; + unsigned char val; + struct wl12xx_common cmn = { + .arch = UNKNOWN_ARCH, + .parse_ops = NULL + }; + + argc -= 2; + argv += 2; + + if (argc < 1) { + fprintf(stderr, "Missing argument\n"); + return 2; + } + + sscanf(argv[0], "%2x", (unsigned int *)&val); + + if (argc == 2) { + fname = argv[1]; + } + + if (set_nvs_file_fem_manuf(fname, val, &cmn)) { + fprintf(stderr, "Fail to set AutoFEM\n"); + return 1; + } + + return 0; +} + +COMMAND(set, fem_manuf, "<0|1> [<nvs file>]", 0, 0, CIB_NONE, set_fem_manuf, + "Set FEM manufacturer"); + |