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