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