diff options
Diffstat (limited to 'bcm4329/dhdutil/dhdu.c')
| -rw-r--r-- | bcm4329/dhdutil/dhdu.c | 2693 |
1 files changed, 0 insertions, 2693 deletions
diff --git a/bcm4329/dhdutil/dhdu.c b/bcm4329/dhdutil/dhdu.c deleted file mode 100644 index c20cef0..0000000 --- a/bcm4329/dhdutil/dhdu.c +++ /dev/null @@ -1,2693 +0,0 @@ -/* - * Common code for DHD command-line utility - * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: dhdu.c,v 1.88.2.19 2011-01-19 23:47:10 Exp $ - */ - -/* For backwards compatibility, the absence of the define 'BWL_NO_FILESYSTEM_SUPPORT' - * implies that a filesystem is supported. - */ -#if !defined(BWL_NO_FILESYSTEM_SUPPORT) -#define BWL_FILESYSTEM_SUPPORT -#endif - -#define PROP_TXSTATUS - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <assert.h> - -#include <typedefs.h> -#include <epivers.h> -#include <proto/ethernet.h> -#include <dhdioctl.h> -#include <sdiovar.h> -#include <bcmutils.h> -#include <bcmendian.h> -#include "dhdu.h" -#include "miniopt.h" -#include <proto/bcmip.h> -#define IPV4_ADDR_LEN 4 -#include <proto/bt_amp_hci.h> - -#include <errno.h> - -#include <trxhdr.h> - -#define stricmp strcasecmp -#define strnicmp strncasecmp - - -static cmd_func_t dhd_var_void; -static cmd_func_t dhd_varint, dhd_varstr; -static cmd_func_t dhd_var_getandprintstr, dhd_var_getint, dhd_var_get; -static cmd_func_t dhd_var_setint; - -static cmd_func_t dhd_version, dhd_list, dhd_msglevel; - -#ifdef SDTEST -static cmd_func_t dhd_pktgen; -#endif -static cmd_func_t dhd_sprom; -static cmd_func_t dhd_sdreg; -static cmd_func_t dhd_sd_msglevel, dhd_sd_blocksize, dhd_sd_mode, dhd_sd_reg; -static cmd_func_t dhd_dma_mode; -static cmd_func_t dhd_membytes, dhd_download, dhd_dldn, - dhd_upload, dhd_vars, dhd_idleclock, dhd_idletime; -static cmd_func_t dhd_logstamp; - -#ifdef PROP_TXSTATUS -static cmd_func_t dhd_proptxstatusenable; -static cmd_func_t dhd_proptxstatusmode; -#endif -static int dhd_var_getbuf(void *dhd, char *iovar, void *param, int param_len, void **bufptr); -static int dhd_var_setbuf(void *dhd, char *iovar, void *param, int param_len); - -static uint dhd_iovar_mkbuf(char *name, char *data, uint datalen, - char *buf, uint buflen, int *perr); -static int dhd_iovar_getint(void *dhd, char *name, int *var); -static int dhd_iovar_setint(void *dhd, char *name, int var); - -#if defined(BWL_FILESYSTEM_SUPPORT) -static int file_size(char *fname); -static int read_vars(char *fname, char *buf, int buf_maxlen); -#endif - -static cmd_func_t wl_HCI_cmd; -static cmd_func_t wl_HCI_ACL_data; - -/* dword align allocation */ -static union { - char bufdata[DHD_IOCTL_MAXLEN]; - uint32 alignme; -} bufstruct_dhd; -static char *buf = (char*) &bufstruct_dhd.bufdata; - -/* integer output format, default to signed integer */ -static uint8 int_fmt; - -typedef struct { - uint value; - char *string; -} dbg_msg_t; - -static int dhd_do_msglevel(void *dhd, cmd_t *cmd, char **argv, dbg_msg_t *dbg_msg); - -/* Actual command table */ -cmd_t dhd_cmds[] = { - { "cmds", dhd_list, -1, -1, - "generate a short list of available commands"}, - { "version", dhd_version, DHD_GET_VAR, -1, - "get version information" }, - { "msglevel", dhd_msglevel, DHD_GET_VAR, DHD_SET_VAR, - "get/set message bits" }, - { "bcmerrorstr", dhd_var_getandprintstr, DHD_GET_VAR, -1, - "errorstring"}, - { "wdtick", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "watchdog tick time (ms units)"}, - { "intr", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "use interrupts on the bus"}, - { "pollrate", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "number of ticks between bus polls (0 means no polling)"}, - { "idletime", dhd_idletime, DHD_GET_VAR, DHD_SET_VAR, - "number of ticks for activity timeout (-1: immediate, 0: never)"}, - { "idleclock", dhd_idleclock, DHD_GET_VAR, DHD_SET_VAR, - "idleclock active | stopped | <N>\n" - "\tactive (0) - do not request any change to the SD clock\n" - "\tstopped (-1) - request SD clock be stopped on activity timeout\n" - "\t<N> (other) - an sd_divisor value to request on activity timeout\n"}, - { "sd1idle", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "change mode to SD1 when turning off clock at idle"}, - { "forceeven", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "force SD tx/rx buffers to be even"}, - { "readahead", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "enable readahead feature (look for next frame len in headers)"}, - { "sdrxchain", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "enable packet chains to SDIO stack for glom receive"}, - { "alignctl", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "align control frames"}, - { "sdalign", dhd_varint, DHD_GET_VAR, -1, - "display the (compiled in) alignment target for sd requests"}, - { "txbound", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "get/set maximum number of tx frames per scheduling"}, - { "rxbound", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "get/set maximum number of rx frames per scheduling"}, - { "txminmax", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "get/set maximum number of tx frames per scheduling while rx frames outstanding"}, - { "dconpoll", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "g/set dongle console polling interval (ms)"}, - { "dump", dhd_varstr, DHD_GET_VAR, -1, - "dump information"}, - { "cons", dhd_varstr, -1, DHD_SET_VAR, - "send string to device console (sd only)"}, - { "clearcounts", dhd_var_void, -1, DHD_SET_VAR, - "reset the bus stats shown in the dhd dump"}, - { "logdump", dhd_varstr, DHD_GET_VAR, -1, - "dump the timestamp logging buffer"}, - { "logcal", dhd_varint, -1, DHD_SET_VAR, - "logcal <n> -- log around an osl_delay of <n> usecs"}, - { "logstamp", dhd_logstamp, -1, DHD_SET_VAR, - "logstamp [<n1>] [<n2>] -- add a message to the log"}, - { "memsize", dhd_varint, DHD_GET_VAR, -1, - "display size of onchip SOCRAM"}, - { "membytes", dhd_membytes, DHD_GET_VAR, DHD_SET_VAR, - "membytes [-h | -r | -i] <address> <length> [<bytes>]\n" - "\tread or write data in the dongle ram\n" - "\t-h <bytes> is a sequence of hex digits, else a char string\n" - "\t-r output as a raw write rather than hexdump display\n"}, - { "download", dhd_download, -1, DHD_SET_VAR, - "download [-a <address>] [--noreset] [--norun] <binfile> [<varsfile>]\n" - "\tdownload file to specified dongle ram address and start CPU\n" - "\toptional vars file will replace vars parsed from the CIS\n" - "\t--noreset do not reset SOCRAM core before download\n" - "\t--norun do not start dongle CPU after download\n" - "\tdefault <address> is 0\n"}, - { "dldn", dhd_dldn, -1, DHD_SET_VAR, - "download <binfile>\n" - "\tdownload file to specified dongle ram address 0\n"}, - { "vars", dhd_vars, DHD_GET_VAR, DHD_SET_VAR, - "vars [<file>]\n" - "\toverride SPROM vars with <file> (before download)\n"}, - { "upload", dhd_upload, -1, -1, - "upload [-a <address> ] <file> [<size>]\n" - "\tupload dongle RAM content into a file\n" - "\tdefault <address> is 0, default <size> is RAM size"}, - { "srdump", dhd_sprom, DHD_GET_VAR, -1, - "display SPROM content" }, - { "srwrite", dhd_sprom, -1, DHD_SET_VAR, - "write data or file content to SPROM\n" - "\tsrwrite <word-offset> <word-value> ...\n" - "\tsrwrite [-c] <srom-file-path>\n" - "\t -c means write regardless of crc"}, - { "sleep", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "enter/exit simulated host sleep (bus powerdown w/OOB wakeup)"}, -#ifdef SDTEST - { "extloop", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "external loopback: convert all tx data to echo test frames"}, - { "pktgen", dhd_pktgen, DHD_GET_VAR, DHD_SET_VAR, - "configure/report pktgen status (SDIO)\n" - "\t-f N frequency: send/recv a burst every N ticks\n" - "\t-c N count: send/recv N packets each burst\n" - "\t-t N total: stop after a total of N packets\n" - "\t-p N print: display counts on console every N bursts\n" - "\t-m N min: set minimum length of packet data\n" - "\t-M N Max: set maximum length of packet data\n" - "\t-l N len: set fixed length of packet data\n" - "\t-s N stop after N tx failures\n" - "\t-d dir test direction/type:\n" - "\t send -- send packets discarded by dongle\n" - "\t echo -- send packets to be echoed by dongle\n" - "\t burst -- request bursts (of size <-c>) from dongle\n" - "\t one every <-f> ticks, until <-t> total requests\n" - "\t recv -- request dongle enter continuous send mode,\n" - "\t read up to <-c> pkts every <-f> ticks until <-t>\n" - "\t total reads\n"}, -#endif /* SDTEST */ - { "dngl_isolation", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "g/set dongle isolation, so the dev could be disabled with out effecting the dongle state"}, - { "sdreg", dhd_sdreg, DHD_GET_VAR, DHD_SET_VAR, - "g/set sdpcmdev core register (f1) across SDIO (CMD53)"}, - { "sbreg", dhd_sdreg, DHD_GET_VAR, DHD_SET_VAR, - "g/set any backplane core register (f1) across SDIO (CMD53)"}, - { "sd_cis", dhd_var_getandprintstr, DHD_GET_VAR, -1, - "dump sdio CIS"}, - { "sd_devreg", dhd_sd_reg, DHD_GET_VAR, DHD_SET_VAR, - "g/set device register across SDIO bus (CMD52)"}, - { "sd_hostreg", dhd_sd_reg, DHD_GET_VAR, DHD_SET_VAR, - "g/set local controller register"}, - { "sd_blocksize", dhd_sd_blocksize, DHD_GET_VAR, DHD_SET_VAR, - "g/set block size for a function"}, - { "sd_blockmode", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "g/set blockmode"}, - { "sd_ints", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "g/set client ints"}, - { "sd_dma", dhd_dma_mode, DHD_GET_VAR, DHD_SET_VAR, - "g/set dma usage: [PIO | SDMA | ADMA1 | ADMA2]"}, - { "sd_yieldcpu", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "allow blocking (yield of CPU) on data xfer"}, - { "sd_minyield", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "minimum xfer size to allow CPU yield"}, - { "sd_forcerb", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "force readback when changing local interrupt settings"}, - { "sd_numints", dhd_varint, DHD_GET_VAR, -1, - "number of device interrupts"}, - { "sd_numlocalints", dhd_varint, DHD_GET_VAR, -1, - "number of non-device interrupts"}, - { "sd_divisor", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "set the divisor for SDIO clock generation"}, - { "sd_power", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "set the SD Card slot power"}, - { "sd_clock", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "turn on/off the SD Clock"}, - { "sd_crc", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "turn on/off CRC checking in SPI mode"}, - { "sd_mode", dhd_sd_mode, DHD_GET_VAR, DHD_SET_VAR, - "g/set SDIO bus mode (spi, sd1, sd4)"}, - { "sd_highspeed", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "set the high-speed clocking mode"}, - { "sd_msglevel", dhd_sd_msglevel, DHD_GET_VAR, DHD_SET_VAR, - "g/set debug message level"}, - { "sd_hciregs", dhd_varstr, DHD_GET_VAR, -1, - "display host-controller interrupt registers"}, - { "sdiod_drive", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "SDIO Device drive strength in milliamps. (0=tri-state, 1-12mA)"}, - { "devreset", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "Move device into or out of reset state (1/reset, or 0/operational)"}, - { "ioctl_timeout", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "IOCTL response timeout (milliseconds)."}, - { "HCI_cmd", wl_HCI_cmd, -1, DHD_SET_VAR, - "carries HCI commands to the driver\n" - "\tusage: dhd HCI_cmd <command> <args>\n" }, - { "HCI_ACL_data", wl_HCI_ACL_data, -1, DHD_SET_VAR, - "carries HCI ACL data packet to the driver\n" - "\tusage: dhd HCI_ACL_data <logical link handle> <data>\n" }, -#ifdef PROP_TXSTATUS - { "proptx", dhd_proptxstatusenable, DHD_GET_VAR, DHD_SET_VAR, - "enable/disable the proptxtstatus feature\n" - "0 - disabled\n" - "1 - enabled\n"}, - { "ptxmode", dhd_proptxstatusmode, DHD_GET_VAR, DHD_SET_VAR, - "set the proptxtstatus operation mode:\n" - "0 - Unsupported\n" - "1 - Use implied credit from a packet status\n" - "2 - Use explicit credit\n" }, -#endif - { "sd_uhsimode", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "g/set UHSI Mode"}, -#ifdef WLMEDIA_HTSF - { "pktdlystatsz", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "Specify the size of the delay statistics buffer\n" - "0 - disable"}, -#endif - { "hsicsleep", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "sleep/wake HSIC bus"}, - { "changemtu", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "change the size of the mtu during runtime <1500-1752> Bytes\n"}, - { "hsicautosleep", dhd_varint, DHD_GET_VAR, DHD_SET_VAR, - "Enable/Disable HSIC bus automatic sleep/resume feature"}, - { NULL, NULL, 0, 0, NULL } -}; - -cmd_t dhd_varcmd = {"var", dhd_varint, -1, -1, "unrecognized name, type -h for help"}; -char *dhdu_av0; - -#if defined(BWL_FILESYSTEM_SUPPORT) -static int -file_size(char *fname) -{ - FILE *fp; - long size = -1; - - /* Can't use stat() because of Win CE */ - - if ((fp = fopen(fname, "rb")) == NULL || - fseek(fp, 0, SEEK_END) < 0 || - (size = ftell(fp)) < 0) - fprintf(stderr, "Could not determine size of %s: %s\n", - fname, strerror(errno)); - - if (fp != NULL) - fclose(fp); - - return (int)size; -} -#endif /* BWL_FILESYSTEM_SUPPORT */ - - -/* parse/validate the command line arguments */ -/* -* pargv is updated upon return if the first argument is an option. - * It remains intact otherwise. - */ -int -dhd_option(char ***pargv, char **pifname, int *phelp) -{ - char *ifname = NULL; - int help = FALSE; - int status = CMD_OPT; - char **argv = *pargv; - - int_fmt = INT_FMT_DEC; - - while (*argv) { - /* select different adapter */ - if (!strcmp(*argv, "-a") || !strcmp(*argv, "-i")) { - char *opt = *argv++; - ifname = *argv; - if (!ifname) { - fprintf(stderr, - "error: expected interface name after option %s\n", opt); - status = CMD_ERR; - break; - } - } - - /* integer output format */ - else if (!strcmp(*argv, "-d")) - int_fmt = INT_FMT_DEC; - else if (!strcmp(*argv, "-u")) - int_fmt = INT_FMT_UINT; - else if (!strcmp(*argv, "-x")) - int_fmt = INT_FMT_HEX; - - /* command usage */ - else if (!strcmp(*argv, "-h")) - help = TRUE; - - /* done with generic options */ - else { - status = CMD_DHD; - break; - } - - /* consume the argument */ - argv ++; - break; - } - - *phelp = help; - *pifname = ifname; - *pargv = argv; - - return status; -} - -void -dhd_cmd_usage(cmd_t *cmd) -{ - if (strlen(cmd->name) >= 8) - fprintf(stderr, "%s\n\t%s\n\n", cmd->name, cmd->help); - else - fprintf(stderr, "%s\t%s\n\n", cmd->name, cmd->help); -} - -/* Dump out short list of commands */ -static int -dhd_list(void *dhd, cmd_t *garb, char **argv) -{ - cmd_t *cmd; - int nrows, i, len; - char *buf; - int letter, col, row, pad; - - UNUSED_PARAMETER(dhd); - UNUSED_PARAMETER(garb); - UNUSED_PARAMETER(argv); - - for (cmd = dhd_cmds, nrows = 0; cmd->name; cmd++) - nrows++; - - nrows /= 4; - nrows++; - - len = nrows * 80 + 2; - buf = malloc(len); - if (buf == NULL) { - fprintf(stderr, "Failed to allocate buffer of %d bytes\n", len); - return COMMAND_ERROR; - } - for (i = 0; i < len; i++) - *(buf+i) = 0; - - row = col = 0; - for (letter = 'a'; letter < 'z'; letter++) { - for (cmd = dhd_cmds; cmd->name; cmd++) { - if (cmd->name[0] == letter || cmd->name[0] == letter - 0x20) { - strcat(buf+row*80, cmd->name); - pad = 18 * (col + 1) - strlen(buf+row*80); - if (pad < 1) - pad = 1; - for (; pad; pad--) - strcat(buf+row*80, " "); - row++; - if (row == nrows) { - col++; row = 0; - } - } - } - } - for (row = 0; row < nrows; row++) - printf("%s\n", buf+row*80); - - printf("\n"); - free(buf); - return (0); -} - -void -dhd_cmds_usage(cmd_t *port_cmds) -{ - cmd_t *port_cmd; - cmd_t *cmd; - - /* print usage of port commands */ - for (port_cmd = port_cmds; port_cmd && port_cmd->name; port_cmd++) - /* Check for wc_cmd */ - dhd_cmd_usage(port_cmd); - - /* print usage of common commands without port counterparts */ - for (cmd = dhd_cmds; cmd->name; cmd++) { - /* search if port counterpart exists */ - for (port_cmd = port_cmds; port_cmd && port_cmd->name; port_cmd++) - if (!strcmp(port_cmd->name, cmd->name)) - break; - if (!port_cmd || !port_cmd->name) - dhd_cmd_usage(cmd); - } -} - -void -dhd_usage(cmd_t *port_cmds) -{ - fprintf(stderr, - "Usage: %s [-a|i <adapter>] [-h] [-d|u|x] <command> [arguments]\n", - dhdu_av0); - - fprintf(stderr, "\n"); - fprintf(stderr, " -h this message\n"); - fprintf(stderr, " -a, -i adapter name or number\n"); - fprintf(stderr, " -d display values as signed integer\n"); - fprintf(stderr, " -u display values as unsigned integer\n"); - fprintf(stderr, " -x display values as hexdecimal\n"); - fprintf(stderr, "\n"); - - dhd_cmds_usage(port_cmds); -} - -int -dhd_check(void *dhd) -{ - int ret; - int val; - - if ((ret = dhd_get(dhd, DHD_GET_MAGIC, &val, sizeof(int)) < 0)) - return ret; - if (val != DHD_IOCTL_MAGIC) - return -1; - if ((ret = dhd_get(dhd, DHD_GET_VERSION, &val, sizeof(int)) < 0)) - return ret; - if (val > DHD_IOCTL_VERSION) { - fprintf(stderr, "Version mismatch, please upgrade\n"); - return -1; - } - return 0; -} - -void -dhd_printint(int val) -{ - switch (int_fmt) { - case INT_FMT_UINT: - printf("%u\n", val); - break; - case INT_FMT_HEX: - printf("0x%x\n", val); - break; - case INT_FMT_DEC: - default: - printf("%d\n", val); - break; - } -} - -/* pretty hex print a contiguous buffer (tweaked from wlu) */ -void -dhd_hexdump(uchar *buf, uint nbytes, uint saddr) -{ - char line[256]; - char* p; - uint i; - - if (nbytes == 0) { - printf("\n"); - return; - } - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - p += sprintf(p, "%08x: ", saddr + i); /* line prefix */ - } - p += sprintf(p, "%02x ", buf[i]); - if (i % 16 == 15) { - uint j; - p += sprintf(p, " "); - for (j = i-15; j <= i; j++) - p += sprintf(p, "%c", - ((buf[j] >= 0x20 && buf[j] <= 0x7f) ? buf[j] : '.')); - printf("%s\n", line); /* flush line */ - p = line; - } - } - - /* flush last partial line */ - if (p != line) - printf("%s\n", line); -} - - -#ifdef SDTEST -static int -dhd_pktgen(void *dhd, cmd_t *cmd, char **argv) -{ - int ret = 0; - void *ptr = NULL; - dhd_pktgen_t pktgen; - char *str; - - UNUSED_PARAMETER(dhd); - UNUSED_PARAMETER(cmd); - - /* Get current settings */ - if ((ret = dhd_var_getbuf(dhd, "pktgen", NULL, 0, &ptr)) != 0) - return ret; - memcpy(&pktgen, ptr, sizeof(pktgen)); - - if (pktgen.version != DHD_PKTGEN_VERSION) { - fprintf(stderr, "pktgen version mismatch (module %d app %d)\n", - pktgen.version, DHD_PKTGEN_VERSION); - return COMMAND_ERROR; - } - - /* Presence of args implies a set, else a get */ - if (*++argv) { - miniopt_t opts; - int opt_err; - - /* Initialize option parser */ - miniopt_init(&opts, "pktgen", "", FALSE); - - while ((opt_err = miniopt(&opts, argv)) != -1) { - if (opt_err == 1) { - fprintf(stderr, "pktgen options error\n"); - ret = -1; - goto exit; - } - argv += opts.consumed; - - if (!opts.good_int && opts.opt != 'd') { - fprintf(stderr, "invalid integer %s\n", opts.valstr); - ret = -1; - goto exit; - } - - switch (opts.opt) { - case 'f': - pktgen.freq = opts.uval; - break; - case 'c': - pktgen.count = opts.uval; - break; - case 'p': - pktgen.print = opts.uval; - break; - case 't': - pktgen.total = opts.uval; - break; - case 's': - pktgen.stop = opts.uval; - break; - case 'm': - pktgen.minlen = opts.uval; - break; - case 'M': - pktgen.maxlen = opts.uval; - break; - case 'l': case 'L': - pktgen.minlen = pktgen.maxlen = opts.uval; - break; - case 'd': - if (!strcmp(opts.valstr, "send")) - pktgen.mode = DHD_PKTGEN_SEND; - else if (!strcmp(opts.valstr, "echo")) - pktgen.mode = DHD_PKTGEN_ECHO; - else if (!strcmp(opts.valstr, "burst")) - pktgen.mode = DHD_PKTGEN_RXBURST; - else if (!strcmp(opts.valstr, "recv")) - pktgen.mode = DHD_PKTGEN_RECV; - else { - fprintf(stderr, "unrecognized dir mode %s\n", - opts.valstr); - return USAGE_ERROR; - } - break; - - default: - fprintf(stderr, "option parsing error (key %s valstr %s)\n", - opts.key, opts.valstr); - ret = USAGE_ERROR; - goto exit; - } - } - - if (pktgen.maxlen < pktgen.minlen) { - fprintf(stderr, "min/max error (%d/%d)\n", pktgen.minlen, pktgen.maxlen); - ret = -1; - goto exit; - } - - /* Set the new values */ - ret = dhd_var_setbuf(dhd, "pktgen", &pktgen, sizeof(pktgen)); - } else { - printf("Counts: %d send attempts, %d received, %d tx failures\n", - pktgen.numsent, pktgen.numrcvd, pktgen.numfail); - } - - /* Show configuration in either case */ - switch (pktgen.mode) { - case DHD_PKTGEN_ECHO: str = "echo"; break; - case DHD_PKTGEN_SEND: str = "send"; break; - case DHD_PKTGEN_RECV: str = "recv"; break; - case DHD_PKTGEN_RXBURST: str = "burst"; break; - default: str = "UNKNOWN"; break; - } - - printf("Config: mode %s %d pkts (len %d-%d) each %d ticks\n", - str, pktgen.count, pktgen.minlen, pktgen.maxlen, pktgen.freq); - - /* Second config line for optional items */ - str = " "; - if (pktgen.total) { - printf("%slimit %d", str, pktgen.total); - str = ", "; - } - if (pktgen.print) { - printf("%sprint every %d ticks", str, (pktgen.freq * pktgen.print)); - str = ", "; - } - if (pktgen.stop) { - printf("%sstop after %d tx failures", str, pktgen.stop); - str = ", "; - } - if (str[0] == ',') - printf("\n"); - -exit: - return ret; -} -#endif /* SDTEST */ - -static dbg_msg_t dhd_sd_msgs[] = { - {SDH_ERROR_VAL, "error"}, - {SDH_TRACE_VAL, "trace"}, - {SDH_INFO_VAL, "info"}, - {SDH_DATA_VAL, "data"}, - {SDH_CTRL_VAL, "control"}, - {SDH_LOG_VAL, "log"}, - {SDH_DMA_VAL, "dma"}, - {0, NULL} -}; - -static int -dhd_sd_msglevel(void *dhd, cmd_t *cmd, char **argv) -{ - return dhd_do_msglevel(dhd, cmd, argv, dhd_sd_msgs); -} - -static int -dhd_sd_blocksize(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - int argc; - char *endptr = NULL; - void *ptr = NULL; - int func, size; - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - if (argc < 1 || argc > 2) { - printf("required args: function [size] (size 0 means max)\n"); - return USAGE_ERROR; - } - - func = strtol(argv[1], &endptr, 0); - if (*endptr != '\0') { - printf("Invalid function: %s\n", argv[1]); - return USAGE_ERROR; - } - - if (argc > 1) { - size = strtol(argv[2], &endptr, 0); - if (*endptr != '\0') { - printf("Invalid size: %s\n", argv[1]); - return USAGE_ERROR; - } - } - - if (argc == 1) { - if ((ret = dhd_var_getbuf(dhd, cmd->name, &func, sizeof(func), &ptr)) >= 0) - printf("Function %d block size: %d\n", func, *(int*)ptr); - } else { - printf("Setting function %d block size to %d\n", func, size); - size &= 0x0000ffff; size |= (func << 16); - ret = dhd_var_setbuf(dhd, cmd->name, &size, sizeof(size)); - } - - return (ret); -} - -static int -dhd_sd_mode(void *wl, cmd_t *cmd, char **argv) -{ - int ret; - int argc; - int sdmode; - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - if (argv[1]) { - if (!strcmp(argv[1], "spi")) { - strcpy(argv[1], "0"); - } else if (!strcmp(argv[1], "sd1")) { - strcpy(argv[1], "1"); - } else if (!strcmp(argv[1], "sd4")) { - strcpy(argv[1], "2"); - } else { - return USAGE_ERROR; - } - - ret = dhd_var_setint(wl, cmd, argv); - - } else { - if ((ret = dhd_var_get(wl, cmd, argv))) { - return (ret); - } else { - sdmode = *(int32*)buf; - - printf("SD Mode is: %s\n", - sdmode == 0 ? "SPI" - : sdmode == 1 ? "SD1" - : sdmode == 2 ? "SD4" : "Unknown"); - } - } - - return (ret); -} - -static int -dhd_dma_mode(void *wl, cmd_t *cmd, char **argv) -{ - int ret; - int argc; - int dmamode; - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - if (argv[1]) { - if (!stricmp(argv[1], "pio")) { - strcpy(argv[1], "0"); - } else if (!strcmp(argv[1], "0")) { - } else if (!stricmp(argv[1], "dma")) { - strcpy(argv[1], "1"); - } else if (!stricmp(argv[1], "sdma")) { - strcpy(argv[1], "1"); - } else if (!strcmp(argv[1], "1")) { - } else if (!stricmp(argv[1], "adma1")) { - strcpy(argv[1], "2"); - } else if (!stricmp(argv[1], "adma")) { - strcpy(argv[1], "3"); - } else if (!stricmp(argv[1], "adma2")) { - strcpy(argv[1], "3"); - } else { - return USAGE_ERROR; - } - - ret = dhd_var_setint(wl, cmd, argv); - - } else { - if ((ret = dhd_var_get(wl, cmd, argv))) { - return (ret); - } else { - dmamode = *(int32*)buf; - - printf("DMA Mode is: %s\n", - dmamode == 0 ? "PIO" - : dmamode == 1 ? "SDMA" - : dmamode == 2 ? "ADMA1" - : dmamode == 3 ? "ADMA2" - : "Unknown"); - } - } - - return (ret); -} - - -static int -dhd_sdreg(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - sdreg_t sdreg; - uint argc; - char *ptr = NULL; - - UNUSED_PARAMETER(cmd); - - bzero(&sdreg, sizeof(sdreg)); - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - /* required args: offset (will default size) */ - if (argc < 1) { - printf("required args: offset[/size] [value]\n"); - return USAGE_ERROR; - } - - sdreg.offset = strtoul(argv[1], &ptr, 0); - if (*ptr && *ptr != '/') { - printf("Bad arg: %s\n", argv[1]); - return USAGE_ERROR; - } - - /* read optional /size */ - if (*ptr == '/') { - sdreg.func = strtol((ptr+1), &ptr, 0); - if (*ptr || ((sdreg.func != 2) && sdreg.func != 4)) { - printf("Bad size option?\n"); - return USAGE_ERROR; - } - } - else { - sdreg.func = 4; - printf("Defaulting to register size 4\n"); - } - - if (argc > 1) { - sdreg.value = strtoul(argv[2], &ptr, 0); - if (*ptr) { - printf("Bad value: %s\n", argv[2]); - return USAGE_ERROR; - } - } - - if (argc <= 1) { - ret = dhd_var_getbuf(dhd, argv[0], &sdreg, sizeof(sdreg), (void**)&ptr); - if (ret >= 0) - printf("0x%0*x\n", (2 * sdreg.func), *(int *)ptr); - } else { - ret = dhd_var_setbuf(dhd, argv[0], &sdreg, sizeof(sdreg)); - } - - return (ret); -} - -static int -dhd_membytes(void *dhd, cmd_t *cmd, char **argv) -{ - int ret = -1; - uint argc; - char *ptr; - int params[2]; - uint addr; - uint len; - int align; - - int rawout, hexin; - - miniopt_t opts; - int opt_err; - - /* Parse command-line options */ - miniopt_init(&opts, "membytes", "rh", FALSE); - - rawout = hexin = 0; - - argv++; - while ((opt_err = miniopt(&opts, argv)) != -1) { - if (opt_err == 1) { - fprintf(stderr, "membytes options error\n"); - ret = -1; - goto exit; - } - - if (opts.positional) - break; - - argv += opts.consumed; - - if (opts.opt == 'h') { - hexin = 1; - } else if (opts.opt == 'r') { - rawout = 1; - } else { - fprintf(stderr, "membytes command error\n"); - ret = -1; - goto exit; - } - } - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - - /* required args: address size [<bytes>]] */ - if (argc < 2) { - fprintf(stderr, "required args: address size [<bytes>]\n"); - return USAGE_ERROR; - } - if (argc < 3 && hexin) { - fprintf(stderr, "missing <bytes> arg implies by -h\n"); - return USAGE_ERROR; - } - if ((argc > 2) && (rawout)) { - fprintf(stderr, "can't have input <bytes> arg with -r or -i\n"); - return USAGE_ERROR; - } - - /* read address */ - addr = strtoul(argv[0], &ptr, 0); - if (*ptr) { - fprintf(stderr, "Bad arg: %s\n", argv[0]); - return USAGE_ERROR; - } - - /* read size */ - len = strtoul(argv[1], &ptr, 0); - if (*ptr) { - fprintf(stderr, "Bad value: %s\n", argv[1]); - return USAGE_ERROR; - } - - align = addr & 0x03; - if (align && argc > 2) { - fprintf(stderr, "Can only write starting at long-aligned addresses.\n"); - return USAGE_ERROR; - } - - /* get can just use utility function, set must copy custom buffer */ - if (argc == 2) { - uint chunk = DHD_IOCTL_MAXLEN; - for (addr -= align, len += align; len; addr += chunk, len -= chunk, align = 0) { - chunk = MIN(chunk, len); - params[0] = addr; params[1] = ROUNDUP(chunk, 4); - ret = dhd_var_getbuf(dhd, "membytes", - params, (2 * sizeof(int)), (void**)&ptr); - if (ret < 0) - goto exit; - - if (rawout) { - fwrite(ptr + align, sizeof(char), chunk - align, stdout); - } else { - dhd_hexdump((uchar*)ptr + align, chunk - align, addr + align); - } - } - } else { - uint patlen = strlen(argv[2]); - uint chunk, maxchunk; - char *sptr; - - if (hexin) { - char *inptr, *outptr; - if (patlen & 1) { - fprintf(stderr, "Hex (-h) must consist of whole bytes\n"); - ret = USAGE_ERROR; - goto exit; - } - - for (inptr = outptr = argv[2]; patlen; patlen -= 2) { - int n1, n2; - - n1 = (int)((unsigned char)*inptr++); - n2 = (int)((unsigned char)*inptr++); - if (!isxdigit(n1) || !isxdigit(n2)) { - fprintf(stderr, "invalid hex digit %c\n", - (isxdigit(n1) ? n2 : n1)); - ret = USAGE_ERROR; - goto exit; - } - n1 = isdigit(n1) ? (n1 - '0') - : ((islower(n1) ? (toupper(n1)) : n1) - 'A' + 10); - n2 = isdigit(n2) ? (n2 - '0') - : ((islower(n2) ? (toupper(n2)) : n2) - 'A' + 10); - *outptr++ = (n1 * 16) + n2; - } - - patlen = outptr - argv[2]; - } - - sptr = argv[2]; - maxchunk = DHD_IOCTL_MAXLEN - (strlen(cmd->name) + 1 + (2 * sizeof(int))); - - while (len) { - chunk = (len > maxchunk) ? (maxchunk & ~0x3) : len; - - /* build the iovar command */ - memset(buf, 0, DHD_IOCTL_MAXLEN); - strcpy(buf, cmd->name); - ptr = buf + strlen(buf) + 1; - params[0] = addr; params[1] = chunk; - memcpy(ptr, params, (2 * sizeof(int))); - ptr += (2 * sizeof(int)); - addr += chunk; len -= chunk; - - while (chunk--) { - *ptr++ = *sptr++; - if (sptr >= (argv[2] + patlen)) - sptr = argv[2]; - } - - ret = dhd_set(dhd, DHD_SET_VAR, &buf[0], (ptr - buf)); - if (ret < 0) - goto exit; - } - } - -exit: - return ret; -} - -static int -dhd_idletime(void *dhd, cmd_t *cmd, char **argv) -{ - int32 idletime; - char *endptr = NULL; - int err = 0; - - if (argv[1]) { - if (!strcmp(argv[1], "never")) { - idletime = 0; - } else if (!strcmp(argv[1], "immediate") || !strcmp(argv[1], "immed")) { - idletime = DHD_IDLE_IMMEDIATE; - } else { - idletime = strtol(argv[1], &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "invalid number %s\n", argv[1]); - err = -1; - } - } - if ((idletime < 0) && (idletime != DHD_IDLE_IMMEDIATE)) { - fprintf(stderr, "invalid value %s\n", argv[1]); - err = -1; - } - - if (!err) { - strcpy(buf, "idletime"); - endptr = buf + strlen(buf) + 1; - memcpy(endptr, &idletime, sizeof(uint32)); - endptr += sizeof(uint32); - err = dhd_set(dhd, DHD_SET_VAR, &buf[0], (endptr - buf)); - } - } else { - if ((err = dhd_var_get(dhd, cmd, argv))) { - return err; - } else { - idletime = *(int32*)buf; - - if (idletime == 0) { - printf("0 (never)\n"); - } else if (idletime == DHD_IDLE_IMMEDIATE) { - printf("-1 (immediate)\n"); - } else if (idletime > 0) { - printf("%d\n", idletime); - } else printf("%d (invalid)\n", idletime); - } - } - return err; -} - -static int -dhd_idleclock(void *dhd, cmd_t *cmd, char **argv) -{ - int32 idleclock; - char *endptr = NULL; - int err = 0; - - if (argv[1]) { - if (!strcmp(argv[1], "active")) { - idleclock = DHD_IDLE_ACTIVE; - } else if (!strcmp(argv[1], "stopped")) { - idleclock = DHD_IDLE_STOP; - } else { - idleclock = strtol(argv[1], &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "invalid number %s\n", argv[1]); - err = USAGE_ERROR; - } - } - - if (!err) { - strcpy(buf, "idleclock"); - endptr = buf + strlen(buf) + 1; - memcpy(endptr, &idleclock, sizeof(int32)); - endptr += sizeof(int32); - err = dhd_set(dhd, DHD_SET_VAR, &buf[0], (endptr - buf)); - } - } else { - if ((err = dhd_var_get(dhd, cmd, argv))) { - return err; - } else { - idleclock = *(int32*)buf; - - if (idleclock == DHD_IDLE_ACTIVE) - printf("Idleclock %d (active)\n", idleclock); - else if (idleclock == DHD_IDLE_STOP) - printf("Idleclock %d (stopped)\n", idleclock); - else - printf("Idleclock divisor %d\n", idleclock); - } - } - return err; -} - -/* Word count for a 4kb SPROM */ -#define SPROM_WORDS 256 - -static int -dhd_sprom(void *dhd, cmd_t *cmd, char **argv) -{ -#if !defined(BWL_FILESYSTEM_SUPPORT) - return (-1); -#else - int ret, i; - uint argc; - char *endptr; - char *bufp, *countptr; - uint16 *wordptr; - uint offset, words, bytes; - bool nocrc = FALSE; - - char *fname; - FILE *fp; - - UNUSED_PARAMETER(cmd); - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - /* init buffer */ - bufp = buf; - memset(bufp, 0, DHD_IOCTL_MAXLEN); - strcpy(bufp, "sprom"); - bufp += strlen("sprom") + 1; - - if (strcmp(argv[0], "srdump") == 0) { - if (argc) { - fprintf(stderr, "Command srdump doesn't take args\n"); - return USAGE_ERROR; - } - offset = 0; - words = SPROM_WORDS; - bytes = 2 * words; - - memcpy(bufp, &offset, sizeof(int)); - bufp += sizeof(int); - memcpy(bufp, &bytes, sizeof(int)); - bufp += sizeof(int); - - if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) { - fprintf(stderr, "Internal error: unaligned word buffer\n"); - return COMMAND_ERROR; - } - } else { - if (strcmp(argv[0], "srwrite") != 0) { - fprintf(stderr, "Unimplemented sprom command: %s\n", argv[0]); - return USAGE_ERROR; - } - - if (argc == 0) { - return USAGE_ERROR; - } else if ((argc == 1) || - ((argc == 2) && ((nocrc = !strcmp(argv[1], "-c"))))) { - - fname = nocrc ? argv[2] : argv[1]; - - /* determine and validate file size */ - if ((ret = file_size(fname)) < 0) - return COMMAND_ERROR; - - bytes = ret; - offset = 0; - words = bytes / 2; - - if (bytes != 2 * SPROM_WORDS) { - fprintf(stderr, "Bad file size\n"); - return COMMAND_ERROR; - } - - memcpy(bufp, &offset, sizeof(int)); - bufp += sizeof(int); - memcpy(bufp, &bytes, sizeof(int)); - bufp += sizeof(int); - - if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) { - fprintf(stderr, "Internal error: unaligned word buffer\n"); - return COMMAND_ERROR; - } - - if ((fp = fopen(fname, "rb")) == NULL) { - fprintf(stderr, "Could not open %s: %s\n", - fname, strerror(errno)); - return COMMAND_ERROR; - } - - if (fread((uint16*)bufp, sizeof(uint16), words, fp) != words) { - fprintf(stderr, "Could not read %d bytes from %s\n", - words * 2, fname); - fclose(fp); - return COMMAND_ERROR; - } - - fclose(fp); - - if (!nocrc && - hndcrc8((uint8*)bufp, bytes, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) { - fprintf(stderr, "CRC check failed: 0x%02x, should be 0x%02x.\n", - ((uint8*)bufp)[bytes-1], - ~hndcrc8((uint8*)bufp, bytes - 1, CRC8_INIT_VALUE) & 0xff); - return COMMAND_ERROR; - } - - ltoh16_buf(bufp, bytes); - } else { - offset = strtoul(*++argv, &endptr, 0) * 2; - if (*endptr != '\0') { - fprintf(stderr, "offset %s is not an integer\n", *argv); - return USAGE_ERROR; - } - - memcpy(bufp, &offset, sizeof(int)); - bufp += sizeof(int); - countptr = bufp; - bufp += sizeof(int); - - if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) { - fprintf(stderr, "Internal error: unaligned word buffer\n"); - return COMMAND_ERROR; - } - - for (words = 0, wordptr = (uint16*)bufp; *++argv; words++) { - *wordptr++ = (uint16)strtoul(*argv, &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "value %s is not an integer\n", *argv); - return USAGE_ERROR; - } - if (words > SPROM_WORDS) { - fprintf(stderr, "max of %d words\n", SPROM_WORDS); - return USAGE_ERROR; - } - } - - bytes = 2 * words; - memcpy(countptr, &bytes, sizeof(int)); - } - } - - if (argc) { - ret = dhd_set(dhd, DHD_SET_VAR, buf, - (strlen("sprom") + 1) + (2 * sizeof(int)) + bytes); - return (ret); - } else { - ret = dhd_get(dhd, DHD_GET_VAR, buf, - (strlen("sprom") + 1) + (2 * sizeof(int)) + bytes); - if (ret < 0) { - return ret; - } - - for (i = 0; i < (int)words; i++) { - if ((i % 8) == 0) - printf("\n srom[%03d]: ", i); - printf("0x%04x ", ((uint16*)buf)[i]); - } - printf("\n"); - } - - return 0; -#endif /* BWL_FILESYSTEM_SUPPORT */ -} - -/* - * read_vars: reads an environment variables file into a buffer, - * reformatting them and returning the length (-1 on error). - * - * The input text file consists of lines of the form "<var>=<value>\n". - * CRs are ignored, as are blank lines and comments beginning with '#'. - * - * The output buffer consists of blocks of the form "<var>=<value>\0" - * (the newlines have been replaced by NULs) - * - * Todo: allow quoted variable names and quoted values. -*/ - -#if defined(BWL_FILESYSTEM_SUPPORT) -static int -read_vars(char *fname, char *buf, int buf_maxlen) -{ - FILE *fp; - int buf_len, slen; - char line[256], *s, *e; - int line_no = 0; - - if ((fp = fopen(fname, "rb")) == NULL) { - fprintf(stderr, "Cannot open NVRAM file %s: %s\n", - fname, strerror(errno)); - exit(1); - } - - buf_len = 0; - - while (fgets(line, sizeof(line), fp) != NULL) { - bool found_eq = FALSE; - - /* Ensure line length is limited */ - line[sizeof(line) - 1] = 0; - - /* Skip any initial white space */ - for (s = line; *s == ' ' || *s == '\t'; s++) - ; - - /* Determine end of string */ - for (e = s; *e != 0 && *e != '#' && *e != '\r' && *e != '\n'; e++) - if (*e == '=') - found_eq = TRUE; - - /* Strip any white space from end of string */ - while (e > s && (e[-1] == ' ' || e[-1] == '\t')) - e--; - - slen = e - s; - - /* Skip lines that end up blank */ - if (slen == 0) - continue; - - if (!found_eq) { - fprintf(stderr, "Invalid line %d in NVRAM file %s\n", line_no, fname); - fclose(fp); - return -1; - } - - if (buf_len + slen + 1 > buf_maxlen) { - fprintf(stderr, "NVRAM file %s too long\n", fname); - fclose(fp); - return -1; - } - - memcpy(buf + buf_len, s, slen); - buf_len += slen; - buf[buf_len++] = 0; - } - - fclose(fp); - - return buf_len; -} -#endif /* BWL_FILESYSTEM_SUPPORT */ - -static int -dhd_vars(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - uint argc; - char *bufp; - - UNUSED_PARAMETER(cmd); - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - switch (argc) { - case 0: /* get */ - { - if ((ret = dhd_var_getbuf(dhd, "vars", NULL, 0, (void**)&bufp))) - break; - while (*bufp) { - printf("%s\n", bufp); - bufp += strlen(bufp) + 1; - } - } - break; - -#if defined(BWL_FILESYSTEM_SUPPORT) - case 1: /* set */ - { - char *vname; - uint nvram_len; - - vname = argv[1]; - - bufp = buf; - strcpy(bufp, "vars"); - bufp += strlen("vars") + 1; - - if ((ret = read_vars(vname, bufp, - DHD_IOCTL_MAXLEN - (strlen("vars") + 3))) < 0) { - ret = -1; - break; - } - - nvram_len = ret; - bufp += nvram_len; - *bufp++ = 0; - - ret = dhd_set(dhd, DHD_SET_VAR, buf, bufp - buf); - } - break; -#endif /* BWL_FILESYSTEM_SUPPORT */ - - default: - ret = -1; - break; - } - - return ret; -} - -#define MEMBLOCK 2048 - -/* Check that strlen("membytes")+1 + 2*sizeof(int32) + MEMBLOCK <= DHD_IOCTL_MAXLEN */ -#if (MEMBLOCK + 17 > DHD_IOCTL_MAXLEN) -#error MEMBLOCK/DHD_IOCTL_MAXLEN sizing -#endif - - -#if defined(BWL_FILESYSTEM_SUPPORT) -static int -dhd_load_file_bytes(void *dhd, cmd_t *cmd, FILE *fp, int fsize, int start) -{ - int tot_len = 0; - uint read_len; - char *bufp; - uint len; - uint8 memblock[MEMBLOCK]; - int ret; - - UNUSED_PARAMETER(cmd); - - while (tot_len < fsize) { - read_len = fsize - tot_len; - if (read_len >= MEMBLOCK) - read_len = MEMBLOCK; - len = fread(memblock, sizeof(uint8), read_len, fp); - if ((len < read_len) && !feof(fp)) { - fprintf(stderr, "%s: error reading file\n", __FUNCTION__); - return -1; - - } - - bufp = buf; - memset(bufp, 0, DHD_IOCTL_MAXLEN); - strcpy(bufp, "membytes"); - bufp += strlen("membytes") + 1; - memcpy(bufp, &start, sizeof(int)); - bufp += sizeof(int); - memcpy(bufp, &len, sizeof(int)); - bufp += sizeof(int); - memcpy(bufp, memblock, len); - - ret = dhd_set(dhd, DHD_SET_VAR, &buf[0], (bufp - buf + len)); - - if (ret) { - fprintf(stderr, "%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, ret, len, start); - return -1; - } - start += len; - tot_len += len; - } - return 0; -} -#endif /* BWL_FILESYSTEM_SUPPORT */ - -#ifdef PROP_TXSTATUS -static int -dhd_proptxstatusenable(void *dhd, cmd_t *cmd, char **argv) -{ - int flag = 0xdead; - - if (argv[1]) { - flag = atoi(argv[1]); - dhd_iovar_setint(dhd, cmd->name, flag); - } - else { - dhd_iovar_getint(dhd, cmd->name, &flag); - printf("proptxstatus: %d\n", flag); - } - return 0; -} - -static int -dhd_proptxstatusmode(void *dhd, cmd_t *cmd, char **argv) -{ - int mode = 0xdead; - - if (argv[1]) { - mode = atoi(argv[1]); - dhd_iovar_setint(dhd, cmd->name, mode); - } - else { - dhd_iovar_getint(dhd, cmd->name, &mode); - printf("proptxstatusmode: %d\n", mode); - } - return 0; -} -#endif /* PROP_TXSTATUS */ - -static int -dhd_download(void *dhd, cmd_t *cmd, char **argv) -{ -#if !defined(BWL_FILESYSTEM_SUPPORT) - return (-1); -#else - bool reset = TRUE; - bool run = TRUE; - char *fname = NULL; - char *vname = NULL; - uint32 start = 0; - int ret = 0; - int fsize; - FILE *fp = NULL; - uint32 memsize; - char *memszargs[] = { "memsize", NULL }; - char *bufp; - miniopt_t opts; - int opt_err; - uint nvram_len; - struct trx_header trx_hdr; - bool trx_file = FALSE; - bool overlays = FALSE; - - UNUSED_PARAMETER(cmd); - - /* Parse command-line options */ - miniopt_init(&opts, "download", "", TRUE); - - argv++; - while ((opt_err = miniopt(&opts, argv)) != -1) { - if (opt_err == 1) { - fprintf(stderr, "download options error\n"); - ret = -1; - goto exit; - } - argv += opts.consumed; - - if (opts.opt == 'a') { - if (!opts.good_int) { - fprintf(stderr, "invalid address %s\n", opts.valstr); - ret = -1; - goto exit; - } - start = (uint32)opts.uval; - } else if (opts.positional) { - if (fname && vname) { - fprintf(stderr, "extra positional arg, %s\n", - opts.valstr); - ret = -1; - goto exit; - } - if (fname) - vname = opts.valstr; - else - fname = opts.valstr; - } else if (!opts.opt) { - if (!strcmp(opts.key, "noreset")) { - reset = FALSE; - } else if (!strcmp(opts.key, "norun")) { - run = FALSE; - } else { - fprintf(stderr, "unrecognized option %s\n", opts.valstr); - ret = -1; - goto exit; - } - } else { - fprintf(stderr, "unrecognized option %c\n", opts.opt); - ret = -1; - goto exit; - } - } - - /* validate arguments */ - if (!fname) { - fprintf(stderr, "filename required\n"); - ret = -1; - goto exit; - } - - /* validate file size compared to memory size */ - if ((fsize = file_size(fname)) < 0) { - ret = -1; - goto exit; - } - /* read the file and push blocks down to memory */ - if ((fp = fopen(fname, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open %s: %s\n", - __FUNCTION__, fname, strerror(errno)); - ret = -1; - goto exit; - } - /* Verify the file is a regular bin file or trx file */ - { - uint32 tmp_len; - uint32 trx_hdr_len = sizeof(struct trx_header); - tmp_len = fread(&trx_hdr, sizeof(uint8), trx_hdr_len, fp); - if (tmp_len == trx_hdr_len) { - if (trx_hdr.magic == TRX_MAGIC) { - trx_file = TRUE; - if (trx_hdr.flag_version & TRX_OVERLAYS) { - fprintf(stderr, "Image contains overlays but overlays " - "not supported by this command\n"); - ret = BCME_UNSUPPORTED; - goto exit; - } else { - } - } - else - fseek(fp, 0, SEEK_SET); - } - else - fseek(fp, 0, SEEK_SET); - } - - if ((ret = dhd_var_get(dhd, NULL, memszargs))) { - fprintf(stderr, "%s: error obtaining memsize\n", __FUNCTION__); - goto exit; - } - - memsize = *(uint32*)buf; - -#ifdef PART_OF_RAM_AS_ROMSIM - /* only useful for cases where you want to sim some RAM as ROM */ - if (memsize && ((uint32)fsize > memsize)) { - fprintf(stderr, "%s: file %s too large (%d > %d)\n", - __FUNCTION__, fname, fsize, memsize); - ret = -1; - goto exit; - } -#endif /* PART_OF_RAM_AS_ROMSIM */ - - /* do the download reset if not suppressed */ - if (reset) { - if ((ret = dhd_iovar_setint(dhd, "download", TRUE))) { - fprintf(stderr, "%s: failed to put dongle in download mode\n", - __FUNCTION__); - goto exit; - } - } - - if (trx_file) - fsize = trx_hdr.offsets[0]; - - /* Load the ram image */ - if (dhd_load_file_bytes(dhd, cmd, fp, fsize, start)) { - fprintf(stderr, "%s: error loading the ramimage at addr 0x%x\n", - __FUNCTION__, start); - ret = -1; - goto exit; - } - - if (trx_file) { - if (overlays) { - } else { - } - } - - fclose(fp); - fp = NULL; - - /* download the vars file if specified */ - if (vname) { - bufp = buf; - strcpy(bufp, "vars"); - bufp += strlen("vars") + 1; - - if ((ret = read_vars(vname, bufp, - DHD_IOCTL_MAXLEN - (strlen("vars") + 3))) < 0) { - ret = -1; - goto exit; - } - - nvram_len = ret; - bufp += nvram_len; - *bufp++ = 0; - - ret = dhd_set(dhd, DHD_SET_VAR, buf, (bufp - buf)); - if (ret) { - fprintf(stderr, "%s: error %d on delivering vars\n", - __FUNCTION__, ret); - goto exit; - } - } - - /* start running the downloaded code if not suppressed */ - if (run) { - if ((ret = dhd_iovar_setint(dhd, "download", FALSE))) { - fprintf(stderr, "%s: failed to take dongle out of download mode\n", - __FUNCTION__); - goto exit; - } - } - -exit: - if (fp) - fclose(fp); - - - return ret; -#endif /* BWL_FILESYSTEM_SUPPORT */ -} - -static int -dhd_dldn(void *dhd, cmd_t *cmd, char **argv) -{ -#if !defined(BWL_FILESYSTEM_SUPPORT) - return (-1); -#else - char *fname = NULL; - uint32 start = 0; - int ret = 0; - int fsize; - int fd = 0; - - FILE *fp = NULL; - uint32 memsize; - - uint len; - uint8 memblock[MEMBLOCK]; - - miniopt_t opts; - int opt_err; - - UNUSED_PARAMETER(cmd); - - /* Parse command-line options */ - miniopt_init(&opts, "download", "", TRUE); - argv++; - - while ((opt_err = miniopt(&opts, argv)) != -1) { - if (opt_err == 1) { - fprintf(stderr, "download options error\n"); - ret = -1; - goto exit; - } - argv += opts.consumed; - - if (opts.positional) { - if (fname) { - fprintf(stderr, "extra positional arg, %s\n", - opts.valstr); - ret = -1; - goto exit; - } - if (!fname) - fname = opts.valstr; - } else { - fprintf(stderr, "unrecognized option %c\n", opts.opt); - ret = -1; - goto exit; - } - } - - fd = dhd_set(dhd, DHD_DLDN_ST, NULL, 0); - if (fd < 0) { - ret = -1; - goto exit; - } - - /* validate arguments */ - if (!fname) { - fprintf(stderr, "filename required\n"); - ret = -1; - goto exit; - } - - /* validate file size compared to memory size */ - if ((fsize = file_size(fname)) < 0) { - ret = -1; - goto exit; - } - - memsize = 393216; - - if (memsize && ((uint32)fsize > memsize)) { - fprintf(stderr, "%s: file %s too large (%d > %d)\n", - __FUNCTION__, fname, fsize, memsize); - ret = -1; - goto exit; - } - - /* read the file and push blocks down to memory */ - if ((fp = fopen(fname, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open %s: %s\n", - __FUNCTION__, fname, strerror(errno)); - ret = -1; - goto exit; - } - - while ((len = fread(memblock, sizeof(uint8), MEMBLOCK, fp))) { - if (len < MEMBLOCK && !feof(fp)) { - fprintf(stderr, "%s: error reading file %s\n", __FUNCTION__, fname); - ret = -1; - goto exit; - } - - ret = dhd_set(dhd, DHD_DLDN_WRITE, memblock, len); - if (ret) { - fprintf(stderr, "%s: error %d on writing %d membytes at 0x%08x\n", - __FUNCTION__, ret, len, start); - goto exit; - } - - start += len; - } - - if (!feof(fp)) { - fprintf(stderr, "%s: error reading file %s\n", __FUNCTION__, fname); - ret = -1; - goto exit; - } - fclose(fp); - fp = NULL; - -exit: - if (fp) - fclose(fp); - - if (fd) - dhd_set(dhd, DHD_DLDN_END, NULL, 0); - - return ret; -#endif /* BWL_FILESYSTEM_SUPPORT */ -} - -static int -dhd_upload(void *dhd, cmd_t *cmd, char **argv) -{ -#if !defined(BWL_FILESYSTEM_SUPPORT) - return (-1); -#else - char *fname = NULL; - uint32 start = 0; - uint32 size = 0; - int ret = 0; - - FILE *fp; - uint32 memsize; - char *memszargs[] = { "memsize", NULL }; - - uint len; - - miniopt_t opts; - int opt_err; - - UNUSED_PARAMETER(cmd); - UNUSED_PARAMETER(argv); - - /* Parse command-line options */ - miniopt_init(&opts, "upload", "", TRUE); - - argv++; - while ((opt_err = miniopt(&opts, argv)) != -1) { - if (opt_err == 1) { - fprintf(stderr, "upload options error\n"); - ret = -1; - goto exit; - } - argv += opts.consumed; - - if (opts.opt == 'a') { - if (!opts.good_int) { - fprintf(stderr, "invalid address %s\n", opts.valstr); - ret = -1; - goto exit; - } - start = (uint32)opts.uval; - } else if (opts.positional) { - if (!fname) { - fname = opts.valstr; - } else if (opts.good_int) { - size = (uint32)opts.uval; - } else { - fprintf(stderr, "upload options error\n"); - ret = -1; - goto exit; - } - } else if (!opts.opt) { - fprintf(stderr, "unrecognized option %s\n", opts.valstr); - ret = -1; - goto exit; - } else { - fprintf(stderr, "unrecognized option %c\n", opts.opt); - ret = -1; - goto exit; - } - } - - /* validate arguments */ - if (!fname) { - fprintf(stderr, "filename required\n"); - ret = -1; - goto exit; - } - - if ((ret = dhd_var_get(dhd, NULL, memszargs))) { - fprintf(stderr, "%s: error obtaining memsize\n", __FUNCTION__); - goto exit; - } - memsize = *(uint32*)buf; - - if (!memsize) - memsize = start + size; - - if (start + size > memsize) { - fprintf(stderr, "%s: %d bytes at 0x%x exceeds ramsize 0x%x\n", - __FUNCTION__, size, start, memsize); - ret = -1; - goto exit; - } - - if ((fp = fopen(fname, "wb")) == NULL) { - fprintf(stderr, "%s: Could not open %s: %s\n", - __FUNCTION__, fname, strerror(errno)); - ret = -1; - goto exit; - } - - /* default size to full RAM */ - if (!size) - size = memsize - start; - - /* read memory and write to file */ - while (size) { - char *ptr; - int params[2]; - - len = MIN(MEMBLOCK, size); - - params[0] = start; - params[1] = len; - ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr); - if (ret) { - fprintf(stderr, "%s: failed reading %d membytes from 0x%08x\n", - __FUNCTION__, len, start); - break; - } - - if (fwrite(ptr, sizeof(*ptr), len, fp) != len) { - fprintf(stderr, "%s: error writing to file %s\n", __FUNCTION__, fname); - ret = -1; - break; - } - - start += len; - size -= len; - } - - fclose(fp); -exit: - return ret; -#endif /* BWL_FILESYSTEM_SUPPORT */ -} - -static int -dhd_logstamp(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - char *endptr = NULL; - uint argc; - int valn[2] = {0, 0}; - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; argv++; - - if (argc > 2) - return USAGE_ERROR; - - if (argc) { - valn[0] = strtol(argv[0], &endptr, 0); - if (*endptr != '\0') { - printf("bad val1: %s\n", argv[0]); - return USAGE_ERROR; - } - } - - if (argc > 1) { - valn[1] = strtol(argv[1], &endptr, 0); - if (*endptr != '\0') { - printf("bad val2: %s\n", argv[1]); - return USAGE_ERROR; - } - } - - ret = dhd_var_setbuf(dhd, cmd->name, valn, argc * sizeof(int)); - - return (ret); -} - -static int -dhd_sd_reg(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - sdreg_t sdreg; - char *endptr = NULL; - uint argc; - void *ptr = NULL; - - bzero(&sdreg, sizeof(sdreg)); - - /* arg count */ - for (argc = 0; argv[argc]; argc++); - argc--; - - /* hostreg: offset [value]; devreg: func offset [value] */ - if (!strcmp(cmd->name, "sd_hostreg")) { - argv++; - if (argc < 1) { - printf("required args: offset [value]\n"); - return USAGE_ERROR; - } - - } else if (!strcmp(cmd->name, "sd_devreg")) { - argv++; - if (argc < 2) { - printf("required args: func offset [value]\n"); - return USAGE_ERROR; - } - - sdreg.func = strtoul(*argv++, &endptr, 0); - if (*endptr != '\0') { - printf("Invalid function number\n"); - return USAGE_ERROR; - } - } else { - return USAGE_ERROR; - } - - sdreg.offset = strtoul(*argv++, &endptr, 0); - if (*endptr != '\0') { - printf("Invalid offset value\n"); - return USAGE_ERROR; - } - - /* third arg: value */ - if (*argv) { - sdreg.value = strtoul(*argv, &endptr, 0); - if (*endptr != '\0') { - printf("Invalid value\n"); - return USAGE_ERROR; - } - } - - /* no third arg means get, otherwise set */ - if (!*argv) { - if ((ret = dhd_var_getbuf(dhd, cmd->name, &sdreg, sizeof(sdreg), &ptr)) >= 0) - printf("0x%x\n", *(int *)ptr); - } else { - ret = dhd_var_setbuf(dhd, cmd->name, &sdreg, sizeof(sdreg)); - } - - return (ret); -} - -static dbg_msg_t dhd_msgs[] = { - {DHD_ERROR_VAL, "error"}, - {DHD_ERROR_VAL, "err"}, - {DHD_TRACE_VAL, "trace"}, - {DHD_INFO_VAL, "inform"}, - {DHD_INFO_VAL, "info"}, - {DHD_INFO_VAL, "inf"}, - {DHD_DATA_VAL, "data"}, - {DHD_CTL_VAL, "ctl"}, - {DHD_TIMER_VAL, "timer"}, - {DHD_HDRS_VAL, "hdrs"}, - {DHD_BYTES_VAL, "bytes"}, - {DHD_INTR_VAL, "intr"}, - {DHD_LOG_VAL, "log"}, - {DHD_GLOM_VAL, "glom"}, - {DHD_EVENT_VAL, "event"}, - {DHD_BTA_VAL, "bta"}, - {0, NULL} -}; - -static int -dhd_msglevel(void *dhd, cmd_t *cmd, char **argv) -{ - return dhd_do_msglevel(dhd, cmd, argv, dhd_msgs); -} - -static int -dhd_do_msglevel(void *dhd, cmd_t *cmd, char **argv, dbg_msg_t *dbg_msg) -{ - int ret, i; - uint val, last_val = 0, msglevel = 0, msglevel_add = 0, msglevel_del = 0; - char *endptr = NULL; - - if ((ret = dhd_iovar_getint(dhd, cmd->name, (int*)&msglevel)) < 0) - return (ret); - - if (!*++argv) { - printf("0x%x ", msglevel); - for (i = 0; (val = dbg_msg[i].value); i++) { - if ((msglevel & val) && (val != last_val)) - printf(" %s", dbg_msg[i].string); - last_val = val; - } - printf("\n"); - return (0); - } - - while (*argv) { - char *s = *argv; - if (*s == '+' || *s == '-') - s++; - else - msglevel_del = ~0; /* make the whole list absolute */ - val = strtoul(s, &endptr, 0); - /* not a plain integer if not all the string was parsed by strtoul */ - if (*endptr != '\0') { - for (i = 0; (val = dbg_msg[i].value); i++) - if (stricmp(dbg_msg[i].string, s) == 0) - break; - if (!val) - goto usage; - } - if (**argv == '-') - msglevel_del |= val; - else - msglevel_add |= val; - ++argv; - } - - msglevel &= ~msglevel_del; - msglevel |= msglevel_add; - - return (dhd_iovar_setint(dhd, cmd->name, msglevel)); - -usage: - fprintf(stderr, "msg values may be a list of numbers or names from the following set.\n"); - fprintf(stderr, "Use a + or - prefix to make an incremental change."); - - for (i = 0; (val = dbg_msg[i].value); i++) { - if (val != last_val) - fprintf(stderr, "\n0x%04x %s", val, dbg_msg[i].string); - else - fprintf(stderr, ", %s", dbg_msg[i].string); - last_val = val; - } - fprintf(stderr, "\n"); - - return 0; -} - -static char * -ver2str(unsigned int vms, unsigned int vls) -{ - static char verstr[100]; - unsigned int maj, year, month, day, build; - - maj = (vms >> 16) & 0xFFFF; - if (maj > 1000) { - /* it is probably a date... */ - year = (vms >> 16) & 0xFFFF; - month = vms & 0xFFFF; - day = (vls >> 16) & 0xFFFF; - build = vls & 0xFFFF; - sprintf(verstr, "%d/%d/%d build %d", - month, day, year, build); - } else { - /* it is a tagged release. */ - sprintf(verstr, "%d.%d RC%d.%d", - (vms>>16)&0xFFFF, vms&0xFFFF, - (vls>>16)&0xFFFF, vls&0xFFFF); - } - return verstr; -} - -static int -dhd_version(void *dhd, cmd_t *cmd, char **argv) -{ - int ret; - char *ptr; - - UNUSED_PARAMETER(cmd); - UNUSED_PARAMETER(argv); - - /* Display the application version info */ - printf("%s: %s\n", dhdu_av0, - ver2str((EPI_MAJOR_VERSION << 16)| EPI_MINOR_VERSION, - (EPI_RC_NUMBER << 16) | EPI_INCREMENTAL_NUMBER)); - - if ((ret = dhd_var_getbuf(dhd, cmd->name, NULL, 0, (void**)&ptr)) < 0) - return ret; - - /* Display the returned string */ - printf("%s\n", ptr); - - return 0; -} - -static int -dhd_var_setint(void *dhd, cmd_t *cmd, char **argv) -{ - int32 val; - int len; - char *varname; - char *endptr = NULL; - char *p; - - if (cmd->set == -1) { - printf("set not defined for %s\n", cmd->name); - return COMMAND_ERROR; - } - - if (!*argv) { - printf("set: missing arguments\n"); - return USAGE_ERROR; - } - - varname = *argv++; - - if (!*argv) { - printf("set: missing value argument for set of \"%s\"\n", varname); - return USAGE_ERROR; - } - - val = strtol(*argv, &endptr, 0); - if (*endptr != '\0') { - /* not all the value string was parsed by strtol */ - printf("set: error parsing value \"%s\" as an integer for set of \"%s\"\n", - *argv, varname); - return USAGE_ERROR; - } - - strcpy(buf, varname); - p = buf; - while (*p != '\0') { - *p = tolower(*p); - p++; - } - - /* skip the NUL */ - p++; - - memcpy(p, &val, sizeof(uint)); - len = (p - buf) + sizeof(uint); - - return (dhd_set(dhd, DHD_SET_VAR, &buf[0], len)); -} - -static int -dhd_var_get(void *dhd, cmd_t *cmd, char **argv) -{ - char *varname; - char *p; - - UNUSED_PARAMETER(cmd); - - if (!*argv) { - printf("get: missing arguments\n"); - return USAGE_ERROR; - } - - varname = *argv++; - - if (*argv) { - printf("get: error, extra arg \"%s\"\n", *argv); - return USAGE_ERROR; - } - - strcpy(buf, varname); - p = buf; - while (*p != '\0') { - *p = tolower(*p); - p++; - } - return (dhd_get(dhd, DHD_GET_VAR, &buf[0], DHD_IOCTL_MAXLEN)); -} - -static int -dhd_var_getint(void *dhd, cmd_t *cmd, char **argv) -{ - int err; - int32 val; - if (cmd->get == -1) { - printf("get not defined for %s\n", cmd->name); - return COMMAND_ERROR; - } - - if ((err = dhd_var_get(dhd, cmd, argv))) - return (err); - - val = *(int32*)buf; - - if (val < 10) - printf("%d\n", val); - else - printf("%d (0x%x)\n", val, val); - - return (0); -} - -static int -dhd_var_getandprintstr(void *dhd, cmd_t *cmd, char **argv) -{ - int err; - - if ((err = dhd_var_get(dhd, cmd, argv))) - return (err); - - printf("%s\n", buf); - return (0); -} - - -void -dhd_printlasterror(void *dhd) -{ - char *cmd[2] = {"bcmerrorstr"}; - - if (dhd_var_get(dhd, NULL, cmd) != 0) { - fprintf(stderr, "%s: \nError getting the last error\n", dhdu_av0); - } else { - fprintf(stderr, "%s: %s\n", dhdu_av0, buf); - } -} - -static int -dhd_varint(void *dhd, cmd_t *cmd, char *argv[]) -{ - if (argv[1]) - return (dhd_var_setint(dhd, cmd, argv)); - else - return (dhd_var_getint(dhd, cmd, argv)); -} - -static int -dhd_var_getbuf(void *dhd, char *iovar, void *param, int param_len, void **bufptr) -{ - int len; - - memset(buf, 0, DHD_IOCTL_MAXLEN); - strcpy(buf, iovar); - - /* include the NUL */ - len = strlen(iovar) + 1; - - if (param_len) - memcpy(&buf[len], param, param_len); - - *bufptr = buf; - - return dhd_get(dhd, DHD_GET_VAR, &buf[0], DHD_IOCTL_MAXLEN); -} - -static int -dhd_var_setbuf(void *dhd, char *iovar, void *param, int param_len) -{ - int len; - - memset(buf, 0, DHD_IOCTL_MAXLEN); - strcpy(buf, iovar); - - /* include the NUL */ - len = strlen(iovar) + 1; - - if (param_len) - memcpy(&buf[len], param, param_len); - - len += param_len; - - return dhd_set(dhd, DHD_SET_VAR, &buf[0], len); -} - -static int -dhd_var_void(void *dhd, cmd_t *cmd, char **argv) -{ - UNUSED_PARAMETER(argv); - - if (cmd->set < 0) - return USAGE_ERROR; - - return dhd_var_setbuf(dhd, cmd->name, NULL, 0); -} - -/* - * format an iovar buffer - */ -static uint -dhd_iovar_mkbuf(char *name, char *data, uint datalen, char *buf, uint buflen, int *perr) -{ - uint len; - - len = strlen(name) + 1; - - /* check for overflow */ - if ((len + datalen) > buflen) { - *perr = BCME_BUFTOOSHORT; - return 0; - } - - strcpy(buf, name); - - /* append data onto the end of the name string */ - if (datalen > 0) - memcpy(&buf[len], data, datalen); - - len += datalen; - - *perr = 0; - return len; -} - -static int -dhd_iovar_getint(void *dhd, char *name, int *var) -{ - char ibuf[DHD_IOCTL_SMLEN]; - int error; - - dhd_iovar_mkbuf(name, NULL, 0, ibuf, sizeof(ibuf), &error); - if (error) - return error; - - if ((error = dhd_get(dhd, DHD_GET_VAR, &ibuf, sizeof(ibuf))) < 0) - return error; - - memcpy(var, ibuf, sizeof(int)); - - return 0; -} - -static int -dhd_iovar_setint(void *dhd, char *name, int var) -{ - int len; - char ibuf[DHD_IOCTL_SMLEN]; - int error; - - len = dhd_iovar_mkbuf(name, (char *)&var, sizeof(var), ibuf, sizeof(ibuf), &error); - if (error) - return error; - - if ((error = dhd_set(dhd, DHD_SET_VAR, &ibuf, len)) < 0) - return error; - - return 0; -} - -static int -dhd_varstr(void *dhd, cmd_t *cmd, char **argv) -{ - int error; - char *str; - - if (!*++argv) { - void *ptr; - - if ((error = dhd_var_getbuf(dhd, cmd->name, NULL, 0, &ptr)) < 0) - return (error); - - str = (char *)ptr; - printf("%s\n", str); - return (0); - } else { - str = *argv; - /* iovar buffer length includes NUL */ - return dhd_var_setbuf(dhd, cmd->name, str, strlen(str) + 1); - } -} - - - -#define MATCH_OP(op, opstr) (strlen(op) == strlen(opstr) && strncmp(op, opstr, strlen(op)) == 0) - -static int -wl_HCI_cmd(void *wl, cmd_t *cmd, char **argv) -{ - union { - char buf[HCI_CMD_PREAMBLE_SIZE + HCI_CMD_DATA_SIZE]; - uint32 alignme; - } cbuf; - amp_hci_cmd_t *cpkt = (amp_hci_cmd_t *)&cbuf.buf[0]; - - char *op; - uint8 plen; - - UNUSED_PARAMETER(cmd); - - if (!*++argv) - return USAGE_ERROR; - - /* recognize and encode operations */ - op = *argv++; - if (MATCH_OP(op, "Read_Link_Quality")) { - cpkt->opcode = HCI_Read_Link_Quality; - } else if (MATCH_OP(op, "Read_Local_AMP_Info")) { - cpkt->opcode = HCI_Read_Local_AMP_Info; - } else if (MATCH_OP(op, "Read_Local_AMP_ASSOC")) { - cpkt->opcode = HCI_Read_Local_AMP_ASSOC; - } else if (MATCH_OP(op, "Write_Remote_AMP_ASSOC")) { - cpkt->opcode = HCI_Write_Remote_AMP_ASSOC; - } else if (MATCH_OP(op, "Create_Physical_Link")) { - cpkt->opcode = HCI_Create_Physical_Link; - } else if (MATCH_OP(op, "Accept_Physical_Link_Request")) { - cpkt->opcode = HCI_Accept_Physical_Link_Request; - } else if (MATCH_OP(op, "Disconnect_Physical_Link")) { - cpkt->opcode = HCI_Disconnect_Physical_Link; - } else if (MATCH_OP(op, "Create_Logical_Link")) { - cpkt->opcode = HCI_Create_Logical_Link; - } else if (MATCH_OP(op, "Accept_Logical_Link")) { - cpkt->opcode = HCI_Accept_Logical_Link; - } else if (MATCH_OP(op, "Disconnect_Logical_Link")) { - cpkt->opcode = HCI_Disconnect_Logical_Link; - } else if (MATCH_OP(op, "Logical_Link_Cancel")) { - cpkt->opcode = HCI_Logical_Link_Cancel; - } else if (MATCH_OP(op, "Short_Range_Mode")) { - cpkt->opcode = HCI_Short_Range_Mode; - } else if (MATCH_OP(op, "Read_Connection_Accept_Timeout")) { - cpkt->opcode = HCI_Read_Connection_Accept_Timeout; - } else if (MATCH_OP(op, "Write_Connection_Accept_Timeout")) { - cpkt->opcode = HCI_Write_Connection_Accept_Timeout; - } else if (MATCH_OP(op, "Read_Link_Supervision_Timeout")) { - cpkt->opcode = HCI_Read_Link_Supervision_Timeout; - } else if (MATCH_OP(op, "Write_Link_Supervision_Timeout")) { - cpkt->opcode = HCI_Write_Link_Supervision_Timeout; - } else if (MATCH_OP(op, "Reset")) { - cpkt->opcode = HCI_Reset; - } else if (MATCH_OP(op, "Enhanced_Flush")) { - cpkt->opcode = HCI_Enhanced_Flush; - } else if (MATCH_OP(op, "Read_Best_Effort_Flush_Timeout")) { - cpkt->opcode = HCI_Read_Best_Effort_Flush_Timeout; - } else if (MATCH_OP(op, "Write_Best_Effort_Flush_Timeout")) { - cpkt->opcode = HCI_Write_Best_Effort_Flush_Timeout; - } else if (MATCH_OP(op, "Read_Logical_Link_Accept_Timeout")) { - cpkt->opcode = HCI_Read_Logical_Link_Accept_Timeout; - } else if (MATCH_OP(op, "Write_Logical_Link_Accept_Timeout")) { - cpkt->opcode = HCI_Write_Logical_Link_Accept_Timeout; - } else if (MATCH_OP(op, "Read_Buffer_Size")) { - cpkt->opcode = HCI_Read_Buffer_Size; - } else if (MATCH_OP(op, "Read_Data_Block_Size")) { - cpkt->opcode = HCI_Read_Data_Block_Size; - } else if (MATCH_OP(op, "Set_Event_Mask_Page_2")) { - cpkt->opcode = HCI_Set_Event_Mask_Page_2; - } else if (MATCH_OP(op, "Flow_Spec_Modify")) { - cpkt->opcode = HCI_Flow_Spec_Modify; - } else if (MATCH_OP(op, "Read_Local_Version_Info")) { - cpkt->opcode = HCI_Read_Local_Version_Info; - } else if (MATCH_OP(op, "Read_Local_Supported_Commands")) { - cpkt->opcode = HCI_Read_Local_Supported_Commands; - } else if (MATCH_OP(op, "Read_Failed_Contact_Counter")) { - cpkt->opcode = HCI_Read_Failed_Contact_Counter; - } else if (MATCH_OP(op, "Reset_Failed_Contact_Counter")) { - cpkt->opcode = HCI_Reset_Failed_Contact_Counter; - } else { - printf("unsupported HCI command: %s\n", op); - return (-1); - } - - plen = 0; - while (*argv && (plen < HCI_CMD_DATA_SIZE)) { - cpkt->parms[plen++] = (uint8)strtol(*argv++, NULL, 0); - } - cpkt->plen = plen; - - return dhd_var_setbuf(wl, cmd->name, cpkt, HCI_CMD_PREAMBLE_SIZE + plen); -} - -static int -wl_HCI_ACL_data(void *wl, cmd_t *cmd, char **argv) -{ - /* Align struct. Also declare static so that large array isn't allocated - * from the stack. - */ - static union { - uint8 buf[HCI_ACL_DATA_PREAMBLE_SIZE + 2048]; - uint32 alignme; - } g_hci_dbuf; - - amp_hci_ACL_data_t *dpkt = (amp_hci_ACL_data_t *)&g_hci_dbuf.buf[0]; - uint16 dlen; - - if (!*++argv) - return USAGE_ERROR; - - /* get logical link handle */ - dpkt->handle = (HCI_ACL_DATA_BC_FLAGS | HCI_ACL_DATA_PB_FLAGS); - dpkt->handle |= (uint16)strtol(*argv++, NULL, 0); - - /* get data */ - dlen = 0; - while (*argv && (dlen < 2048)) { - dpkt->data[dlen++] = (uint8)strtol(*argv++, NULL, 0); - } - dpkt->dlen = dlen; - - return dhd_var_setbuf(wl, cmd->name, dpkt, HCI_ACL_DATA_PREAMBLE_SIZE + dlen); -} - -/* These two utility functions are used by dhdu_linux.c - * The code is taken from wlu.c. - */ -int -dhd_atoip(const char *a, struct ipv4_addr *n) -{ - char *c; - int i = 0; - - for (;;) { - n->addr[i++] = (uint8)strtoul(a, &c, 0); - if (*c++ != '.' || i == IPV4_ADDR_LEN) - break; - a = c; - } - return (i == IPV4_ADDR_LEN); -} - -int -dhd_ether_atoe(const char *a, struct ether_addr *n) -{ - char *c; - int i = 0; - - memset(n, 0, ETHER_ADDR_LEN); - for (;;) { - n->octet[i++] = (uint8)strtoul(a, &c, 16); - if (!*c++ || i == ETHER_ADDR_LEN) - break; - a = c; - } - return (i == ETHER_ADDR_LEN); -} |
