1b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
26dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Common code for DHD command-line utility
3b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * Copyright (C) 1999-2013, Broadcom Corporation
56dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
66dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Permission to use, copy, modify, and/or distribute this software for any
76dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * purpose with or without fee is hereby granted, provided that the above
86dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * copyright notice and this permission notice appear in all copies.
96dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
106dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
116dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
126dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * $Id: dhdu.c 385965 2013-02-19 04:33:34Z $
19b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
20b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
21b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* For backwards compatibility, the absence of the define 'BWL_NO_FILESYSTEM_SUPPORT'
22b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * implies that a filesystem is supported.
23b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
24b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if !defined(BWL_NO_FILESYSTEM_SUPPORT)
25b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define BWL_FILESYSTEM_SUPPORT
26b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
27b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
28ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifndef PROP_TXSTATUS
29b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define PROP_TXSTATUS
30ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif
31b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
32b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <stdio.h>
33b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <stdlib.h>
34b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <string.h>
35f73584dcb4cd1fc17a006e502db7cb10a30f23b6Elliott Hughes#include <strings.h>
36b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <ctype.h>
37b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <assert.h>
38b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
39b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <typedefs.h>
40b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <epivers.h>
41b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/ethernet.h>
42b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <dhdioctl.h>
43b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <sdiovar.h>
44b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmutils.h>
45b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmendian.h>
46b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include "dhdu.h"
47b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include "miniopt.h"
48b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/bcmip.h>
4938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#include <hndrte_debug.h>
5038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#include <hndrte_armtrap.h>
5138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#include <hndrte_cons.h>
52b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define IPV4_ADDR_LEN 4
53b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
54b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <errno.h>
55b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
56b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <trxhdr.h>
5738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#include "ucode_download.h"
58b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
59b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define stricmp strcasecmp
60b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define strnicmp strncasecmp
61b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
62b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
63b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_var_void;
64b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_varint, dhd_varstr;
65b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_var_getandprintstr, dhd_var_getint, dhd_var_get;
66b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_var_setint;
67b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
68b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_version, dhd_list, dhd_msglevel;
69b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
70b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef SDTEST
71b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_pktgen;
72b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
73b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_sprom;
74b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_sdreg;
75b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_sd_msglevel, dhd_sd_blocksize, dhd_sd_mode, dhd_sd_reg;
76b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_dma_mode;
77b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_membytes, dhd_download, dhd_dldn,
7838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	dhd_upload, dhd_coredump, dhd_consoledump, dhd_vars, dhd_idleclock, dhd_idletime;
79b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_logstamp;
80b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
81ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtstatic cmd_func_t dhd_hostreorder_flows;
82ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
83b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef PROP_TXSTATUS
84b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_proptxstatusenable;
85b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic cmd_func_t dhd_proptxstatusmode;
8638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic cmd_func_t dhd_proptxopt;
87b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
88b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int dhd_var_getbuf(void *dhd, char *iovar, void *param, int param_len, void **bufptr);
89b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int dhd_var_setbuf(void *dhd, char *iovar, void *param, int param_len);
90b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
91b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic uint dhd_iovar_mkbuf(char *name, char *data, uint datalen,
92b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt                            char *buf, uint buflen, int *perr);
93b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int dhd_iovar_getint(void *dhd, char *name, int *var);
94b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int dhd_iovar_setint(void *dhd, char *name, int var);
95b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
96b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BWL_FILESYSTEM_SUPPORT)
97b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int file_size(char *fname);
98b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int read_vars(char *fname, char *buf, int buf_maxlen);
99b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
101b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
102b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* dword align allocation */
103b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic union {
104b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char bufdata[DHD_IOCTL_MAXLEN];
105b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint32 alignme;
106b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt} bufstruct_dhd;
107b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic char *buf = (char*) &bufstruct_dhd.bufdata;
108b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
109b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* integer output format, default to signed integer */
110b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic uint8 int_fmt;
111b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
11238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#define DEBUG_INFO_PTRS_END 0xffffffff
11338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtconst uint32 debug_info_ptrs[] = {0xf8, 0x878, DEBUG_INFO_PTRS_END};
11438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
115b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidttypedef struct {
116b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint value;
117b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *string;
118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt} dbg_msg_t;
119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
120b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int dhd_do_msglevel(void *dhd, cmd_t *cmd, char **argv, dbg_msg_t *dbg_msg);
121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Actual command table */
123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtcmd_t dhd_cmds[] = {
124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "cmds", dhd_list, -1, -1,
125b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"generate a short list of available commands"},
126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "version", dhd_version, DHD_GET_VAR, -1,
127b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"get version information" },
128b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "msglevel", dhd_msglevel, DHD_GET_VAR, DHD_SET_VAR,
129b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"get/set message bits" },
130b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "bcmerrorstr", dhd_var_getandprintstr, DHD_GET_VAR, -1,
131b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"errorstring"},
132b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "wdtick", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"watchdog tick time (ms units)"},
134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "intr", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
135b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"use interrupts on the bus"},
136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "pollrate", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"number of ticks between bus polls (0 means no polling)"},
138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "idletime", dhd_idletime, DHD_GET_VAR, DHD_SET_VAR,
139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"number of ticks for activity timeout (-1: immediate, 0: never)"},
140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "idleclock", dhd_idleclock, DHD_GET_VAR, DHD_SET_VAR,
141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"idleclock active | stopped | <N>\n"
142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tactive (0)   - do not request any change to the SD clock\n"
143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tstopped (-1) - request SD clock be stopped on activity timeout\n"
144b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t<N> (other)  - an sd_divisor value to request on activity timeout\n"},
145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd1idle", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"change mode to SD1 when turning off clock at idle"},
147b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "forceeven", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"force SD tx/rx buffers to be even"},
149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "readahead", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"enable readahead feature (look for next frame len in headers)"},
151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sdrxchain", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
152b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"enable packet chains to SDIO stack for glom receive"},
153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "alignctl", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"align control frames"},
155b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sdalign", dhd_varint, DHD_GET_VAR, -1,
156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"display the (compiled in) alignment target for sd requests"},
157b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "txbound", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
158b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"get/set maximum number of tx frames per scheduling"},
159b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "rxbound", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
160b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"get/set maximum number of rx frames per scheduling"},
161b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "txminmax", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
162b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"get/set maximum number of tx frames per scheduling while rx frames outstanding"},
163b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "dconpoll", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
164b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set dongle console polling interval (ms)"},
165b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "dump", dhd_varstr, DHD_GET_VAR, -1,
166b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"dump information"},
167b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "cons", dhd_varstr, -1, DHD_SET_VAR,
168b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"send string to device console (sd only)"},
169b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "clearcounts", dhd_var_void, -1, DHD_SET_VAR,
170b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"reset the bus stats shown in the dhd dump"},
171b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "logdump", dhd_varstr, DHD_GET_VAR, -1,
172b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"dump the timestamp logging buffer"},
173b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "logcal", dhd_varint, -1, DHD_SET_VAR,
174b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"logcal <n>  -- log around an osl_delay of <n> usecs"},
175b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "logstamp", dhd_logstamp, -1, DHD_SET_VAR,
176b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"logstamp [<n1>] [<n2>]  -- add a message to the log"},
17738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "ramstart", dhd_varint, DHD_GET_VAR, -1,
17838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"display start address of onchip SOCRAM"},
17938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "ramsize", dhd_varint, DHD_GET_VAR, -1,
180b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"display size of onchip SOCRAM"},
181b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "membytes", dhd_membytes, DHD_GET_VAR, DHD_SET_VAR,
182ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"membytes [-h | -r | -i] <address> <length> [<data>]\n"
183b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tread or write data in the dongle ram\n"
184ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"\t-h   <data> is a sequence of hex digits rather than a char string\n"
185ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"\t-r   output binary to stdout rather hex\n"},
186b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "download", dhd_download, -1, DHD_SET_VAR,
187ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"download [-a <address>] [--noreset] [--norun] [--verify] <binfile> [<varsfile>]\n"
188b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tdownload file to specified dongle ram address and start CPU\n"
189b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\toptional vars file will replace vars parsed from the CIS\n"
190b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t--noreset    do not reset SOCRAM core before download\n"
191b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t--norun      do not start dongle CPU after download\n"
192ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"\t--verify     do readback verify \n"
193b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tdefault <address> is 0\n"},
194b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "dldn", dhd_dldn, -1, DHD_SET_VAR,
195b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"download <binfile>\n"
196b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tdownload file to specified dongle ram address 0\n"},
197b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "vars", dhd_vars, DHD_GET_VAR, DHD_SET_VAR,
198b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"vars [<file>]\n"
199b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\toverride SPROM vars with <file> (before download)\n"},
20038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "coredump", dhd_coredump, -1, -1,
20138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"coredump <file>\n"
20238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"\tdump dongle RAM content into a file in dumpfile format\n"
20338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"\tfor use with ELF core generator"},
20438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "consoledump", dhd_consoledump, -1, -1,
20538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"consoledump\n"
20638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"\tdump dongle debug console buffer"},
207b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "upload", dhd_upload, -1, -1,
208b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"upload [-a <address> ] <file> [<size>]\n"
209b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tupload dongle RAM content into a file\n"
210b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tdefault <address> is 0, default <size> is RAM size"},
211b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "srdump", dhd_sprom, DHD_GET_VAR, -1,
212b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"display SPROM content" },
213b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "srwrite", dhd_sprom, -1, DHD_SET_VAR,
214b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"write data or file content to SPROM\n"
215b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tsrwrite <word-offset> <word-value> ...\n"
216b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\tsrwrite [-c] <srom-file-path>\n"
217b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t  -c means write regardless of crc"},
218b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sleep", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
219b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"enter/exit simulated host sleep (bus powerdown w/OOB wakeup)"},
220ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "kso", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
221ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"keep sdio on"},
222ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "devcap", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
223ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"brcm device capabilities"},
224ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "devsleep", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
225ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"Sleep CMD14"},
226b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef SDTEST
227b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "extloop", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
228b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"external loopback: convert all tx data to echo test frames"},
229b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "pktgen", dhd_pktgen, DHD_GET_VAR, DHD_SET_VAR,
230b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"configure/report pktgen status (SDIO)\n"
231b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-f N     frequency: send/recv a burst every N ticks\n"
232b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-c N     count: send/recv N packets each burst\n"
233b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-t N     total: stop after a total of N packets\n"
234b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-p N     print: display counts on console every N bursts\n"
235b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-m N     min: set minimum length of packet data\n"
236b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-M N     Max: set maximum length of packet data\n"
237b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-l N     len: set fixed length of packet data\n"
238b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-s N     stop after N tx failures\n"
239b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t-d dir   test direction/type:\n"
240b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t            send -- send packets discarded by dongle\n"
241b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t            echo -- send packets to be echoed by dongle\n"
242b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t            burst -- request bursts (of size <-c>) from dongle\n"
243b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t              one every <-f> ticks, until <-t> total requests\n"
244b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t            recv -- request dongle enter continuous send mode,\n"
245b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t              read up to <-c> pkts every <-f> ticks until <-t>\n"
246b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"\t              total reads\n"},
247b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* SDTEST */
248b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "dngl_isolation", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
249b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set dongle isolation, so the dev could be disabled with out effecting the dongle state"},
250b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sdreg", dhd_sdreg, DHD_GET_VAR, DHD_SET_VAR,
251b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set sdpcmdev core register (f1) across SDIO (CMD53)"},
252b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sbreg", dhd_sdreg, DHD_GET_VAR, DHD_SET_VAR,
253b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set any backplane core register (f1) across SDIO (CMD53)"},
254b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_cis", dhd_var_getandprintstr, DHD_GET_VAR, -1,
255b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"dump sdio CIS"},
256b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_devreg", dhd_sd_reg, DHD_GET_VAR, DHD_SET_VAR,
257b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set device register across SDIO bus (CMD52)"},
258b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_hostreg", dhd_sd_reg, DHD_GET_VAR, DHD_SET_VAR,
259b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set local controller register"},
260b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_blocksize", dhd_sd_blocksize, DHD_GET_VAR, DHD_SET_VAR,
261b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set block size for a function"},
262b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_blockmode", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
263b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set blockmode"},
264b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_ints", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
265b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set client ints"},
266b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_dma", dhd_dma_mode, DHD_GET_VAR, DHD_SET_VAR,
267b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set dma usage: [PIO | SDMA | ADMA1 | ADMA2]"},
268b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_yieldcpu", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
269b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"allow blocking (yield of CPU) on data xfer"},
270b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_minyield", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
271b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"minimum xfer size to allow CPU yield"},
272b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_forcerb", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
273b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"force readback when changing local interrupt settings"},
274b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_numints", dhd_varint, DHD_GET_VAR, -1,
275b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"number of device interrupts"},
276b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_numlocalints", dhd_varint, DHD_GET_VAR, -1,
277b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"number of non-device interrupts"},
278b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_divisor", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
279b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"set the divisor for SDIO clock generation"},
280b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_power", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
281b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"set the SD Card slot power"},
28238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "sd_power_save", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
28338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"set the SDIO3.0 power save value"},
284b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_clock", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
285b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"turn on/off the SD Clock"},
286b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_crc", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
287b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"turn on/off CRC checking in SPI mode"},
288b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_mode", dhd_sd_mode, DHD_GET_VAR, DHD_SET_VAR,
289b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set SDIO bus mode (spi, sd1, sd4)"},
290b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_highspeed", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
291b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"set the high-speed clocking mode"},
292b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_msglevel", dhd_sd_msglevel, DHD_GET_VAR, DHD_SET_VAR,
293b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set debug message level"},
294b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_hciregs", dhd_varstr, DHD_GET_VAR, -1,
295b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"display host-controller interrupt registers"},
296b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sdiod_drive", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
297b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"SDIO Device drive strength in milliamps. (0=tri-state, 1-12mA)"},
298b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "devreset", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
299b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"Move device into or out of reset state (1/reset, or 0/operational)"},
300b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "ioctl_timeout", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
301b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"IOCTL response timeout (milliseconds)."},
302b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef PROP_TXSTATUS
303b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "proptx", dhd_proptxstatusenable, DHD_GET_VAR, DHD_SET_VAR,
304b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"enable/disable the proptxtstatus feature\n"
305b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"0 - disabled\n"
306b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"1 - enabled\n"},
307b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "ptxmode", dhd_proptxstatusmode, DHD_GET_VAR, DHD_SET_VAR,
308b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"set the proptxtstatus operation mode:\n"
309b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"0 - Unsupported\n"
310b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"1 - Use implied credit from a packet status\n"
311b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"2 - Use explicit credit\n" },
31238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "proptx_opt", dhd_proptxopt, DHD_GET_VAR, DHD_SET_VAR,
31338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"enable/disable proptxtstatus optimizations to increase throughput:\n"
31438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"0 - Unsupported\n"
31538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"1 - Enable proptxstatus optimizations to increase throughput\n" },
316b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
317b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ "sd_uhsimode", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
318b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"g/set UHSI Mode"},
319ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "host_reorder_flows", dhd_hostreorder_flows, DHD_GET_VAR, -1,
320ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"get host reorder flows "},
321ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "txglomsize", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
322ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"max glom size for sdio tx\n"},
323ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{ "txglommode", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
324ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	"glom mode for sdio tx 0- copy, 1- multidescriptor\n"},
32538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	{ "fw_hang_report", dhd_varint, DHD_GET_VAR, DHD_SET_VAR,
32638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"enable/disable report firmware hangs for firmware reload\n"
32738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"0 - disabled (for testing)\n"
32838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	"1 - enabled (default)\n"},
329b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{ NULL, NULL, 0, 0, NULL }
330b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
331b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
332b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtcmd_t dhd_varcmd = {"var", dhd_varint, -1, -1, "unrecognized name, type -h for help"};
333b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *dhdu_av0;
334b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
335b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BWL_FILESYSTEM_SUPPORT)
336b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
337b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtfile_size(char *fname)
338b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
339b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp;
340b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	long size = -1;
341b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
342b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Can't use stat() because of Win CE */
343b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
344b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fp = fopen(fname, "rb")) == NULL ||
345b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	    fseek(fp, 0, SEEK_END) < 0 ||
346b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	    (size = ftell(fp)) < 0)
347b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Could not determine size of %s: %s\n",
348b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        fname, strerror(errno));
349b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
350b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fp != NULL)
351b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fclose(fp);
352b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
353b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (int)size;
354b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
355b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif   /* BWL_FILESYSTEM_SUPPORT */
356b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
357b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
358b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* parse/validate the command line arguments */
359b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
360b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* pargv is updated upon return if the first argument is an option.
361b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * It remains intact otherwise.
362b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
363b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
364b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_option(char ***pargv, char **pifname, int *phelp)
365b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
366b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *ifname = NULL;
367b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int help = FALSE;
368b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int status = CMD_OPT;
369b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char **argv = *pargv;
370b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
371b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int_fmt = INT_FMT_DEC;
372b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
373b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*argv) {
374b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* select different adapter */
375b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!strcmp(*argv, "-a") || !strcmp(*argv, "-i")) {
376b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			char *opt = *argv++;
377b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ifname = *argv;
378b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!ifname) {
379b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr,
380b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					"error: expected interface name after option %s\n", opt);
381b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				status = CMD_ERR;
382b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
383b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
384b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
385b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
386b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* integer output format */
387b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else if (!strcmp(*argv, "-d"))
388b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			int_fmt = INT_FMT_DEC;
389b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else if (!strcmp(*argv, "-u"))
390b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			int_fmt = INT_FMT_UINT;
391b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else if (!strcmp(*argv, "-x"))
392b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			int_fmt = INT_FMT_HEX;
393b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
394b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* command usage */
395b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else if (!strcmp(*argv, "-h"))
396b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			help = TRUE;
397b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
398b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* done with generic options */
399b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else {
400b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			status = CMD_DHD;
401b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
402b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
403b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
404b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* consume the argument */
405b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv ++;
406b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
407b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
408b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
409b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*phelp = help;
410b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*pifname = ifname;
411b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*pargv = argv;
412b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
413b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return status;
414b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
415b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
416b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
417b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_cmd_usage(cmd_t *cmd)
418b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
419b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (strlen(cmd->name) >= 8)
420b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s\n\t%s\n\n", cmd->name, cmd->help);
421b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
422b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s\t%s\n\n", cmd->name, cmd->help);
423b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
424b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
425b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Dump out short list of commands */
426b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
427b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_list(void *dhd, cmd_t *garb, char **argv)
428b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
429b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	cmd_t *cmd;
430b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int nrows, i, len;
431b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *buf;
432b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int letter, col, row, pad;
433b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
434b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(dhd);
435b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(garb);
436b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(argv);
437b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
438b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (cmd = dhd_cmds, nrows = 0; cmd->name; cmd++)
439b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		    nrows++;
440b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
441b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	nrows /= 4;
442b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	nrows++;
443b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
444b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = nrows * 80 + 2;
445b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	buf = malloc(len);
446b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (buf == NULL) {
447b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Failed to allocate buffer of %d bytes\n", len);
44838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_NOMEM;
449b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
450b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < len; i++)
451b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*(buf+i) = 0;
452b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
453b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	row = col = 0;
454b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (letter = 'a'; letter < 'z'; letter++) {
455b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (cmd = dhd_cmds; cmd->name; cmd++) {
456b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (cmd->name[0] == letter || cmd->name[0] == letter - 0x20) {
457b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				strcat(buf+row*80, cmd->name);
458b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pad = 18 * (col + 1) - strlen(buf+row*80);
459b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (pad < 1)
460b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					pad = 1;
461b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				for (; pad; pad--)
462b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					strcat(buf+row*80, " ");
463b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				row++;
464b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (row == nrows) {
465b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					col++; row = 0;
466b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				}
467b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
468b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
469b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
470b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (row = 0; row < nrows; row++)
471b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s\n", buf+row*80);
472b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
473b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("\n");
474b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	free(buf);
475b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (0);
476b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
477b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
478b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
479b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_cmds_usage(cmd_t *port_cmds)
480b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
481b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	cmd_t *port_cmd;
482b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	cmd_t *cmd;
483b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
484b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* print usage of port commands */
485b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (port_cmd = port_cmds; port_cmd && port_cmd->name; port_cmd++)
486b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Check for wc_cmd */
487b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		dhd_cmd_usage(port_cmd);
488b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
489b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* print usage of common commands without port counterparts */
490b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (cmd = dhd_cmds; cmd->name; cmd++) {
491b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* search if port counterpart exists */
492b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (port_cmd = port_cmds; port_cmd && port_cmd->name; port_cmd++)
493b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!strcmp(port_cmd->name, cmd->name))
494b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
495b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!port_cmd || !port_cmd->name)
496b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			dhd_cmd_usage(cmd);
497b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
498b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
499b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
500b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
501b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_usage(cmd_t *port_cmds)
502b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
503b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr,
504b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        "Usage: %s [-a|i <adapter>] [-h] [-d|u|x] <command> [arguments]\n",
505b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		dhdu_av0);
506b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
507b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "\n");
508b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "  -h		this message\n");
509b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "  -a, -i	adapter name or number\n");
510b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "  -d		display values as signed integer\n");
511b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "  -u		display values as unsigned integer\n");
512b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "  -x		display values as hexdecimal\n");
513b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "\n");
514b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
515b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	dhd_cmds_usage(port_cmds);
516b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
517b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
518b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
519b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_check(void *dhd)
520b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
521b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
522b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int val;
523b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
52438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get(dhd, DHD_GET_MAGIC, &val, sizeof(int))) < 0)
525b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return ret;
526b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (val != DHD_IOCTL_MAGIC)
527b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return -1;
52838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get(dhd, DHD_GET_VERSION, &val, sizeof(int))) < 0)
529b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return ret;
530b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (val > DHD_IOCTL_VERSION) {
531b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Version mismatch, please upgrade\n");
532b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return -1;
533b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
534b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
535b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
536b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
537b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
538b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_printint(int val)
539b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
540b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	switch (int_fmt) {
541b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case INT_FMT_UINT:
542b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%u\n", val);
543b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
544b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case INT_FMT_HEX:
545b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("0x%x\n", val);
546b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
547b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case INT_FMT_DEC:
548b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	default:
549b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%d\n", val);
550b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
551b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
552b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
553b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
554b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* pretty hex print a contiguous buffer (tweaked from wlu) */
555b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
556b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_hexdump(uchar *buf, uint nbytes, uint saddr)
557b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
558b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char line[256];
559b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char* p;
560b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint i;
561b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
562b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (nbytes == 0) {
563b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("\n");
564b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return;
565b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
566b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
567b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = line;
568b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < nbytes; i++) {
569b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (i % 16 == 0) {
570b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += sprintf(p, "%08x: ", saddr + i);	/* line prefix */
571b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
572b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p += sprintf(p, "%02x ", buf[i]);
573b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (i % 16 == 15) {
574b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			uint j;
575b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += sprintf(p, "  ");
576b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			for (j = i-15; j <= i; j++)
577b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				p += sprintf(p, "%c",
578b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				             ((buf[j] >= 0x20 && buf[j] <= 0x7f) ? buf[j] : '.'));
579b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("%s\n", line);		/* flush line */
580b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p = line;
581b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
582b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
583b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
584b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* flush last partial line */
585b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (p != line)
586b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s\n", line);
587b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
588b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
589b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
590b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef SDTEST
591b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
592b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_pktgen(void *dhd, cmd_t *cmd, char **argv)
593b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
594b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret = 0;
595b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *ptr = NULL;
596b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	dhd_pktgen_t pktgen;
597b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *str;
598b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
599b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(dhd);
600b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
601b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
602b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Get current settings */
603b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((ret = dhd_var_getbuf(dhd, "pktgen", NULL, 0, &ptr)) != 0)
604b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return ret;
605b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memcpy(&pktgen, ptr, sizeof(pktgen));
606b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
607b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pktgen.version != DHD_PKTGEN_VERSION) {
608b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "pktgen version mismatch (module %d app %d)\n",
609b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        pktgen.version, DHD_PKTGEN_VERSION);
61038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_ERROR;
611b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
612b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
613b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Presence of args implies a set, else a get */
614b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*++argv) {
615b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		miniopt_t opts;
616b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		int opt_err;
617b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
618b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Initialize option parser */
619b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		miniopt_init(&opts, "pktgen", "", FALSE);
620b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
621b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		while ((opt_err = miniopt(&opts, argv)) != -1) {
622b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (opt_err == 1) {
623b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "pktgen options error\n");
624b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
625b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
626b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
627b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			argv += opts.consumed;
628b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
629b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!opts.good_int && opts.opt != 'd') {
630b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "invalid integer %s\n", opts.valstr);
631b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
632b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
633b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
634b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
635b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			switch (opts.opt) {
636b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'f':
637b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.freq = opts.uval;
638b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
639b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'c':
640b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.count = opts.uval;
641b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
642b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'p':
643b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.print = opts.uval;
644b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
645b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 't':
646b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.total = opts.uval;
647b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
648b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 's':
649b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.stop = opts.uval;
650b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
651b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'm':
652b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.minlen = opts.uval;
653b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
654b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'M':
655b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.maxlen = opts.uval;
656b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
657b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'l': case 'L':
658b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				pktgen.minlen = pktgen.maxlen = opts.uval;
659b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
660b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			case 'd':
661b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (!strcmp(opts.valstr, "send"))
662b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					pktgen.mode = DHD_PKTGEN_SEND;
663b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				else if (!strcmp(opts.valstr, "echo"))
664b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					pktgen.mode = DHD_PKTGEN_ECHO;
665b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				else if (!strcmp(opts.valstr, "burst"))
666b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					pktgen.mode = DHD_PKTGEN_RXBURST;
667b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				else if (!strcmp(opts.valstr, "recv"))
668b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					pktgen.mode = DHD_PKTGEN_RECV;
669b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				else {
670b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					fprintf(stderr, "unrecognized dir mode %s\n",
671b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					        opts.valstr);
67238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					return BCME_USAGE_ERROR;
673b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				}
674b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				break;
675b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
676b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			default:
677b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "option parsing error (key %s valstr %s)\n",
678b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        opts.key, opts.valstr);
67938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				ret = BCME_USAGE_ERROR;
680b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
681b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
682b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
683b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
684b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (pktgen.maxlen < pktgen.minlen) {
685b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "min/max error (%d/%d)\n", pktgen.minlen, pktgen.maxlen);
686b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
687b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
688b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
689b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
690b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Set the new values */
691b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setbuf(dhd, "pktgen", &pktgen, sizeof(pktgen));
692b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
693b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Counts: %d send attempts, %d received, %d tx failures\n",
694b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		       pktgen.numsent, pktgen.numrcvd, pktgen.numfail);
695b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
696b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
697b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Show configuration in either case */
698b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	switch (pktgen.mode) {
699b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case DHD_PKTGEN_ECHO: str = "echo"; break;
700b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case DHD_PKTGEN_SEND: str = "send"; break;
701b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case DHD_PKTGEN_RECV: str = "recv"; break;
702b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case DHD_PKTGEN_RXBURST: str = "burst"; break;
703b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	default: str = "UNKNOWN"; break;
704b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
705b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
706b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("Config: mode %s %d pkts (len %d-%d) each %d ticks\n",
707b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	       str, pktgen.count, pktgen.minlen, pktgen.maxlen, pktgen.freq);
708b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
709b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Second config line for optional items */
710b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	str = "        ";
711b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pktgen.total) {
712b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%slimit %d", str, pktgen.total);
713b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str = ", ";
714b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
715b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pktgen.print) {
716b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%sprint every %d ticks", str, (pktgen.freq * pktgen.print));
717b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str = ", ";
718b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
719b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pktgen.stop) {
720b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%sstop after %d tx failures", str, pktgen.stop);
721b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str = ", ";
722b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
723b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (str[0] == ',')
724b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("\n");
725b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
726b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtexit:
727b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
728b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
729b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* SDTEST */
730b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
731b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic dbg_msg_t dhd_sd_msgs[] = {
732b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_ERROR_VAL,	"error"},
733b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_TRACE_VAL,	"trace"},
734b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_INFO_VAL,	"info"},
735b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_DATA_VAL,	"data"},
736b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_CTRL_VAL,	"control"},
737b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_LOG_VAL,	"log"},
738b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{SDH_DMA_VAL,	"dma"},
739b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{0,		NULL}
740b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
741b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
742b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
743b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sd_msglevel(void *dhd, cmd_t *cmd, char **argv)
744b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
745b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return dhd_do_msglevel(dhd, cmd, argv, dhd_sd_msgs);
746b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
747b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
748b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
749b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sd_blocksize(void *dhd, cmd_t *cmd, char **argv)
750b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
751b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
752b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int argc;
753b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
754b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *ptr = NULL;
755b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int func, size;
756b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
757b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
758b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
759b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
760b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
761b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc < 1 || argc > 2) {
762b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("required args: function [size] (size 0 means max)\n");
76338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
764b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
765b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
766b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	func = strtol(argv[1], &endptr, 0);
767b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*endptr != '\0') {
768b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Invalid function: %s\n", argv[1]);
76938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
770b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
771b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
772b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc > 1) {
773b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		size = strtol(argv[2], &endptr, 0);
774b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
775b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Invalid size: %s\n", argv[1]);
77638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
777b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
778b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
779b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
780b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc == 1) {
781b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = dhd_var_getbuf(dhd, cmd->name, &func, sizeof(func), &ptr)) >= 0)
782b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Function %d block size: %d\n", func, *(int*)ptr);
783b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
784b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Setting function %d block size to %d\n", func, size);
785b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		size &= 0x0000ffff; size |= (func << 16);
786b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setbuf(dhd, cmd->name, &size, sizeof(size));
787b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
788b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
789b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
790b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
791b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
792b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
793b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sd_mode(void *wl, cmd_t *cmd, char **argv)
794b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
795b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
796b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int argc;
797b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int sdmode;
798b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
799b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
800b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
801b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
802b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
803b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
804b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!strcmp(argv[1], "spi")) {
805b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "0");
806b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "sd1")) {
807b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "1");
808b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "sd4")) {
809b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "2");
810b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
81138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
812b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
813b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
814b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setint(wl, cmd, argv);
815b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
816b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
817b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = dhd_var_get(wl, cmd, argv))) {
818b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (ret);
819b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
820b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			sdmode = *(int32*)buf;
821b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
822b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("SD Mode is: %s\n",
823b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       sdmode == 0 ? "SPI"
824b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       : sdmode == 1 ? "SD1"
825b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				   : sdmode == 2 ? "SD4" : "Unknown");
826b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
827b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
828b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
829b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
830b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
831b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
832b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
833b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_dma_mode(void *wl, cmd_t *cmd, char **argv)
834b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
835b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
836b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int argc;
837b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int dmamode;
838b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
839b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
840b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
841b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
842b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
843b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
844b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!stricmp(argv[1], "pio")) {
845b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "0");
846b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "0")) {
847b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!stricmp(argv[1], "dma")) {
848b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "1");
849b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!stricmp(argv[1], "sdma")) {
850b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "1");
851b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "1")) {
852b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!stricmp(argv[1], "adma1")) {
853b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "2");
854b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!stricmp(argv[1], "adma")) {
855b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "3");
856b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!stricmp(argv[1], "adma2")) {
857b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(argv[1], "3");
858b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
85938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
860b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
861b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
862b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setint(wl, cmd, argv);
863b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
864b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
865b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = dhd_var_get(wl, cmd, argv))) {
866b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (ret);
867b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
868b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			dmamode = *(int32*)buf;
869b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
870b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("DMA Mode is: %s\n",
871b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       dmamode == 0 ? "PIO"
872b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       : dmamode == 1 ? "SDMA"
873b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       : dmamode == 2 ? "ADMA1"
874b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       : dmamode == 3 ? "ADMA2"
875b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			       : "Unknown");
876b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
877b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
878b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
879b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
880b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
881b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
882b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
883b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
884b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sdreg(void *dhd, cmd_t *cmd, char **argv)
885b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
886b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
887b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	sdreg_t sdreg;
888b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
889b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *ptr = NULL;
890b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
891b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
892b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
893b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bzero(&sdreg, sizeof(sdreg));
894b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
895b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
896b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
897b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
898b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
899b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* required args: offset (will default size) */
900b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc < 1) {
901b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("required args: offset[/size] [value]\n");
90238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
903b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
904b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
905b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	sdreg.offset = strtoul(argv[1], &ptr, 0);
906b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*ptr && *ptr != '/') {
907b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Bad arg: %s\n", argv[1]);
90838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
909b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
910b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
911b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read optional /size */
912b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*ptr == '/') {
913b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sdreg.func = strtol((ptr+1), &ptr, 0);
914b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*ptr || ((sdreg.func != 2) && sdreg.func != 4)) {
915b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Bad size option?\n");
91638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
917b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
918b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
919b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else {
920b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sdreg.func = 4;
921b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Defaulting to register size 4\n");
922b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
923b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
924b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc > 1) {
925b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sdreg.value = strtoul(argv[2], &ptr, 0);
926b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*ptr) {
927b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Bad value: %s\n", argv[2]);
92838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
929b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
930b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
931b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
932b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc <= 1) {
933b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_getbuf(dhd, argv[0], &sdreg, sizeof(sdreg), (void**)&ptr);
934b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret >= 0)
935b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("0x%0*x\n", (2 * sdreg.func), *(int *)ptr);
936b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
937b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setbuf(dhd, argv[0], &sdreg, sizeof(sdreg));
938b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
939b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
940b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
941b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
942b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
943b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
944b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_membytes(void *dhd, cmd_t *cmd, char **argv)
945b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
946b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret = -1;
947b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
948b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *ptr;
949b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int params[2];
950b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint addr;
951b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
952b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int align;
953b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
954b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int rawout, hexin;
955b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
956b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_t opts;
957b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int opt_err;
958b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
959b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Parse command-line options */
960b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_init(&opts, "membytes", "rh", FALSE);
961b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
962b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	rawout = hexin = 0;
963b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
964b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argv++;
965b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
966b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opt_err == 1) {
967b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "membytes options error\n");
968b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
969b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
970b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
971b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
972b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opts.positional)
973b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
974b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
975b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv += opts.consumed;
976b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
977b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opts.opt == 'h') {
978b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			hexin = 1;
979b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (opts.opt == 'r') {
980b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			rawout = 1;
981b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
982b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "membytes command error\n");
983b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
984b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
985b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
986b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
987b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
988b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
989b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
990b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
991ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* required args: address size [<data>]] */
992b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc < 2) {
993ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fprintf(stderr, "required args: address size [<data>]\n");
99438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
995b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
996ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
997b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc < 3 && hexin) {
998ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fprintf(stderr, "missing <data> required by -h\n");
99938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
1000b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1001b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((argc > 2) && (rawout)) {
1002ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fprintf(stderr, "can't have <data> arg with -r\n");
100338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
1004b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1005b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1006b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read address */
1007b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	addr = strtoul(argv[0], &ptr, 0);
1008b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*ptr) {
1009b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Bad arg: %s\n", argv[0]);
101038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
1011b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1012b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1013b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read size */
1014b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strtoul(argv[1], &ptr, 0);
1015b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*ptr) {
1016b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Bad value: %s\n", argv[1]);
101738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
1018b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1019b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1020b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	align = addr & 0x03;
1021b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (align && argc > 2) {
1022b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Can only write starting at long-aligned addresses.\n");
102338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
1024b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1025b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1026b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* get can just use utility function, set must copy custom buffer */
1027b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc == 2) {
1028ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* Read */
1029b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint chunk = DHD_IOCTL_MAXLEN;
1030b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (addr -= align, len += align; len; addr += chunk, len -= chunk, align = 0) {
1031b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			chunk = MIN(chunk, len);
1032ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			params[0] = addr;
1033ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			params[1] = ROUNDUP(chunk, 4);
1034b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = dhd_var_getbuf(dhd, "membytes",
1035b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			                     params, (2 * sizeof(int)), (void**)&ptr);
1036b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (ret < 0)
1037b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1038b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1039b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (rawout) {
1040b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fwrite(ptr + align, sizeof(char), chunk - align, stdout);
1041b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else {
1042b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				dhd_hexdump((uchar*)ptr + align, chunk - align, addr + align);
1043b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1044b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1045b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
1046ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* Write */
1047b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint patlen = strlen(argv[2]);
1048b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint chunk, maxchunk;
1049b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		char *sptr;
1050b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1051b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (hexin) {
1052b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			char *inptr, *outptr;
1053b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (patlen & 1) {
1054b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Hex (-h) must consist of whole bytes\n");
105538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				ret = BCME_USAGE_ERROR;
1056b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1057b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1058b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1059b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			for (inptr = outptr = argv[2]; patlen; patlen -= 2) {
1060b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				int n1, n2;
1061b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1062b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				n1 = (int)((unsigned char)*inptr++);
1063b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				n2 = (int)((unsigned char)*inptr++);
1064b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (!isxdigit(n1) || !isxdigit(n2)) {
1065b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					fprintf(stderr, "invalid hex digit %c\n",
1066b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					        (isxdigit(n1) ? n2 : n1));
106738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					ret = BCME_USAGE_ERROR;
1068b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					goto exit;
1069b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				}
1070b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				n1 = isdigit(n1) ? (n1 - '0')
1071b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        : ((islower(n1) ? (toupper(n1)) : n1) - 'A' + 10);
1072b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				n2 = isdigit(n2) ? (n2 - '0')
1073b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        : ((islower(n2) ? (toupper(n2)) : n2) - 'A' + 10);
1074b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				*outptr++ = (n1 * 16) + n2;
1075b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1076b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1077b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			patlen = outptr - argv[2];
1078b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1079b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1080b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sptr = argv[2];
1081b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		maxchunk = DHD_IOCTL_MAXLEN - (strlen(cmd->name) + 1 + (2 * sizeof(int)));
1082b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1083b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		while (len) {
1084b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			chunk = (len > maxchunk) ? (maxchunk & ~0x3) : len;
1085b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1086b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			/* build the iovar command */
1087b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memset(buf, 0, DHD_IOCTL_MAXLEN);
1088b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(buf, cmd->name);
1089b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ptr = buf + strlen(buf) + 1;
1090b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			params[0] = addr; params[1] = chunk;
1091b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(ptr, params, (2 * sizeof(int)));
1092b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ptr += (2 * sizeof(int));
1093b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			addr += chunk; len -= chunk;
1094b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1095b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			while (chunk--) {
1096b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				*ptr++ = *sptr++;
1097b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (sptr >= (argv[2] + patlen))
1098b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					sptr = argv[2];
1099b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1101b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = dhd_set(dhd, DHD_SET_VAR, &buf[0], (ptr - buf));
1102b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (ret < 0)
1103b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1104b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1105b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1106b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1107b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtexit:
1108b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
1109b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1110b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1111b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1112b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_idletime(void *dhd, cmd_t *cmd, char **argv)
1113b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1114b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int32 idletime;
1115b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
1116b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int err = 0;
1117b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
1119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!strcmp(argv[1], "never")) {
1120b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idletime = 0;
1121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "immediate") || !strcmp(argv[1], "immed")) {
1122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idletime = DHD_IDLE_IMMEDIATE;
1123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idletime = strtol(argv[1], &endptr, 0);
1125b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (*endptr != '\0') {
1126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "invalid number %s\n", argv[1]);
112738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				err = BCME_USAGE_ERROR;
1128b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1129b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1130b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((idletime < 0) && (idletime != DHD_IDLE_IMMEDIATE)) {
1131b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "invalid value %s\n", argv[1]);
1132b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			err = -1;
1133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1135b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!err) {
1136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(buf, "idletime");
1137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			endptr = buf + strlen(buf) + 1;
1138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(endptr, &idletime, sizeof(uint32));
1139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			endptr += sizeof(uint32);
1140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			err = dhd_set(dhd, DHD_SET_VAR, &buf[0], (endptr - buf));
1141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
1143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((err = dhd_var_get(dhd, cmd, argv))) {
1144b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return err;
1145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idletime = *(int32*)buf;
1147b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (idletime == 0) {
1149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("0 (never)\n");
1150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else if (idletime == DHD_IDLE_IMMEDIATE) {
1151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("-1 (immediate)\n");
1152b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else if (idletime > 0) {
1153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("%d\n", idletime);
1154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else printf("%d (invalid)\n", idletime);
1155b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1157b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return err;
1158b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1159b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1160b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1161b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_idleclock(void *dhd, cmd_t *cmd, char **argv)
1162b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1163b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int32 idleclock;
1164b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
1165b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int err = 0;
1166b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1167b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
1168b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!strcmp(argv[1], "active")) {
1169b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idleclock = DHD_IDLE_ACTIVE;
1170b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!strcmp(argv[1], "stopped")) {
1171b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idleclock = DHD_IDLE_STOP;
1172b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1173b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idleclock = strtol(argv[1], &endptr, 0);
1174b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (*endptr != '\0') {
1175b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "invalid number %s\n", argv[1]);
117638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				err = BCME_USAGE_ERROR;
1177b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1178b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1179b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1180b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!err) {
1181b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			strcpy(buf, "idleclock");
1182b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			endptr = buf + strlen(buf) + 1;
1183b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(endptr, &idleclock, sizeof(int32));
1184b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			endptr += sizeof(int32);
1185b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			err = dhd_set(dhd, DHD_SET_VAR, &buf[0], (endptr - buf));
1186b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1187b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
1188b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((err = dhd_var_get(dhd, cmd, argv))) {
1189b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return err;
1190b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1191b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			idleclock = *(int32*)buf;
1192b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1193b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (idleclock == DHD_IDLE_ACTIVE)
1194b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("Idleclock %d (active)\n", idleclock);
1195b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			else if (idleclock == DHD_IDLE_STOP)
1196b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("Idleclock %d (stopped)\n", idleclock);
1197b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			else
1198b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("Idleclock divisor %d\n", idleclock);
1199b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1200b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1201b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return err;
1202b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1203b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1204b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Word count for a 4kb SPROM */
1205b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define SPROM_WORDS 256
1206b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1207b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1208b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sprom(void *dhd, cmd_t *cmd, char **argv)
1209b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1210b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
1211b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (-1);
1212b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#else
1213b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret, i;
1214b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
1215b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr;
1216b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *bufp, *countptr;
1217b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint16 *wordptr;
1218b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint offset, words, bytes;
1219b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool nocrc = FALSE;
1220b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1221b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *fname;
1222b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp;
1223b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1224b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
1225b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1226b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
1227b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
1228b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
1229b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1230b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* init buffer */
1231b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bufp = buf;
1232b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memset(bufp, 0, DHD_IOCTL_MAXLEN);
1233b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(bufp, "sprom");
1234b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bufp += strlen("sprom") + 1;
1235b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1236b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (strcmp(argv[0], "srdump") == 0) {
1237b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (argc) {
1238b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "Command srdump doesn't take args\n");
123938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
1240b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1241b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset = 0;
1242b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		words = SPROM_WORDS;
1243b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bytes = 2 * words;
1244b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1245b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(bufp, &offset, sizeof(int));
1246b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += sizeof(int);
1247b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(bufp, &bytes, sizeof(int));
1248b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += sizeof(int);
1249b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1250b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) {
1251b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "Internal error: unaligned word buffer\n");
125238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_ERROR;
1253b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1254b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
1255b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (strcmp(argv[0], "srwrite") != 0) {
1256b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "Unimplemented sprom command: %s\n", argv[0]);
125738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
1258b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1259b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1260b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (argc == 0) {
126138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
1262b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if ((argc == 1) ||
1263b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		           ((argc == 2) && ((nocrc = !strcmp(argv[1], "-c"))))) {
1264b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1265b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fname = nocrc ? argv[2] : argv[1];
1266b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1267b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			/* determine and validate file size */
1268b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if ((ret = file_size(fname)) < 0)
126938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1270b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1271b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bytes = ret;
1272b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			offset = 0;
1273b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			words = bytes / 2;
1274b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1275b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (bytes != 2 * SPROM_WORDS) {
1276b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Bad file size\n");
127738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1278b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1279b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1280b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(bufp, &offset, sizeof(int));
1281b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bufp += sizeof(int);
1282b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(bufp, &bytes, sizeof(int));
1283b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bufp += sizeof(int);
1284b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1285b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) {
1286b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Internal error: unaligned word buffer\n");
128738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1288b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1289b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1290b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if ((fp = fopen(fname, "rb")) == NULL) {
1291b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Could not open %s: %s\n",
1292b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        fname, strerror(errno));
129338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1294b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1295b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1296b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (fread((uint16*)bufp, sizeof(uint16), words, fp) != words) {
1297b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Could not read %d bytes from %s\n",
1298b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        words * 2, fname);
1299b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fclose(fp);
130038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1301b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1302b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1303b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fclose(fp);
1304b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1305b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!nocrc &&
1306b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			    hndcrc8((uint8*)bufp, bytes, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
1307b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "CRC check failed: 0x%02x, should be 0x%02x.\n",
1308b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        ((uint8*)bufp)[bytes-1],
1309b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        ~hndcrc8((uint8*)bufp, bytes - 1, CRC8_INIT_VALUE) & 0xff);
131038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1311b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1312b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1313b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ltoh16_buf(bufp, bytes);
1314b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1315b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			offset = strtoul(*++argv, &endptr, 0) * 2;
1316b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (*endptr != '\0') {
1317b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "offset %s is not an integer\n", *argv);
131838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_USAGE_ERROR;
1319b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1320b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1321b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(bufp, &offset, sizeof(int));
1322b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bufp += sizeof(int);
1323b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			countptr = bufp;
1324b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bufp += sizeof(int);
1325b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1326b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!ISALIGNED((uintptr)bufp, sizeof(uint16))) {
1327b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "Internal error: unaligned word buffer\n");
132838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return BCME_ERROR;
1329b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1330b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1331b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			for (words = 0, wordptr = (uint16*)bufp; *++argv; words++) {
1332b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				*wordptr++ = (uint16)strtoul(*argv, &endptr, 0);
1333b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (*endptr != '\0') {
1334b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					fprintf(stderr, "value %s is not an integer\n", *argv);
133538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					return BCME_USAGE_ERROR;
1336b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				}
1337b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (words > SPROM_WORDS) {
1338b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					fprintf(stderr, "max of %d words\n", SPROM_WORDS);
133938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					return BCME_USAGE_ERROR;
1340b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				}
1341b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1342b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1343b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bytes = 2 * words;
1344b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			memcpy(countptr, &bytes, sizeof(int));
1345b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1346b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1347b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1348b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc) {
1349b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_set(dhd, DHD_SET_VAR, buf,
1350b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		              (strlen("sprom") + 1) + (2 * sizeof(int)) + bytes);
1351b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (ret);
1352b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
1353b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_get(dhd, DHD_GET_VAR, buf,
1354b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		              (strlen("sprom") + 1) + (2 * sizeof(int)) + bytes);
1355b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret < 0) {
1356b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return ret;
1357b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1358b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1359b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (i = 0; i < (int)words; i++) {
1360b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if ((i % 8) == 0)
1361b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf("\n  srom[%03d]:  ", i);
1362b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("0x%04x  ", ((uint16*)buf)[i]);
1363b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1364b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("\n");
1365b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1366b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1367b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
1368b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
1369b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1370b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1371b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
1372b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * read_vars: reads an environment variables file into a buffer,
1373b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * reformatting them and returning the length (-1 on error).
1374b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1375b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * The input text file consists of lines of the form "<var>=<value>\n".
1376b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * CRs are ignored, as are blank lines and comments beginning with '#'.
1377b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1378b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * The output buffer consists of blocks of the form "<var>=<value>\0"
1379b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * (the newlines have been replaced by NULs)
1380b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1381b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Todo: allow quoted variable names and quoted values.
1382b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*/
1383b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1384b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BWL_FILESYSTEM_SUPPORT)
1385b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1386b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtread_vars(char *fname, char *buf, int buf_maxlen)
1387b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1388b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp;
1389b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int buf_len, slen;
1390b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char line[256], *s, *e;
1391b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int line_no = 0;
1392b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1393b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fp = fopen(fname, "rb")) == NULL) {
1394b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "Cannot open NVRAM file %s: %s\n",
1395b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        fname, strerror(errno));
1396b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		exit(1);
1397b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1398b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1399b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	buf_len = 0;
1400b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1401b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (fgets(line, sizeof(line), fp) != NULL) {
1402b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bool found_eq = FALSE;
1403b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1404b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Ensure line length is limited */
1405b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		line[sizeof(line) - 1] = 0;
1406b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1407b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Skip any initial white space */
1408b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (s = line; *s == ' ' || *s == '\t'; s++)
1409b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			;
1410b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1411b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Determine end of string */
1412b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (e = s; *e != 0 && *e != '#' && *e != '\r' && *e != '\n'; e++)
1413b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (*e == '=')
1414b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				found_eq = TRUE;
1415b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1416b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Strip any white space from end of string */
1417b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		while (e > s && (e[-1] == ' ' || e[-1] == '\t'))
1418b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			e--;
1419b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1420b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		slen = e - s;
1421b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1422b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Skip lines that end up blank */
1423b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (slen == 0)
1424b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
1425b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1426b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!found_eq) {
1427b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "Invalid line %d in NVRAM file %s\n", line_no, fname);
1428b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fclose(fp);
1429b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return -1;
1430b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1431b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1432b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (buf_len + slen + 1 > buf_maxlen) {
1433b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "NVRAM file %s too long\n", fname);
1434b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fclose(fp);
1435b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return -1;
1436b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1437b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1438b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(buf + buf_len, s, slen);
1439b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf_len += slen;
1440b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf[buf_len++] = 0;
1441b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1442b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1443b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fclose(fp);
1444b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1445b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return buf_len;
1446b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1447b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif   /* BWL_FILESYSTEM_SUPPORT */
1448b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1449b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1450b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_vars(void *dhd, cmd_t *cmd, char **argv)
1451b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1452b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
1453b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
1454b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *bufp;
1455b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1456b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
1457b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1458b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
1459b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
1460b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
1461b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1462b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	switch (argc) {
1463b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case 0: /* get */
1464b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{
1465b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = dhd_var_getbuf(dhd, "vars", NULL, 0, (void**)&bufp)))
1466b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1467b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		while (*bufp) {
1468b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("%s\n", bufp);
1469b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bufp += strlen(bufp) + 1;
1470b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1471b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1472b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	break;
1473b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1474b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BWL_FILESYSTEM_SUPPORT)
1475b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case 1: /* set */
1476b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{
1477b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		char *vname;
1478b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint nvram_len;
1479b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1480b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		vname = argv[1];
1481b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1482b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp = buf;
1483b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		strcpy(bufp, "vars");
1484b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += strlen("vars") + 1;
1485b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1486b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = read_vars(vname, bufp,
1487b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		                           DHD_IOCTL_MAXLEN - (strlen("vars") + 3))) < 0) {
1488b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1489b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1490b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1491b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1492b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		nvram_len = ret;
1493b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += nvram_len;
1494b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*bufp++ = 0;
1495b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1496b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_set(dhd, DHD_SET_VAR, buf, bufp - buf);
1497b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1498b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	break;
1499b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif   /* BWL_FILESYSTEM_SUPPORT */
1500b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1501b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	default:
1502b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
1503b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
1504b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1505b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1506b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
1507b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1508b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1509b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define MEMBLOCK 2048
1510b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1511b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Check that strlen("membytes")+1 + 2*sizeof(int32) + MEMBLOCK <= DHD_IOCTL_MAXLEN */
1512b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if (MEMBLOCK + 17 > DHD_IOCTL_MAXLEN)
1513b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#error MEMBLOCK/DHD_IOCTL_MAXLEN sizing
1514b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
1515b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1516b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1517b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BWL_FILESYSTEM_SUPPORT)
1518b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1519ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtdhd_verify_file_bytes(void *dhd, uint8 *memblock, int start, uint len)
1520ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
1521ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int ret = 0;
1522ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint i = 0;
1523ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	char *ptr;
1524ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int params[2];
1525ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 *src, *dst;
1526ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1527ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	params[0] = start;
1528ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	params[1] = len;
1529ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
1530ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (ret) {
1531ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fprintf(stderr, "%s: failed reading %d membytes from 0x%08x\n",
1532ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		__FUNCTION__, len, start);
153338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return ret;
1534ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1535ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1536ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	src = (uint8 *)memblock;
1537ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	dst = (uint8 *)ptr;
1538ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while (i < len) {
1539ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (src[i] != dst[i]) {
1540ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr, "   0x%x: exp[0x%02X] != got[0x%02X]\n",
1541ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				start+i, src[i], dst[i]);
1542ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			ret = -1;
1543ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1544ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		i++;
1545ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1546ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1547ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return ret;
1548ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
1549ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1550ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtstatic int
1551ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtdhd_load_file_bytes(void *dhd, cmd_t *cmd, FILE *fp, int fsize, int start, uint blk_sz, bool verify)
1552b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1553b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int tot_len = 0;
1554b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint read_len;
1555b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *bufp;
1556b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
1557b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 memblock[MEMBLOCK];
1558b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
1559ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int retry;
1560b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1561b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
1562b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1563ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (!fsize || !fp)
1564ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return -1;
1565ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1566ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	assert(blk_sz <= MEMBLOCK);
1567ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1568b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (tot_len < fsize) {
1569b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		read_len = fsize - tot_len;
1570ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (read_len >= blk_sz) {
1571ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			read_len = blk_sz;
1572ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1573ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (!ISALIGNED(start, MEMBLOCK))
1574ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				read_len = ROUNDUP(start, MEMBLOCK) - start;
1575ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1576ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1577b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len = fread(memblock, sizeof(uint8), read_len, fp);
1578b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((len < read_len) && !feof(fp)) {
1579b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error reading file\n", __FUNCTION__);
1580b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return -1;
1581b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1582b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1583ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		retry = 0;
1584ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtfailed_retry:
1585b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1586b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp = buf;
1587b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memset(bufp, 0, DHD_IOCTL_MAXLEN);
1588b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		strcpy(bufp, "membytes");
1589b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += strlen("membytes") + 1;
1590b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(bufp, &start, sizeof(int));
1591b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += sizeof(int);
1592b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(bufp, &len, sizeof(int));
1593b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += sizeof(int);
1594b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(bufp, memblock, len);
1595b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1596b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_set(dhd, DHD_SET_VAR, &buf[0], (bufp - buf + len));
1597b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1598b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret) {
1599b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error %d on writing %d membytes at 0x%08x\n",
1600b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__, ret, len, start);
160138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return ret;
1602b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1603ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1604ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (verify == TRUE) {
1605ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (dhd_verify_file_bytes(dhd, memblock, start, len) != 0) {
1606ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				if (retry++ < 5000)
1607ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				{
1608ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					fprintf(stderr, "%s: verify failed %d membytes "
1609ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt						"from 0x%08x\n", __FUNCTION__, len, start);
1610ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					goto failed_retry;
1611ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				}
1612ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			}
1613ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1614ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1615b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		start += len;
1616b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		tot_len += len;
1617b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1618b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
1619b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1620b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif   /* BWL_FILESYSTEM_SUPPORT */
1621b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1622b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef PROP_TXSTATUS
1623b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1624b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_proptxstatusenable(void *dhd, cmd_t *cmd, char **argv)
1625b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1626b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int flag = 0xdead;
162738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
1628b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1629b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
1630b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		flag = atoi(argv[1]);
163138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_setint(dhd, cmd->name, flag);
1632b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1633b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else {
163438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_getint(dhd, cmd->name, &flag);
163538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret >= 0)
163638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			printf("proptxstatus: %d\n", flag);
1637b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
163838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
1639b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1640b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1641b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1642b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_proptxstatusmode(void *dhd, cmd_t *cmd, char **argv)
1643b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1644b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int mode = 0xdead;
164538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
1646b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1647b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1]) {
1648b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		mode = atoi(argv[1]);
164938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_setint(dhd, cmd->name, mode);
1650b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1651b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else {
165238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_getint(dhd, cmd->name, &mode);
165338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret >= 0)
165438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			printf("proptxstatusmode: %d\n", mode);
1655b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
165638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
1657b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
165838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
165938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int
166038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtdhd_proptxopt(void *dhd, cmd_t *cmd, char **argv)
166138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
166238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int flag = 0xdead;
166338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
166438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
166538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (argv[1]) {
166638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		flag = atoi(argv[1]);
166738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_setint(dhd, cmd->name, flag);
166838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
166938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	else {
167038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_iovar_getint(dhd, cmd->name, &flag);
167138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret >= 0)
167238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			printf("proptx_opt: %d\n", flag);
167338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
167438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
167538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
167638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
1677b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* PROP_TXSTATUS */
1678b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1679b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
168038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtdhd_get_ramstart(void *dhd, uint32 *ramstart)
168138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
168238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
168338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *ramstart_args[] = {"ramstart", NULL};
168438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
168538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Read the bus type the DHD driver is associated to */
168638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_var_get(dhd, NULL, ramstart_args)) != BCME_OK) {
168738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: error obtaining ramstart\n", __FUNCTION__);
168838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
168938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return ret;
169038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
169138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
169238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	*ramstart = *(uint32 *)buf;
169338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
169438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return BCME_OK;
169538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
169638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
169738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int
1698b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_download(void *dhd, cmd_t *cmd, char **argv)
1699b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1700b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
1701b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (-1);
1702b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#else
1703b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool reset = TRUE;
1704b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool run = TRUE;
1705ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	bool verify = FALSE;
1706b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *fname = NULL;
1707b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *vname = NULL;
170838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 start;
1709b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret = 0;
1710b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int fsize;
1711ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint32 bustype;
1712ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	long filepos;
1713ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1714b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp = NULL;
171538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 ramsize;
171638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *memszargs[] = { "ramsize", NULL };
1717ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1718b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *bufp;
1719ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1720b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_t opts;
1721b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int opt_err;
1722b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint nvram_len;
1723b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct trx_header trx_hdr;
1724ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint32 trx_hdr_len;
1725b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool trx_file = FALSE;
1726ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint memblock_sz = MEMBLOCK;
1727ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	bool embedded_ucode = FALSE;
1728b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1729b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
1730b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
173138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_ramstart(dhd, &start)) != BCME_OK)
173238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
173338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
1734b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Parse command-line options */
1735b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_init(&opts, "download", "", TRUE);
1736b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1737b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argv++;
1738b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
1739b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opt_err == 1) {
1740b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "download options error\n");
1741b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1742b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1743b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1744b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv += opts.consumed;
1745b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1746b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opts.opt == 'a') {
1747b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!opts.good_int) {
1748b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "invalid address %s\n", opts.valstr);
1749b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
1750b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1751b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1752b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			start = (uint32)opts.uval;
1753b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (opts.positional) {
1754b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (fname && vname) {
1755b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "extra positional arg, %s\n",
1756b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        opts.valstr);
1757b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
1758b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1759b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1760b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (fname)
1761b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				vname = opts.valstr;
1762b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			else
1763b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fname = opts.valstr;
1764b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!opts.opt) {
1765b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!strcmp(opts.key, "noreset")) {
1766b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				reset = FALSE;
1767b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else if (!strcmp(opts.key, "norun")) {
1768b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				run = FALSE;
1769ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			} else if (!strcmp(opts.key, "verify")) {
1770ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				verify = TRUE;
1771b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else {
1772b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "unrecognized option %s\n", opts.valstr);
1773b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
1774b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1775b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1776b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1777b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "unrecognized option %c\n", opts.opt);
1778b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1779b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1780b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1781b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1782b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1783b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate arguments */
1784b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!fname) {
1785b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "filename required\n");
1786b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
1787b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
1788b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1789b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1790b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate file size compared to memory size */
1791b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fsize = file_size(fname)) < 0) {
1792b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
1793b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
1794b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1795b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read the file and push blocks down to memory */
1796b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fp = fopen(fname, "rb")) == NULL) {
1797b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: unable to open %s: %s\n",
1798b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        __FUNCTION__, fname, strerror(errno));
1799b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
1800b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
1801b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1802b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Verify the file is a regular bin file or trx file */
1803b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{
1804b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint32 tmp_len;
1805ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		trx_hdr_len = sizeof(struct trx_header);
1806b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		tmp_len = fread(&trx_hdr, sizeof(uint8), trx_hdr_len, fp);
1807b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (tmp_len == trx_hdr_len) {
1808b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (trx_hdr.magic == TRX_MAGIC) {
1809b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				trx_file = TRUE;
1810ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				if (trx_hdr.flag_version & TRX_EMBED_UCODE)
1811ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					embedded_ucode = TRUE;
1812b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1813b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			else
1814b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fseek(fp, 0, SEEK_SET);
1815b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1816b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else
1817b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fseek(fp, 0, SEEK_SET);
1818b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1819b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1820ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Check on which bus the dhd driver is sitting. Downloading methodology differs from
1821ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 * USB to SDIO.
1822ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 */
1823ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{
1824ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		char* bustype_args[] = {"bustype", NULL};
1825ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1826ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* Read the bus type the DHD driver is associated to */
1827ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((ret = dhd_var_get(dhd, NULL, bustype_args))) {
1828ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr, "%s: error obtaining bustype\n", __FUNCTION__);
1829ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			goto exit;
1830ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1831ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1832ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		bustype = *(uint32*)buf;
1833b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1834b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1835ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (trx_file)
1836ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fsize = (int)(trx_hdr.offsets[0]);
1837b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1838ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (bustype == BUS_TYPE_SDIO) {
1839ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((ret = dhd_var_get(dhd, NULL, memszargs))) {
184038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "%s: error obtaining ramsize\n", __FUNCTION__);
1841ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			goto exit;
1842ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
184338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ramsize = *(uint32*)buf;
1844b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1845ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1846ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
184738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	BCM_REFERENCE(ramsize);
1848b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1849b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* do the download reset if not suppressed */
1850b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (reset) {
1851ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((ret = dhd_iovar_setint(dhd, "dwnldstate", TRUE))) {
1852b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: failed to put dongle in download mode\n",
1853b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__);
1854b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1855b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1856b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
185738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
185838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#define RDL_CHUNK	1500  /* size of each dl transfer */
1859b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1860ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (BUS_TYPE_USB == bustype) {
1861ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* store the cur pos pointing to base image which should be written */
1862ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		filepos = ftell(fp);
1863ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (filepos == -1) {
1864ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr, "%s: ftell failed.\n", __FUNCTION__);
1865ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1866ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1867ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* In case of USB, we need to write header information also to dongle. */
1868ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fseek(fp, 0, SEEK_SET);
1869ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1870ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* The file size is "base_image + TRX_Header_size" */
1871ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		fsize = (int)(trx_hdr.offsets[0] + sizeof(struct trx_header));
1872ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1873ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		memblock_sz = RDL_CHUNK;
1874ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1875ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1876b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1877b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Load the ram image */
187838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_load_file_bytes(dhd, cmd, fp, fsize, start, memblock_sz, verify))) {
1879b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: error loading the ramimage at addr 0x%x\n",
1880b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        __FUNCTION__, start);
1881b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
1882b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1883b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1884b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (trx_file) {
1885ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1886ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		filepos = ftell(fp);
1887ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (filepos == -1) {
1888ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr, "%s: ftell failed.\n", __FUNCTION__);
1889ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
1890ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1891ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (BUS_TYPE_SDIO == bustype) {
1892ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1893b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1894b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1895b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1896b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fclose(fp);
1897b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fp = NULL;
1898b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1899b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* download the vars file if specified */
1900b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (vname) {
1901b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp = buf;
1902b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		strcpy(bufp, "vars");
1903b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += strlen("vars") + 1;
1904b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1905b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = read_vars(vname, bufp,
1906b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		                           DHD_IOCTL_MAXLEN - (strlen("vars") + 3))) < 0) {
1907b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1908b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1909b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1910b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1911b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		nvram_len = ret;
1912b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufp += nvram_len;
1913b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*bufp++ = 0;
1914b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1915b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_set(dhd, DHD_SET_VAR, buf, (bufp - buf));
1916b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret) {
1917b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error %d on delivering vars\n",
1918b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__, ret);
1919b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1920b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1921b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1922b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1923b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* start running the downloaded code if not suppressed */
1924b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (run) {
1925ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((ret = dhd_iovar_setint(dhd, "dwnldstate", FALSE))) {
1926ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1927b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: failed to take dongle out of download mode\n",
1928b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__);
1929ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			/* USB Error return values */
1930ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (BUS_TYPE_USB == bustype) {
1931ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				if (ret == -1)
1932ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					fprintf(stderr, "%s: CPU is not in RUNNABLE State\n",
1933ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt						__FUNCTION__);
1934ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				else
1935ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					fprintf(stderr, "%s: Error in setting CPU to RUN mode.\n",
1936ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt						__FUNCTION__);
1937ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			}
1938b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1939b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1940b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1941ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (embedded_ucode) {
1942ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1943b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1944b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtexit:
1945b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fp)
1946b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fclose(fp);
1947b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1948b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
1949b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
1950b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1951b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1952b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
1953b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_dldn(void *dhd, cmd_t *cmd, char **argv)
1954b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1955b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
1956b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (-1);
1957b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#else
1958b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *fname = NULL;
195938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 start;
1960b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret = 0;
1961b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int fsize;
1962b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int fd = 0;
1963b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1964b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp = NULL;
196538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 ramsize;
1966b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1967b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
1968b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 memblock[MEMBLOCK];
1969b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1970b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_t opts;
1971b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int opt_err;
1972b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1973b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
1974b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1975b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Parse command-line options */
1976b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_init(&opts, "download", "", TRUE);
1977b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argv++;
1978b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1979b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
1980b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opt_err == 1) {
1981b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "download options error\n");
1982b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1983b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
1984b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1985b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv += opts.consumed;
1986b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1987b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opts.positional) {
1988b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (fname) {
1989b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "extra positional arg, %s\n",
1990b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				        opts.valstr);
1991b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
1992b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
1993b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
1994b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!fname)
1995b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fname = opts.valstr;
1996b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1997b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "unrecognized option %c\n", opts.opt);
1998b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
1999b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2000b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2001b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2002b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2003b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fd = dhd_set(dhd, DHD_DLDN_ST, NULL, 0);
2004b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fd < 0) {
2005b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2006b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2007b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2008b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2009b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate arguments */
2010b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!fname) {
2011b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "filename required\n");
2012b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2013b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2014b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2015b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2016b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate file size compared to memory size */
2017b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fsize = file_size(fname)) < 0) {
2018b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2019b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2020b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2021b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
202238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ramsize = 393216;
2023b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
202438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ramsize && ((uint32)fsize > ramsize)) {
2025b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: file %s too large (%d > %d)\n",
202638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		        __FUNCTION__, fname, fsize, ramsize);
2027b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2028b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2029b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2030b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2031b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read the file and push blocks down to memory */
2032b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fp = fopen(fname, "rb")) == NULL) {
2033b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: unable to open %s: %s\n",
2034b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        __FUNCTION__, fname, strerror(errno));
2035b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2036b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2037b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2038b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
203938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_ramstart(dhd, &start)) != BCME_OK)
204038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
204138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
2042b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((len = fread(memblock, sizeof(uint8), MEMBLOCK, fp))) {
2043b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len < MEMBLOCK && !feof(fp)) {
2044b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error reading file %s\n", __FUNCTION__, fname);
2045b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
2046b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2047b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2048b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2049b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_set(dhd, DHD_DLDN_WRITE, memblock, len);
2050b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret) {
2051b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error %d on writing %d membytes at 0x%08x\n",
2052b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__, ret, len, start);
2053b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2054b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2055b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2056b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		start += len;
2057b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2058b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2059b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!feof(fp)) {
2060b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: error reading file %s\n", __FUNCTION__, fname);
2061b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2062b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2063b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2064b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fclose(fp);
2065b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fp = NULL;
2066b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2067b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtexit:
2068b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fp)
2069b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fclose(fp);
2070b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2071b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fd)
207238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_set(dhd, DHD_DLDN_END, NULL, 0);
2073b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2074b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
2075b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
2076b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2077b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2078b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2079b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_upload(void *dhd, cmd_t *cmd, char **argv)
2080b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2081b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
2082b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (-1);
2083b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#else
2084b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *fname = NULL;
208538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 start;
2086b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint32 size = 0;
2087b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret = 0;
2088b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2089b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	FILE *fp;
209038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 ramsize;
209138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *memszargs[] = { "ramsize", NULL };
2092b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2093b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
2094b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2095b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_t opts;
2096b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int opt_err;
2097b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2098b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
2099b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(argv);
2100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
210138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_ramstart(dhd, &start)) != BCME_OK)
210238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
210338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
2104b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Parse command-line options */
2105b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	miniopt_init(&opts, "upload", "", TRUE);
2106b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2107b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argv++;
2108b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
2109b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opt_err == 1) {
2110b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "upload options error\n");
2111b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
2112b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2113b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2114b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv += opts.consumed;
2115b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2116b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (opts.opt == 'a') {
2117b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!opts.good_int) {
2118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "invalid address %s\n", opts.valstr);
2119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
2120b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
2121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
2122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			start = (uint32)opts.uval;
2123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (opts.positional) {
2124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!fname) {
2125b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fname = opts.valstr;
2126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else if (opts.good_int) {
2127b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				size = (uint32)opts.uval;
2128b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else {
2129b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				fprintf(stderr, "upload options error\n");
2130b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				ret = -1;
2131b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto exit;
2132b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
2133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (!opts.opt) {
2134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "unrecognized option %s\n", opts.valstr);
2135b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
2136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
2138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "unrecognized option %c\n", opts.opt);
2139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
2140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			goto exit;
2141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2144b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate arguments */
2145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!fname) {
2146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "filename required\n");
2147b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((ret = dhd_var_get(dhd, NULL, memszargs))) {
215238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: error obtaining ramsize\n", __FUNCTION__);
2153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
215538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ramsize = *(uint32*)buf;
2156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
215738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (!ramsize)
21581a98081b29afa74fb3af0699a2c2f0100257f3d5Ashwin		ramsize = size;
2159b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2160b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((fp = fopen(fname, "wb")) == NULL) {
2161b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: Could not open %s: %s\n",
2162b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		        __FUNCTION__, fname, strerror(errno));
2163b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = -1;
2164b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		goto exit;
2165b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2166b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2167b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* default size to full RAM */
2168b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!size)
21691a98081b29afa74fb3af0699a2c2f0100257f3d5Ashwin		size = ramsize;
2170b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2171b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* read memory and write to file */
2172b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (size) {
2173b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		char *ptr;
2174b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		int params[2];
2175b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2176b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len = MIN(MEMBLOCK, size);
2177b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2178b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		params[0] = start;
2179b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		params[1] = len;
2180b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
2181b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (ret) {
2182b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: failed reading %d membytes from 0x%08x\n",
2183b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			        __FUNCTION__, len, start);
2184b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
2185b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2186b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
218738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (fwrite(ptr, sizeof(char), len, fp) != len) {
2188b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "%s: error writing to file %s\n", __FUNCTION__, fname);
2189b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ret = -1;
2190b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
2191b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2192b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2193b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		start += len;
2194b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		size -= len;
2195b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2196b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2197b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fclose(fp);
2198b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtexit:
2199b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
2200b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
2201b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2202b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
220338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#ifdef BWL_FILESYSTEM_SUPPORT
220438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int
220538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtdhd_get_debug_info(void *dhd, hndrte_debug_t *debug_info)
220638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
220738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int i;
220838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
220938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int params[2];
221038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
221138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 *buffer;
221238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 debug_info_ptr;
221338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 ramstart;
221438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
221538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_ramstart(dhd, &ramstart)) != BCME_OK)
221638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return ret;
221738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
221838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/*
221938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	 * Different chips have different fixed debug_info_ptrs
222038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	 * because of different ROM locations/uses.  Try them all looking
222138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	 * for the magic number.
222238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	 */
222338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	for (i = 0; ; i++) {
222438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (debug_info_ptrs[i] == DEBUG_INFO_PTRS_END) {
222538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "Error: cannot find pointer to debug_info\n");
222638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return -1;
222738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
222838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
222938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[0] = debug_info_ptrs[i] + ramstart;
223038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[1] = 8;
223138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&buffer);
223238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if ((ret == 0) &&
223338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		    (*buffer == HNDRTE_DEBUG_PTR_PTR_MAGIC)) {
223438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
223538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
223638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
223738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
223838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	debug_info_ptr = *(buffer + 1);
223938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (debug_info_ptr == 0) {
224038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "Error: Debug info pointer is zero\n");
224138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return -1;
224238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
224338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
224438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Read the area the debuginfoptr points at */
224538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	params[0] = debug_info_ptr;
224638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	params[1] = sizeof(hndrte_debug_t);
224738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&buffer);
224838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ret) {
224938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: failed reading %lu membytes from 0x%08lx\n",
225038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			__FUNCTION__, (long unsigned) params[1], (long unsigned) params[0]);
225138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return ret;
225238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
225338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
225438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	memcpy((char *) debug_info, buffer, sizeof(hndrte_debug_t));
225538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
225638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Sanity check the area */
225738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((debug_info->magic != HNDRTE_DEBUG_MAGIC) ||
225838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	    (debug_info->version != HNDRTE_DEBUG_VERSION)) {
225938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "Error: Invalid debug info area\n");
226038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return -1;
226138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
226238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
226338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return 0;
226438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
226538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
226638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
226738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int
226838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtdhd_coredump(void *dhd, cmd_t *cmd, char **argv)
226938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
227038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
227138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return (-1);
227238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#else
227338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *fname = NULL;
227438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
227538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
227638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FILE *fp;
227738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
227838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	hndrte_debug_t debugInfo;
227938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	miniopt_t opts;
228138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int opt_err;
228238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int params[2];
228438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *ptr;
228538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	unsigned int start;
228738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	unsigned int size;
228838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	prstatus_t prstatus;
229038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
229138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	UNUSED_PARAMETER(cmd);
229238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	UNUSED_PARAMETER(argv);
229338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
229438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Parse command-line options */
229538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	miniopt_init(&opts, "dump", "", TRUE);
229638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
229738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	argv++;
229838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
229938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (opt_err == 1) {
230038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "dump options error\n");
230138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
230238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
230338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
230438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		argv += opts.consumed;
230538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
230638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (opts.positional) {
230738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			if (!fname) {
230838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				fname = opts.valstr;
230938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			} else {
231038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				fprintf(stderr, "dump options error\n");
231138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				ret = -1;
231238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				goto exit;
231338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			}
231438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		} else if (!opts.opt) {
231538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "unrecognized option %s\n", opts.valstr);
231638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
231738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
231838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		} else {
231938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "unrecognized option %c\n", opts.opt);
232038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
232138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
232238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
232338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
232438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
232538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* validate arguments */
232638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (!fname) {
232738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "filename required\n");
232838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
232938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
233038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
233138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
233238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_debug_info(dhd, &debugInfo)) < 0)
233338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
233438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
233538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Get the base and size to dump */
233638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	start = debugInfo.ram_base;
233738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	size = debugInfo.ram_size;
233838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
233938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Get the arm trap area */
234038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	bzero(&prstatus, sizeof(prstatus_t));
234138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (debugInfo.trap_ptr != 0) {
234238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		int i;
234338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		trap_t armtrap;
234438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		uint32 *reg;
234538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
234638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[0] = debugInfo.trap_ptr;
234738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[1] = sizeof(trap_t);
234838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
234938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret) {
235038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "%s: failed reading %lu membytes from 0x%08lx\n",
235138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				__FUNCTION__, (long unsigned) params[1], (long unsigned) params[0]);
235238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
235338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
235438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
235538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		memcpy((char *) &armtrap, ptr, sizeof(trap_t));
235638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
235738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		/* Populate the prstatus */
235838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		prstatus.si_signo = armtrap.type;
235938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		reg = &armtrap.r0;
236038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		for (i = 0; i < 15; i++, reg++) {
236138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			prstatus.uregs[i] = *reg;
236238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
236338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		prstatus.uregs[15] = armtrap.epc;
236438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
236538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
236638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((fp = fopen(fname, "wb")) == NULL) {
236738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: Could not open %s: %s\n",
236838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		        __FUNCTION__, fname, strerror(errno));
236938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
237038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
237138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
237238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
237338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Write the preamble and debug header */
237438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fprintf(fp, "Dump starts for version %s FWID 01-%x\n", debugInfo.epivers, debugInfo.fwid);
237538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fprintf(fp, "XXXXXXXXXXXXXXXXXXXX");
237638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fprintf(fp, "%8.8lX", (long unsigned) sizeof(debugInfo));
237738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (fwrite(&debugInfo, sizeof(unsigned char), sizeof(debugInfo), fp) != sizeof(debugInfo)) {
237838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: error writing to file %s\n", __FUNCTION__, fname);
237938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
238038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fclose(fp);
238138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
238238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
238338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
238438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Write the prstatus */
238538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (fwrite(&prstatus, sizeof(unsigned char), sizeof(prstatus), fp) != sizeof(prstatus)) {
238638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: error writing to file %s\n", __FUNCTION__, fname);
238738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
238838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fclose(fp);
238938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
239038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
239138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
239238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Write the ram size as another sanity check */
239338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fprintf(fp, "%8.8X", size);
239438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
239538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* read memory and write to file */
239638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while (size) {
239738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		int len;
239838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		len = MIN(MEMBLOCK, size);
239938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
240038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[0] = start;
240138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[1] = len;
240238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
240338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret) {
240438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "%s: failed reading %d membytes from 0x%08x\n",
240538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			        __FUNCTION__, len, start);
240638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
240738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
240838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
240938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (fwrite(ptr, sizeof(char), len, fp) != (uint) len) {
241038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "%s: error writing to file %s\n", __FUNCTION__, fname);
241138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
241238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
241338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
241438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
241538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		start += len;
241638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		size -= len;
241738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
241838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
241938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fclose(fp);
242038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtexit:
242138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
242238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
242338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
242438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
242538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int
242638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtdhd_consoledump(void *dhd, cmd_t *cmd, char **argv)
242738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
242838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#if !defined(BWL_FILESYSTEM_SUPPORT)
242938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return (-1);
243038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#else
243138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret;
243238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
243338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	hndrte_debug_t debugInfo;
243438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
243538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	miniopt_t opts;
243638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int opt_err;
243738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
243838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int params[2];
243938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	char *ptr;
244038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
244138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	unsigned int start;
244238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	unsigned int size;
244338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int len;
244438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
244538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	UNUSED_PARAMETER(cmd);
244638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	UNUSED_PARAMETER(argv);
244738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
244838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Parse command-line options */
244938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	miniopt_init(&opts, "consoledump", "", TRUE);
245038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
245138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	argv++;
245238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while ((opt_err = miniopt(&opts, argv)) != -1) {
245338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (opt_err == 1) {
245438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "dump options error\n");
245538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
245638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
245738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
245838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		argv += opts.consumed;
245938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
246038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (!opts.opt) {
246138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "unrecognized option %s\n", opts.valstr);
246238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
246338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
246438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		} else {
246538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "unrecognized option %c\n", opts.opt);
246638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			ret = -1;
246738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			goto exit;
246838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
246938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
247038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
247138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((ret = dhd_get_debug_info(dhd, &debugInfo)) < 0)
247238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
247338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
247438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (debugInfo.console <= debugInfo.ram_base) {
247538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: console not found\n", __FUNCTION__);
247638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
247738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
247838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
247938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
248038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Get the debug console area */
248138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	params[0] = debugInfo.console;
248238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	params[1] = sizeof(hndrte_cons_t);
248338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
248438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ret) {
248538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: failed reading %lu membytes from 0x%08lx\n",
248638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			__FUNCTION__, (long unsigned) params[1], (long unsigned) params[0]);
248738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
248838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
248938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
249038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ptr == NULL) {
249138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: console not initialised\n", __FUNCTION__);
249238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
249338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
249438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
249538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
249638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	start = (unsigned int)((hndrte_cons_t *)ptr)->log.buf;
249738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	size = ((hndrte_cons_t *)ptr)->log.buf_size;
249838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
249938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (start <= debugInfo.ram_base) {
250038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "%s: console buffer not initialised\n", __FUNCTION__);
250138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = -1;
250238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		goto exit;
250338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
250438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
250538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* read memory and write to file */
250638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while (size > 0) {
250738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		len = MIN(MEMBLOCK, size);
250838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
250938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[0] = start;
251038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		params[1] = len;
251138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = dhd_var_getbuf(dhd, "membytes", params, 2 * sizeof(int), (void**)&ptr);
251238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (ret) {
251338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			fprintf(stderr, "%s: failed reading %d membytes from 0x%08x\n",
251438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			        __FUNCTION__, len, start);
251538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
251638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
251738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
251838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		printf("%s", ptr);
251938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
252038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		start += len;
252138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		size -= len;
252238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
252338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
252438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtexit:
252538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
252638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* BWL_FILESYSTEM_SUPPORT */
252738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
252838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
2529b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2530b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_logstamp(void *dhd, cmd_t *cmd, char **argv)
2531b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2532b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
2533b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
2534b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
2535b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int valn[2] = {0, 0};
2536b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2537b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
2538b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
2539b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--; argv++;
2540b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2541b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc > 2)
254238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2543b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2544b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc) {
2545b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		valn[0] = strtol(argv[0], &endptr, 0);
2546b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
2547b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("bad val1: %s\n", argv[0]);
254838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2549b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2550b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2551b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2552b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argc > 1) {
2553b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		valn[1] = strtol(argv[1], &endptr, 0);
2554b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
2555b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("bad val2: %s\n", argv[1]);
255638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2557b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2558b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2559b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2560b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ret = dhd_var_setbuf(dhd, cmd->name, valn, argc * sizeof(int));
2561b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2562b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
2563b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2564b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2565b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2566b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_sd_reg(void *dhd, cmd_t *cmd, char **argv)
2567b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2568b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
2569b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	sdreg_t sdreg;
2570b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
2571b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint argc;
2572b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *ptr = NULL;
2573b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2574b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bzero(&sdreg, sizeof(sdreg));
2575b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2576b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* arg count */
2577b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (argc = 0; argv[argc]; argc++);
2578b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	argc--;
2579b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2580b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* hostreg: offset [value]; devreg: func offset [value] */
2581b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!strcmp(cmd->name, "sd_hostreg")) {
2582b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv++;
2583b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (argc < 1) {
2584b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("required args: offset [value]\n");
258538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2586b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2587b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2588b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else if (!strcmp(cmd->name, "sd_devreg")) {
2589b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		argv++;
2590b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (argc < 2) {
2591b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("required args: func offset [value]\n");
259238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2593b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2594b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2595b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sdreg.func = strtoul(*argv++, &endptr, 0);
2596b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
2597b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Invalid function number\n");
259838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2599b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2600b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
260138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2602b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2603b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2604b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	sdreg.offset = strtoul(*argv++, &endptr, 0);
2605b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*endptr != '\0') {
2606b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("Invalid offset value\n");
260738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2608b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2609b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2610b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* third arg: value */
2611b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*argv) {
2612b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sdreg.value = strtoul(*argv, &endptr, 0);
2613b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
2614b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("Invalid value\n");
261538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			return BCME_USAGE_ERROR;
2616b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2617b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2618b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2619b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* no third arg means get, otherwise set */
2620b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*argv) {
2621b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((ret = dhd_var_getbuf(dhd, cmd->name, &sdreg, sizeof(sdreg), &ptr)) >= 0)
2622b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("0x%x\n", *(int *)ptr);
2623b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
2624b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret = dhd_var_setbuf(dhd, cmd->name, &sdreg, sizeof(sdreg));
2625b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2626b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2627b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (ret);
2628b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2629b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2630b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic dbg_msg_t dhd_msgs[] = {
2631b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_ERROR_VAL,	"error"},
2632b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_ERROR_VAL, "err"},
2633b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_TRACE_VAL, "trace"},
2634b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_INFO_VAL,	"inform"},
2635b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_INFO_VAL,	"info"},
2636b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_INFO_VAL,	"inf"},
2637b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_DATA_VAL,	"data"},
2638b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_CTL_VAL,	"ctl"},
2639b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_TIMER_VAL,	"timer"},
2640b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_HDRS_VAL,	"hdrs"},
2641b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_BYTES_VAL,	"bytes"},
2642b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_INTR_VAL,	"intr"},
2643b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_LOG_VAL,	"log"},
2644b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_GLOM_VAL,	"glom"},
2645b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_EVENT_VAL,	"event"},
2646b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{DHD_BTA_VAL,	"bta"},
2647ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{DHD_ISCAN_VAL,	"iscan"},
2648ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{DHD_ARPOE_VAL,	"arpoe"},
2649ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{DHD_REORDER_VAL, "reorder"},
2650b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	{0,		NULL}
2651b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
2652b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2653b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2654b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_msglevel(void *dhd, cmd_t *cmd, char **argv)
2655b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2656b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return dhd_do_msglevel(dhd, cmd, argv, dhd_msgs);
2657b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2658b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2659b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2660b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_do_msglevel(void *dhd, cmd_t *cmd, char **argv, dbg_msg_t *dbg_msg)
2661b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2662b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret, i;
2663b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint val, last_val = 0, msglevel = 0, msglevel_add = 0, msglevel_del = 0;
2664b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
2665b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2666b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((ret = dhd_iovar_getint(dhd, cmd->name, (int*)&msglevel)) < 0)
2667b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (ret);
2668b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2669b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*++argv) {
2670b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("0x%x ", msglevel);
2671b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (i = 0; (val = dbg_msg[i].value); i++) {
2672b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if ((msglevel & val) && (val != last_val))
2673b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				printf(" %s", dbg_msg[i].string);
2674b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			last_val = val;
2675b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2676b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("\n");
2677b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (0);
2678b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2679b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2680b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*argv) {
2681b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		char *s = *argv;
2682b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*s == '+' || *s == '-')
2683b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			s++;
2684b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else
2685b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			msglevel_del = ~0;	/* make the whole list absolute */
2686b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		val = strtoul(s, &endptr, 0);
2687b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* not a plain integer if not all the string was parsed by strtoul */
2688b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (*endptr != '\0') {
2689b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			for (i = 0; (val = dbg_msg[i].value); i++)
2690b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				if (stricmp(dbg_msg[i].string, s) == 0)
2691b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt					break;
2692b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (!val)
2693b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				goto usage;
2694b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2695b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (**argv == '-')
2696b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			msglevel_del |= val;
2697b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else
2698b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			msglevel_add |= val;
2699b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		++argv;
2700b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2701b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2702b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	msglevel &= ~msglevel_del;
2703b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	msglevel |= msglevel_add;
2704b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2705b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (dhd_iovar_setint(dhd, cmd->name, msglevel));
2706b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2707b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtusage:
2708b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "msg values may be a list of numbers or names from the following set.\n");
2709b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "Use a + or - prefix to make an incremental change.");
2710b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2711b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; (val = dbg_msg[i].value); i++) {
2712b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (val != last_val)
2713b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, "\n0x%04x %s", val, dbg_msg[i].string);
2714b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		else
2715b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			fprintf(stderr, ", %s", dbg_msg[i].string);
2716b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		last_val = val;
2717b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2718b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fprintf(stderr, "\n");
2719b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2720b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
2721b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2722b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2723b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic char *
2724b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtver2str(unsigned int vms, unsigned int vls)
2725b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2726b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	static char verstr[100];
2727b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	unsigned int maj, year, month, day, build;
2728b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2729b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	maj = (vms >> 16) & 0xFFFF;
2730b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (maj > 1000) {
2731b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* it is probably a date... */
2732b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		year = (vms >> 16) & 0xFFFF;
2733b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		month = vms & 0xFFFF;
2734b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		day = (vls >> 16) & 0xFFFF;
2735b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		build = vls & 0xFFFF;
2736b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sprintf(verstr, "%d/%d/%d build %d",
2737b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			month, day, year, build);
2738b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
2739b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* it is a tagged release. */
2740b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sprintf(verstr, "%d.%d RC%d.%d",
2741b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			(vms>>16)&0xFFFF, vms&0xFFFF,
2742b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			(vls>>16)&0xFFFF, vls&0xFFFF);
2743b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2744b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return verstr;
2745b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2746b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2747b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2748b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_version(void *dhd, cmd_t *cmd, char **argv)
2749b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2750b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int ret;
2751b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *ptr;
2752b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2753b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
2754b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(argv);
2755b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2756b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Display the application version info */
2757b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("%s: %s\n", dhdu_av0,
2758b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ver2str((EPI_MAJOR_VERSION << 16)| EPI_MINOR_VERSION,
2759b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		(EPI_RC_NUMBER << 16) | EPI_INCREMENTAL_NUMBER));
2760b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2761b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((ret = dhd_var_getbuf(dhd, cmd->name, NULL, 0, (void**)&ptr)) < 0)
2762b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return ret;
2763b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2764b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Display the returned string */
2765b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("%s\n", ptr);
2766b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2767b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
2768b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2769b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2770b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2771b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_setint(void *dhd, cmd_t *cmd, char **argv)
2772b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2773b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int32 val;
2774b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
2775b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *varname;
2776b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endptr = NULL;
2777b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p;
2778b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2779b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (cmd->set == -1) {
2780b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("set not defined for %s\n", cmd->name);
278138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_ERROR;
2782b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2783b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2784b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*argv) {
2785b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("set: missing arguments\n");
278638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2787b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2788b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2789b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	varname = *argv++;
2790b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2791b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*argv) {
2792b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("set: missing value argument for set of \"%s\"\n", varname);
279338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2794b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2795b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2796b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	val = strtol(*argv, &endptr, 0);
2797b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*endptr != '\0') {
2798b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* not all the value string was parsed by strtol */
2799b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("set: error parsing value \"%s\" as an integer for set of \"%s\"\n",
2800b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*argv, varname);
280138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2802b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2803b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2804b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(buf, varname);
2805b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = buf;
2806b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*p != '\0') {
2807b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*p = tolower(*p);
2808b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p++;
2809b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2810b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2811b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* skip the NUL */
2812b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p++;
2813b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2814b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memcpy(p, &val, sizeof(uint));
2815b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = (p - buf) +  sizeof(uint);
2816b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2817b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (dhd_set(dhd, DHD_SET_VAR, &buf[0], len));
2818b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2819b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2820b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2821b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_get(void *dhd, cmd_t *cmd, char **argv)
2822b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2823b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *varname;
2824b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p;
2825b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2826b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(cmd);
2827b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2828b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*argv) {
2829b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("get: missing arguments\n");
283038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2831b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2832b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2833b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	varname = *argv++;
2834b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2835b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*argv) {
2836b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("get: error, extra arg \"%s\"\n", *argv);
283738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_USAGE_ERROR;
2838b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2839b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2840b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(buf, varname);
2841b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = buf;
2842b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*p != '\0') {
2843b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*p = tolower(*p);
2844b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p++;
2845b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2846b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (dhd_get(dhd, DHD_GET_VAR, &buf[0], DHD_IOCTL_MAXLEN));
2847b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2848b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2849b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2850b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_getint(void *dhd, cmd_t *cmd, char **argv)
2851b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2852b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int err;
2853b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int32 val;
2854b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (cmd->get == -1) {
2855b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("get not defined for %s\n", cmd->name);
285638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_ERROR;
2857b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2858b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2859b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((err = dhd_var_get(dhd, cmd, argv)))
2860b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (err);
2861b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2862b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	val = *(int32*)buf;
2863b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2864b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (val < 10)
2865b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%d\n", val);
2866b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
2867b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%d (0x%x)\n", val, val);
2868b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2869b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (0);
2870b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2871b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2872b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2873b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_getandprintstr(void *dhd, cmd_t *cmd, char **argv)
2874b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2875b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int err;
2876b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2877b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((err = dhd_var_get(dhd, cmd, argv)))
2878b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (err);
2879b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2880b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("%s\n", buf);
2881b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (0);
2882b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2883b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2884b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2885b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
2886b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_printlasterror(void *dhd)
2887b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2888b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *cmd[2] = {"bcmerrorstr"};
2889b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2890b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (dhd_var_get(dhd, NULL, cmd) != 0) {
2891b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: \nError getting the last error\n", dhdu_av0);
2892b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
2893b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		fprintf(stderr, "%s: %s\n", dhdu_av0, buf);
2894b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2895b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2896b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2897b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2898b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_varint(void *dhd, cmd_t *cmd, char *argv[])
2899b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2900b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (argv[1])
2901b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (dhd_var_setint(dhd, cmd, argv));
2902b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
2903b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (dhd_var_getint(dhd, cmd, argv));
2904b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2905b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2906b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2907b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_getbuf(void *dhd, char *iovar, void *param, int param_len, void **bufptr)
2908b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2909b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
2910b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2911b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memset(buf, 0, DHD_IOCTL_MAXLEN);
2912b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(buf, iovar);
2913b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2914b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* include the NUL */
2915b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(iovar) + 1;
2916b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2917b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (param_len)
2918b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(&buf[len], param, param_len);
2919b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2920b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*bufptr = buf;
2921b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2922b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return dhd_get(dhd, DHD_GET_VAR, &buf[0], DHD_IOCTL_MAXLEN);
2923b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2924b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2925b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2926b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_setbuf(void *dhd, char *iovar, void *param, int param_len)
2927b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2928b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
2929b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2930b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memset(buf, 0, DHD_IOCTL_MAXLEN);
2931b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(buf, iovar);
2932b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2933b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* include the NUL */
2934b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(iovar) + 1;
2935b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2936b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (param_len)
2937b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(&buf[len], param, param_len);
2938b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2939b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len += param_len;
2940b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2941b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return dhd_set(dhd, DHD_SET_VAR, &buf[0], len);
2942b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2943b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2944b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2945b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_var_void(void *dhd, cmd_t *cmd, char **argv)
2946b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2947b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	UNUSED_PARAMETER(argv);
2948b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2949b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (cmd->set < 0)
295038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_ERROR;
2951b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2952b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return dhd_var_setbuf(dhd, cmd->name, NULL, 0);
2953b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2954b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2955b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
2956b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * format an iovar buffer
2957b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
2958b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic uint
2959b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_iovar_mkbuf(char *name, char *data, uint datalen, char *buf, uint buflen, int *perr)
2960b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2961b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
2962b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2963b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(name) + 1;
2964b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2965b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* check for overflow */
2966b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((len + datalen) > buflen) {
2967b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*perr = BCME_BUFTOOSHORT;
2968b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
2969b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2970b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2971b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strcpy(buf, name);
2972b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2973b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* append data onto the end of the name string */
2974b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (datalen > 0)
2975b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		memcpy(&buf[len], data, datalen);
2976b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2977b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len += datalen;
2978b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2979b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*perr = 0;
2980b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return len;
2981b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2982b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2983b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
2984b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_iovar_getint(void *dhd, char *name, int *var)
2985b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2986b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char ibuf[DHD_IOCTL_SMLEN];
2987b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int error;
2988b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2989b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	dhd_iovar_mkbuf(name, NULL, 0, ibuf, sizeof(ibuf), &error);
2990b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (error)
2991b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return error;
2992b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2993b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((error = dhd_get(dhd, DHD_GET_VAR, &ibuf, sizeof(ibuf))) < 0)
2994b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return error;
2995b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2996b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memcpy(var, ibuf, sizeof(int));
2997b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2998b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
2999b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
3000b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3001b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
3002b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_iovar_setint(void *dhd, char *name, int var)
3003b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
3004b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
3005b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char ibuf[DHD_IOCTL_SMLEN];
3006b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int error;
3007b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3008b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = dhd_iovar_mkbuf(name, (char *)&var, sizeof(var), ibuf, sizeof(ibuf), &error);
3009b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (error)
3010b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return error;
3011b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3012b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((error = dhd_set(dhd, DHD_SET_VAR, &ibuf, len)) < 0)
3013b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return error;
3014b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3015b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
3016b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
3017b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3018b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic int
3019b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_varstr(void *dhd, cmd_t *cmd, char **argv)
3020b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
3021b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int error;
3022b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *str;
3023b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3024b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*++argv) {
3025b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		void *ptr;
3026b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3027b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((error = dhd_var_getbuf(dhd, cmd->name, NULL, 0, &ptr)) < 0)
3028b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (error);
3029b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3030b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str = (char *)ptr;
3031b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s\n", str);
3032b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return (0);
3033b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
3034b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str = *argv;
3035b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* iovar buffer length includes NUL */
3036b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return dhd_var_setbuf(dhd, cmd->name, str, strlen(str) + 1);
3037b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
3038b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
3039b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3040b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3041ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtstatic int
3042ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtdhd_hostreorder_flows(void *dhd, cmd_t *cmd, char **argv)
3043ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
3044ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int ret, count, i = 0;
3045ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	void *ptr;
3046ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 *flow_id;
3047ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
3048ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
3049ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((ret = dhd_var_getbuf(dhd, cmd->name, NULL, 0, &ptr)) < 0) {
3050ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		printf("error getting reorder flows from the host\n");
3051ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return ret;
3052ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
3053ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	flow_id = (uint8 *)ptr;
3054ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	count = *flow_id;
3055ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (!count)
3056ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		printf("there are no active flows\n");
3057ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	else {
3058ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		printf("flows(%d): \t", count);
3059ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		while (i++ < count)
3060ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			printf("%d  ", *flow_id++);
3061ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		printf("\n");
3062ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
3063ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return 0;
3064ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
3065ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
3066ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
3067b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3068b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* These two utility functions are used by dhdu_linux.c
3069b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * The code is taken from wlu.c.
3070b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
3071b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
3072b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_atoip(const char *a, struct ipv4_addr *n)
3073b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
3074b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *c;
3075b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i = 0;
3076b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3077b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (;;) {
3078b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        n->addr[i++] = (uint8)strtoul(a, &c, 0);
3079b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        if (*c++ != '.' || i == IPV4_ADDR_LEN)
3080b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	                break;
3081b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        a = c;
3082b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
3083b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (i == IPV4_ADDR_LEN);
3084b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
3085b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3086b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
3087b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtdhd_ether_atoe(const char *a, struct ether_addr *n)
3088b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
3089b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *c;
3090b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i = 0;
3091b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
3092b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memset(n, 0, ETHER_ADDR_LEN);
3093b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (;;) {
3094b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        n->octet[i++] = (uint8)strtoul(a, &c, 16);
3095b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        if (!*c++ || i == ETHER_ADDR_LEN)
3096b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	                break;
3097b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	        a = c;
3098b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
3099b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (i == ETHER_ADDR_LEN);
3100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
3101