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