summaryrefslogtreecommitdiffstats
path: root/bcm4329/dhdutil/dhdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'bcm4329/dhdutil/dhdu.c')
-rw-r--r--bcm4329/dhdutil/dhdu.c2693
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);
-}