Commit | Line | Data |
---|---|---|
a9533e7e HP |
1 | /* |
2 | * Copyright (c) 2010 Broadcom Corporation | |
3 | * | |
4 | * Permission to use, copy, modify, and/or distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #ifndef _bcmutils_h_ | |
18 | #define _bcmutils_h_ | |
19 | ||
20 | #ifdef __cplusplus | |
21 | extern "C" { | |
22 | #endif | |
23 | ||
cf2b4488 HP |
24 | #ifdef BRCM_FULLMAC |
25 | /* ctype replacement */ | |
26 | #define _BCM_U 0x01 /* upper */ | |
27 | #define _BCM_L 0x02 /* lower */ | |
28 | #define _BCM_D 0x04 /* digit */ | |
29 | #define _BCM_C 0x08 /* cntrl */ | |
30 | #define _BCM_P 0x10 /* punct */ | |
31 | #define _BCM_S 0x20 /* white space (space/lf/tab) */ | |
32 | #define _BCM_X 0x40 /* hex digit */ | |
33 | #define _BCM_SP 0x80 /* hard space (0x20) */ | |
34 | ||
35 | extern const unsigned char bcm_ctype[]; | |
36 | #define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) | |
37 | ||
38 | #define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) | |
39 | #define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) | |
40 | #define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) | |
41 | #define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) | |
42 | #define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) | |
43 | #define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) | |
44 | #define bcm_isprint(c) \ | |
45 | ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) | |
46 | #define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) | |
47 | #define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) | |
48 | #define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) | |
49 | #define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) | |
50 | #define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) | |
51 | #define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) | |
52 | #endif /* BRCM_FULLMAC */ | |
53 | ||
a9533e7e HP |
54 | /* Buffer structure for collecting string-formatted data |
55 | * using bcm_bprintf() API. | |
56 | * Use bcm_binit() to initialize before use | |
57 | */ | |
58 | ||
59 | struct bcmstrbuf { | |
60 | char *buf; /* pointer to current position in origbuf */ | |
61 | unsigned int size; /* current (residual) size in bytes */ | |
62 | char *origbuf; /* unmodified pointer to orignal buffer */ | |
63 | unsigned int origsize; /* unmodified orignal buffer size in bytes */ | |
64 | }; | |
65 | ||
66 | /* ** driver-only section ** */ | |
67 | #include <osl.h> | |
68 | ||
69 | #define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ | |
70 | ||
71 | /* | |
72 | * Spin at most 'us' microseconds while 'exp' is true. | |
73 | * Caller should explicitly test 'exp' when this completes | |
74 | * and take appropriate error action if 'exp' is still true. | |
75 | */ | |
76 | #define SPINWAIT(exp, us) { \ | |
77 | uint countdown = (us) + 9; \ | |
78 | while ((exp) && (countdown >= 10)) {\ | |
79 | OSL_DELAY(10); \ | |
80 | countdown -= 10; \ | |
81 | } \ | |
82 | } | |
83 | ||
84 | /* osl multi-precedence packet queue */ | |
85 | #ifndef PKTQ_LEN_DEFAULT | |
86 | #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ | |
87 | #endif | |
88 | #ifndef PKTQ_MAX_PREC | |
89 | #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ | |
90 | #endif | |
91 | ||
92 | typedef struct pktq_prec { | |
93 | void *head; /* first packet to dequeue */ | |
94 | void *tail; /* last packet to dequeue */ | |
95 | uint16 len; /* number of queued packets */ | |
96 | uint16 max; /* maximum number of queued packets */ | |
97 | } pktq_prec_t; | |
98 | ||
99 | /* multi-priority pkt queue */ | |
100 | struct pktq { | |
101 | uint16 num_prec; /* number of precedences in use */ | |
102 | uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ | |
103 | uint16 max; /* total max packets */ | |
104 | uint16 len; /* total number of packets */ | |
105 | /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ | |
106 | struct pktq_prec q[PKTQ_MAX_PREC]; | |
107 | }; | |
108 | ||
109 | /* simple, non-priority pkt queue */ | |
110 | struct spktq { | |
111 | uint16 num_prec; /* number of precedences in use (always 1) */ | |
112 | uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ | |
113 | uint16 max; /* total max packets */ | |
114 | uint16 len; /* total number of packets */ | |
115 | /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ | |
116 | struct pktq_prec q[1]; | |
117 | }; | |
118 | ||
119 | #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) | |
120 | ||
121 | /* fn(pkt, arg). return true if pkt belongs to if */ | |
122 | typedef bool(*ifpkt_cb_t) (void *, int); | |
123 | ||
124 | /* forward definition of ether_addr structure used by some function prototypes */ | |
125 | ||
126 | struct ether_addr; | |
127 | ||
128 | extern int ether_isbcast(const void *ea); | |
129 | extern int ether_isnulladdr(const void *ea); | |
130 | ||
131 | /* operations on a specific precedence in packet queue */ | |
132 | ||
133 | #define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) | |
134 | #define pktq_plen(pq, prec) ((pq)->q[prec].len) | |
135 | #define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) | |
136 | #define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) | |
137 | #define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) | |
138 | ||
139 | #define pktq_ppeek(pq, prec) ((pq)->q[prec].head) | |
140 | #define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) | |
141 | ||
142 | extern void *pktq_penq(struct pktq *pq, int prec, void *p); | |
143 | extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); | |
144 | extern void *pktq_pdeq(struct pktq *pq, int prec); | |
145 | extern void *pktq_pdeq_tail(struct pktq *pq, int prec); | |
146 | /* Empty the queue at particular precedence level */ | |
cf2b4488 HP |
147 | #ifdef BRCM_FULLMAC |
148 | extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, | |
149 | bool dir); | |
150 | #else | |
7cc4a4c0 | 151 | extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, |
cf2b4488 HP |
152 | bool dir, ifpkt_cb_t fn, int arg); |
153 | #endif | |
52b0e80e | 154 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
155 | /* Remove a specified packet from its queue */ |
156 | extern bool pktq_pdel(struct pktq *pq, void *p, int prec); | |
52b0e80e | 157 | #endif /* BRCM_FULLMAC */ |
a9533e7e HP |
158 | |
159 | /* operations on a set of precedences in packet queue */ | |
160 | ||
52b0e80e | 161 | #ifdef BRCM_FULLMAC |
a9533e7e | 162 | extern int pktq_mlen(struct pktq *pq, uint prec_bmp); |
52b0e80e | 163 | #endif /* BRCM_FULLMAC */ |
a9533e7e HP |
164 | extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); |
165 | ||
166 | /* operations on packet queue as a whole */ | |
167 | ||
168 | #define pktq_len(pq) ((int)(pq)->len) | |
169 | #define pktq_max(pq) ((int)(pq)->max) | |
170 | #define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) | |
171 | #define pktq_full(pq) ((pq)->len >= (pq)->max) | |
172 | #define pktq_empty(pq) ((pq)->len == 0) | |
173 | ||
174 | /* operations for single precedence queues */ | |
175 | #define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) | |
176 | #define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) | |
177 | #define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) | |
178 | #define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) | |
179 | #define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) | |
180 | ||
181 | extern void pktq_init(struct pktq *pq, int num_prec, int max_len); | |
182 | /* prec_out may be NULL if caller is not interested in return value */ | |
52b0e80e | 183 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
184 | extern void *pktq_deq(struct pktq *pq, int *prec_out); |
185 | extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); | |
186 | extern void *pktq_peek(struct pktq *pq, int *prec_out); | |
52b0e80e | 187 | #endif /* BRCM_FULLMAC */ |
a9533e7e | 188 | extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); |
cf2b4488 HP |
189 | #ifdef BRCM_FULLMAC |
190 | extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); | |
191 | #else | |
7cc4a4c0 | 192 | extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, |
cf2b4488 HP |
193 | ifpkt_cb_t fn, int arg); |
194 | #endif | |
a9533e7e HP |
195 | |
196 | /* externs */ | |
197 | /* packet */ | |
52b0e80e | 198 | #ifdef BRCM_FULLMAC |
7cc4a4c0 | 199 | extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, |
580a0bd9 | 200 | unsigned char *buf); |
7cc4a4c0 | 201 | extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, |
580a0bd9 | 202 | unsigned char *buf); |
7cc4a4c0 JC |
203 | extern void *pktlast(osl_t *osh, void *p); |
204 | extern uint pktsegcnt(osl_t *osh, void *p); | |
52b0e80e BR |
205 | #endif /* BRCM_FULLMAC */ |
206 | extern uint pkttotlen(osl_t *osh, void *p); | |
a9533e7e HP |
207 | |
208 | /* Get priority from a packet and pass it back in scb (or equiv) */ | |
209 | extern uint pktsetprio(void *pkt, bool update_vtag); | |
210 | #define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */ | |
211 | #define PKTPRIO_VLAN 0x200 /* VLAN prio found */ | |
212 | #define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */ | |
213 | #define PKTPRIO_DSCP 0x800 /* DSCP prio found */ | |
214 | ||
cf2b4488 HP |
215 | #ifdef BRCM_FULLMAC |
216 | /* string */ | |
217 | extern int BCMROMFN(bcm_atoi) (char *s); | |
3deea904 | 218 | extern unsigned long BCMROMFN(bcm_strtoul) (char *cp, char **endp, uint base); |
cf2b4488 HP |
219 | extern char *BCMROMFN(bcmstrstr) (char *haystack, char *needle); |
220 | extern char *BCMROMFN(bcmstrcat) (char *dest, const char *src); | |
221 | extern char *BCMROMFN(bcmstrncat) (char *dest, const char *src, | |
222 | uint size); | |
3deea904 GKH |
223 | extern unsigned long wchar2ascii(char *abuf, unsigned short *wbuf, unsigned short wbuflen, |
224 | unsigned long abuflen); | |
cf2b4488 HP |
225 | char *bcmstrtok(char **string, const char *delimiters, char *tokdelim); |
226 | int bcmstricmp(const char *s1, const char *s2); | |
227 | int bcmstrnicmp(const char *s1, const char *s2, int cnt); | |
228 | #endif | |
a9533e7e HP |
229 | /* ethernet address */ |
230 | extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); | |
7cc4a4c0 | 231 | extern int BCMROMFN(bcm_ether_atoe) (char *p, struct ether_addr *ea); |
a9533e7e HP |
232 | |
233 | /* ip address */ | |
234 | struct ipv4_addr; | |
235 | extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); | |
236 | ||
52b0e80e | 237 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
238 | /* delay */ |
239 | extern void bcm_mdelay(uint ms); | |
52b0e80e | 240 | #endif |
a9533e7e HP |
241 | /* variable access */ |
242 | extern char *getvar(char *vars, const char *name); | |
243 | extern int getintvar(char *vars, const char *name); | |
52b0e80e | 244 | #ifdef BRCM_FULLMAC |
de9bca63 | 245 | extern int getintvararray(char *vars, const char *name, u8 index); |
a9533e7e | 246 | extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); |
52b0e80e | 247 | #endif |
a9533e7e | 248 | #ifdef BCMDBG |
7cc4a4c0 | 249 | extern void prpkt(const char *msg, osl_t *osh, void *p0); |
a9533e7e HP |
250 | #endif /* BCMDBG */ |
251 | #define bcm_perf_enable() | |
252 | #define bcmstats(fmt) | |
253 | #define bcmlog(fmt, a1, a2) | |
0d706ef4 | 254 | #define bcmdumplog(buf, size) (*buf = '\0') |
a9533e7e HP |
255 | #define bcmdumplogent(buf, idx) -1 |
256 | ||
257 | #define bcmtslog(tstamp, fmt, a1, a2) | |
258 | #define bcmprinttslogs() | |
259 | #define bcmprinttstamp(us) | |
260 | ||
52b0e80e | 261 | #ifdef BRCM_FULLLMAC |
7cc4a4c0 | 262 | extern char *bcm_nvram_vars(uint *length); |
a9533e7e | 263 | extern int bcm_nvram_cache(void *sih); |
52b0e80e | 264 | #endif |
a9533e7e HP |
265 | |
266 | /* Support for sharing code across in-driver iovar implementations. | |
267 | * The intent is that a driver use this structure to map iovar names | |
268 | * to its (private) iovar identifiers, and the lookup function to | |
269 | * find the entry. Macros are provided to map ids and get/set actions | |
270 | * into a single number space for a switch statement. | |
271 | */ | |
272 | ||
273 | /* iovar structure */ | |
274 | typedef struct bcm_iovar { | |
275 | const char *name; /* name for lookup and display */ | |
276 | uint16 varid; /* id for switch */ | |
277 | uint16 flags; /* driver-specific flag bits */ | |
278 | uint16 type; /* base type of argument */ | |
279 | uint16 minlen; /* min length for buffer vars */ | |
280 | } bcm_iovar_t; | |
281 | ||
282 | /* varid definitions are per-driver, may use these get/set bits */ | |
283 | ||
284 | /* IOVar action bits for id mapping */ | |
285 | #define IOV_GET 0 /* Get an iovar */ | |
286 | #define IOV_SET 1 /* Set an iovar */ | |
287 | ||
288 | /* Varid to actionid mapping */ | |
289 | #define IOV_GVAL(id) ((id)*2) | |
290 | #define IOV_SVAL(id) (((id)*2)+IOV_SET) | |
291 | #define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) | |
292 | #define IOV_ID(actionid) (actionid >> 1) | |
293 | ||
294 | /* flags are per-driver based on driver attributes */ | |
295 | ||
52b0e80e | 296 | #ifdef BRCM_FULLMAC |
7cc4a4c0 | 297 | extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, |
a9533e7e | 298 | const char *name); |
52b0e80e | 299 | #endif |
7cc4a4c0 | 300 | extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, |
a9533e7e | 301 | int len, bool set); |
52b0e80e | 302 | #ifdef BRCM_FULLMAC |
a9533e7e | 303 | #if defined(BCMDBG) |
580a0bd9 | 304 | extern int bcm_format_ssid(char *buf, const unsigned char ssid[], |
a9533e7e HP |
305 | uint ssid_len); |
306 | #endif | |
52b0e80e | 307 | #endif /* BRCM_FULLMAC */ |
a9533e7e HP |
308 | |
309 | /* Base type definitions */ | |
310 | #define IOVT_VOID 0 /* no value (implictly set only) */ | |
311 | #define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ | |
312 | #define IOVT_INT8 2 /* integer values are range-checked */ | |
313 | #define IOVT_UINT8 3 /* unsigned int 8 bits */ | |
314 | #define IOVT_INT16 4 /* int 16 bits */ | |
315 | #define IOVT_UINT16 5 /* unsigned int 16 bits */ | |
316 | #define IOVT_INT32 6 /* int 32 bits */ | |
317 | #define IOVT_UINT32 7 /* unsigned int 32 bits */ | |
318 | #define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ | |
319 | #define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) | |
320 | ||
321 | /* Initializer for IOV type strings */ | |
322 | #define BCM_IOV_TYPE_INIT { \ | |
323 | "void", \ | |
324 | "bool", \ | |
562c8850 | 325 | "s8", \ |
de9bca63 | 326 | "u8", \ |
a9533e7e HP |
327 | "int16", \ |
328 | "uint16", \ | |
329 | "int32", \ | |
330 | "uint32", \ | |
331 | "buffer", \ | |
332 | "" } | |
333 | ||
334 | #define BCM_IOVT_IS_INT(type) (\ | |
335 | (type == IOVT_BOOL) || \ | |
336 | (type == IOVT_INT8) || \ | |
337 | (type == IOVT_UINT8) || \ | |
338 | (type == IOVT_INT16) || \ | |
339 | (type == IOVT_UINT16) || \ | |
340 | (type == IOVT_INT32) || \ | |
341 | (type == IOVT_UINT32)) | |
342 | ||
343 | /* ** driver/apps-shared section ** */ | |
344 | ||
345 | #define BCME_STRLEN 64 /* Max string length for BCM errors */ | |
346 | #define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) | |
347 | ||
348 | /* | |
349 | * error codes could be added but the defined ones shouldn't be changed/deleted | |
350 | * these error codes are exposed to the user code | |
351 | * when ever a new error code is added to this list | |
352 | * please update errorstring table with the related error string and | |
353 | * update osl files with os specific errorcode map | |
354 | */ | |
355 | ||
356 | #define BCME_OK 0 /* Success */ | |
357 | #define BCME_ERROR -1 /* Error generic */ | |
358 | #define BCME_BADARG -2 /* Bad Argument */ | |
359 | #define BCME_BADOPTION -3 /* Bad option */ | |
360 | #define BCME_NOTUP -4 /* Not up */ | |
361 | #define BCME_NOTDOWN -5 /* Not down */ | |
362 | #define BCME_NOTAP -6 /* Not AP */ | |
363 | #define BCME_NOTSTA -7 /* Not STA */ | |
364 | #define BCME_BADKEYIDX -8 /* BAD Key Index */ | |
365 | #define BCME_RADIOOFF -9 /* Radio Off */ | |
366 | #define BCME_NOTBANDLOCKED -10 /* Not band locked */ | |
367 | #define BCME_NOCLK -11 /* No Clock */ | |
368 | #define BCME_BADRATESET -12 /* BAD Rate valueset */ | |
369 | #define BCME_BADBAND -13 /* BAD Band */ | |
370 | #define BCME_BUFTOOSHORT -14 /* Buffer too short */ | |
371 | #define BCME_BUFTOOLONG -15 /* Buffer too long */ | |
372 | #define BCME_BUSY -16 /* Busy */ | |
373 | #define BCME_NOTASSOCIATED -17 /* Not Associated */ | |
374 | #define BCME_BADSSIDLEN -18 /* Bad SSID len */ | |
375 | #define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ | |
376 | #define BCME_BADCHAN -20 /* Bad Channel */ | |
377 | #define BCME_BADADDR -21 /* Bad Address */ | |
378 | #define BCME_NORESOURCE -22 /* Not Enough Resources */ | |
379 | #define BCME_UNSUPPORTED -23 /* Unsupported */ | |
380 | #define BCME_BADLEN -24 /* Bad length */ | |
381 | #define BCME_NOTREADY -25 /* Not Ready */ | |
382 | #define BCME_EPERM -26 /* Not Permitted */ | |
383 | #define BCME_NOMEM -27 /* No Memory */ | |
384 | #define BCME_ASSOCIATED -28 /* Associated */ | |
385 | #define BCME_RANGE -29 /* Not In Range */ | |
386 | #define BCME_NOTFOUND -30 /* Not Found */ | |
387 | #define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ | |
388 | #define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ | |
389 | #define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ | |
390 | #define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ | |
391 | #define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ | |
392 | #define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ | |
393 | #define BCME_VERSION -37 /* Incorrect version */ | |
394 | #define BCME_TXFAIL -38 /* TX failure */ | |
395 | #define BCME_RXFAIL -39 /* RX failure */ | |
396 | #define BCME_NODEVICE -40 /* Device not present */ | |
397 | #define BCME_NMODE_DISABLED -41 /* NMODE disabled */ | |
398 | #define BCME_NONRESIDENT -42 /* access to nonresident overlay */ | |
399 | #define BCME_LAST BCME_NONRESIDENT | |
400 | ||
401 | /* These are collection of BCME Error strings */ | |
402 | #define BCMERRSTRINGTABLE { \ | |
403 | "OK", \ | |
404 | "Undefined error", \ | |
405 | "Bad Argument", \ | |
406 | "Bad Option", \ | |
407 | "Not up", \ | |
408 | "Not down", \ | |
409 | "Not AP", \ | |
410 | "Not STA", \ | |
411 | "Bad Key Index", \ | |
412 | "Radio Off", \ | |
413 | "Not band locked", \ | |
414 | "No clock", \ | |
415 | "Bad Rate valueset", \ | |
416 | "Bad Band", \ | |
417 | "Buffer too short", \ | |
418 | "Buffer too long", \ | |
419 | "Busy", \ | |
420 | "Not Associated", \ | |
421 | "Bad SSID len", \ | |
422 | "Out of Range Channel", \ | |
423 | "Bad Channel", \ | |
424 | "Bad Address", \ | |
425 | "Not Enough Resources", \ | |
426 | "Unsupported", \ | |
427 | "Bad length", \ | |
428 | "Not Ready", \ | |
429 | "Not Permitted", \ | |
430 | "No Memory", \ | |
431 | "Associated", \ | |
432 | "Not In Range", \ | |
433 | "Not Found", \ | |
434 | "WME Not Enabled", \ | |
435 | "TSPEC Not Found", \ | |
436 | "ACM Not Supported", \ | |
437 | "Not WME Association", \ | |
438 | "SDIO Bus Error", \ | |
439 | "Dongle Not Accessible", \ | |
440 | "Incorrect version", \ | |
441 | "TX Failure", \ | |
442 | "RX Failure", \ | |
443 | "Device Not Present", \ | |
444 | "NMODE Disabled", \ | |
445 | "Nonresident overlay access", \ | |
446 | } | |
447 | ||
448 | #ifndef ABS | |
5fee2540 | 449 | #define ABS(a) (((a) < 0) ? -(a) : (a)) |
a9533e7e HP |
450 | #endif /* ABS */ |
451 | ||
452 | #ifndef MIN | |
5fee2540 | 453 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
a9533e7e HP |
454 | #endif /* MIN */ |
455 | ||
456 | #ifndef MAX | |
5fee2540 | 457 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) |
a9533e7e HP |
458 | #endif /* MAX */ |
459 | ||
460 | #define CEIL(x, y) (((x) + ((y)-1)) / (y)) | |
461 | #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) | |
462 | #define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) | |
463 | #define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ | |
464 | & ~((boundary) - 1)) | |
465 | #define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) | |
0d706ef4 | 466 | #define VALID_MASK(mask) (!((mask) & ((mask) + 1))) |
a9533e7e HP |
467 | #ifndef OFFSETOF |
468 | #define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) | |
469 | #endif /* OFFSETOF */ | |
470 | #ifndef ARRAYSIZE | |
471 | #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) | |
472 | #endif | |
473 | ||
474 | /* bit map related macros */ | |
475 | #ifndef setbit | |
476 | #ifndef NBBY /* the BSD family defines NBBY */ | |
477 | #define NBBY 8 /* 8 bits per byte */ | |
478 | #endif /* #ifndef NBBY */ | |
de9bca63 GKH |
479 | #define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) |
480 | #define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) | |
481 | #define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) | |
482 | #define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) | |
a9533e7e HP |
483 | #endif /* setbit */ |
484 | ||
485 | #define NBITS(type) (sizeof(type) * 8) | |
486 | #define NBITVAL(nbits) (1 << (nbits)) | |
487 | #define MAXBITVAL(nbits) ((1 << (nbits)) - 1) | |
488 | #define NBITMASK(nbits) MAXBITVAL(nbits) | |
489 | #define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) | |
490 | ||
491 | /* basic mux operation - can be optimized on several architectures */ | |
492 | #define MUX(pred, true, false) ((pred) ? (true) : (false)) | |
493 | ||
494 | /* modulo inc/dec - assumes x E [0, bound - 1] */ | |
495 | #define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) | |
496 | #define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) | |
497 | ||
498 | /* modulo inc/dec, bound = 2^k */ | |
499 | #define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) | |
500 | #define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) | |
501 | ||
502 | /* modulo add/sub - assumes x, y E [0, bound - 1] */ | |
503 | #define MODADD(x, y, bound) \ | |
504 | MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) | |
505 | #define MODSUB(x, y, bound) \ | |
506 | MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) | |
507 | ||
508 | /* module add/sub, bound = 2^k */ | |
509 | #define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) | |
510 | #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) | |
511 | ||
512 | /* crc defines */ | |
513 | #define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ | |
514 | #define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ | |
515 | #define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ | |
516 | #define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ | |
517 | ||
518 | /* bcm_format_flags() bit description structure */ | |
519 | typedef struct bcm_bit_desc { | |
520 | uint32 bit; | |
521 | const char *name; | |
522 | } bcm_bit_desc_t; | |
523 | ||
524 | /* tag_ID/length/value_buffer tuple */ | |
525 | typedef struct bcm_tlv { | |
de9bca63 GKH |
526 | u8 id; |
527 | u8 len; | |
528 | u8 data[1]; | |
a9533e7e HP |
529 | } bcm_tlv_t; |
530 | ||
531 | /* Check that bcm_tlv_t fits into the given buflen */ | |
532 | #define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) | |
533 | ||
534 | /* buffer length for ethernet address from bcm_ether_ntoa() */ | |
535 | #define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ | |
536 | ||
537 | /* crypto utility function */ | |
538 | /* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */ | |
2d956e22 | 539 | static inline void |
de9bca63 | 540 | xor_128bit_block(const u8 *src1, const u8 *src2, u8 *dst) { |
a9533e7e HP |
541 | if ( |
542 | #ifdef __i386__ | |
543 | 1 || | |
544 | #endif | |
545 | (((uintptr) src1 | (uintptr) src2 | (uintptr) dst) & | |
546 | 3) == 0) { | |
547 | /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */ | |
548 | /* x86 supports unaligned. This version runs 6x-9x faster on x86. */ | |
549 | ((uint32 *) dst)[0] = | |
550 | ((const uint32 *)src1)[0] ^ ((const uint32 *) | |
551 | src2)[0]; | |
552 | ((uint32 *) dst)[1] = | |
553 | ((const uint32 *)src1)[1] ^ ((const uint32 *) | |
554 | src2)[1]; | |
555 | ((uint32 *) dst)[2] = | |
556 | ((const uint32 *)src1)[2] ^ ((const uint32 *) | |
557 | src2)[2]; | |
558 | ((uint32 *) dst)[3] = | |
559 | ((const uint32 *)src1)[3] ^ ((const uint32 *) | |
560 | src2)[3]; | |
561 | } else { | |
562 | /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */ | |
563 | int k; | |
564 | for (k = 0; k < 16; k++) | |
565 | dst[k] = src1[k] ^ src2[k]; | |
566 | } | |
567 | } | |
568 | ||
569 | /* externs */ | |
570 | /* crc */ | |
de9bca63 GKH |
571 | extern u8 BCMROMFN(hndcrc8) (u8 *p, uint nbytes, u8 crc); |
572 | extern uint16 BCMROMFN(hndcrc16) (u8 *p, uint nbytes, uint16 crc); | |
a9533e7e HP |
573 | /* format/print */ |
574 | #if defined(BCMDBG) | |
7cc4a4c0 | 575 | extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, |
a9533e7e HP |
576 | char *buf, int len); |
577 | extern int bcm_format_hex(char *str, const void *bytes, int len); | |
578 | #endif | |
52b0e80e | 579 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
580 | #ifdef BCMDBG |
581 | extern void deadbeef(void *p, uint len); | |
582 | #endif | |
583 | extern const char *bcm_crypto_algo_name(uint algo); | |
52b0e80e | 584 | #endif /* BRCM_FULLMAC */ |
a9533e7e | 585 | extern char *bcm_chipname(uint chipid, char *buf, uint len); |
52b0e80e | 586 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
587 | extern char *bcm_brev_str(uint32 brev, char *buf); |
588 | extern void printbig(char *buf); | |
52b0e80e | 589 | #endif /* BRCM_FULLMAC */ |
580a0bd9 | 590 | extern void prhex(const char *msg, unsigned char *buf, uint len); |
a9533e7e | 591 | |
52b0e80e | 592 | #ifdef BRCM_FULLMAC |
a9533e7e | 593 | /* IE parsing */ |
7cc4a4c0 | 594 | extern bcm_tlv_t *BCMROMFN(bcm_next_tlv) (bcm_tlv_t *elt, int *buflen); |
a9533e7e HP |
595 | extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs) (void *buf, |
596 | int buflen, | |
597 | uint key); | |
52b0e80e BR |
598 | #endif |
599 | extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs) (void *buf, int buflen, | |
600 | uint key); | |
601 | #ifdef BRCM_FULLMAC | |
a9533e7e HP |
602 | /* bcmerror */ |
603 | extern const char *bcmerrorstr(int bcmerror); | |
52b0e80e | 604 | #endif |
a9533e7e HP |
605 | |
606 | /* multi-bool data type: set of bools, mbool is true if any is set */ | |
607 | typedef uint32 mbool; | |
608 | #define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ | |
609 | #define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ | |
610 | #define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */ | |
611 | #define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) | |
612 | ||
52b0e80e | 613 | #ifdef BRCM_FULLMAC |
a9533e7e | 614 | /* power conversion */ |
de9bca63 GKH |
615 | extern uint16 BCMROMFN(bcm_qdbm_to_mw) (u8 qdbm); |
616 | extern u8 BCMROMFN(bcm_mw_to_qdbm) (uint16 mw); | |
52b0e80e | 617 | #endif |
a9533e7e HP |
618 | |
619 | /* generic datastruct to help dump routines */ | |
620 | struct fielddesc { | |
621 | const char *nameandfmt; | |
622 | uint32 offset; | |
623 | uint32 len; | |
624 | }; | |
625 | ||
52b0e80e | 626 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
627 | extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); |
628 | extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); | |
580a0bd9 GKH |
629 | extern void bcm_inc_bytes(unsigned char *num, int num_bytes, u8 amount); |
630 | extern int bcm_cmp_bytes(unsigned char *arg1, unsigned char *arg2, u8 nbytes); | |
631 | extern void bcm_print_bytes(char *name, const unsigned char *cdata, int len); | |
52b0e80e | 632 | #endif |
a9533e7e HP |
633 | |
634 | typedef uint32(*bcmutl_rdreg_rtn) (void *arg0, uint arg1, | |
635 | uint32 offset); | |
52b0e80e | 636 | #ifdef BRCM_FULLMAC |
a9533e7e HP |
637 | extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, |
638 | uint arg1, struct fielddesc *str, char *buf, | |
639 | uint32 bufsize); | |
640 | ||
641 | extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, | |
642 | uint len); | |
52b0e80e | 643 | #endif |
de9bca63 | 644 | extern uint BCMROMFN(bcm_bitcount) (u8 *bitmap, uint bytelength); |
a9533e7e HP |
645 | |
646 | #ifdef __cplusplus | |
647 | } | |
648 | #endif | |
649 | ||
650 | #endif /* _bcmutils_h_ */ |