1b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
2b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Driver O/S-independent utility routines
3b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * Copyright (C) 1999-2013, Broadcom Corporation
5ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt *
66dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Permission to use, copy, modify, and/or distribute this software for any
76dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * purpose with or without fee is hereby granted, provided that the above
86dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * copyright notice and this permission notice appear in all copies.
96dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
106dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
116dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
126dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
1838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * $Id: bcmutils.c 380908 2013-01-24 12:26:18Z $
19b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
20b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
21ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#include <bcm_cfg.h>
22b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <typedefs.h>
23b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmdefs.h>
24b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <stdarg.h>
25b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef BCMDRIVER
26b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
27b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <osl.h>
28b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmutils.h>
29b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
30b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#else /* !BCMDRIVER */
31b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
32b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <stdio.h>
33b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <string.h>
34b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmutils.h>
35b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
36b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(BCMEXTSUP)
37b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcm_osl.h>
38b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif
39b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
40b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
41b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* !BCMDRIVER */
42b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
43b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmendian.h>
44b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <bcmdevs.h>
45b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/ethernet.h>
46b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/vlan.h>
47b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/bcmip.h>
48b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/802.1d.h>
49b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#include <proto/802.11.h>
50b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid *_bcmutils_dummy_fn = NULL;
51b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
52ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
53b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef BCMDRIVER
54b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
55b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
56b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
57b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* copy a pkt buffer chain into a buffer */
58b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint
59b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
60b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
61b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint n, ret = 0;
62b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
63b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (len < 0)
64ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		len = 4096;	/* "infinite" */
65b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
66b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* skip 'offset' bytes */
67b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; p && offset; p = PKTNEXT(osh, p)) {
68b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (offset < (uint)PKTLEN(osh, p))
69b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
70b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset -= PKTLEN(osh, p);
71b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
72b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
73b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!p)
74b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
75b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
76b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* copy the data */
77b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; p && len; p = PKTNEXT(osh, p)) {
78b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
79b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bcopy(PKTDATA(osh, p) + offset, buf, n);
80b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf += n;
81b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len -= n;
82b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret += n;
83b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset = 0;
84b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
85b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
86b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
87b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
88b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
89b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* copy a buffer into a pkt buffer chain */
90b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint
91b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf)
92b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
93b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint n, ret = 0;
94b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
95b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* skip 'offset' bytes */
96b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; p && offset; p = PKTNEXT(osh, p)) {
97b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (offset < (uint)PKTLEN(osh, p))
98b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
99b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset -= PKTLEN(osh, p);
100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
101b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
102b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!p)
103b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
104b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
105b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* copy the data */
106b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; p && len; p = PKTNEXT(osh, p)) {
107b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
108b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bcopy(buf, PKTDATA(osh, p) + offset, n);
109b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf += n;
110b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len -= n;
111b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ret += n;
112b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset = 0;
113b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
114b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
115b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ret;
116b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
117b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
120b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* return total length of buffer chain */
121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint BCMFASTPATH
122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpkttotlen(osl_t *osh, void *p)
123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint total;
125ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int len;
126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
127b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	total = 0;
128ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	for (; p; p = PKTNEXT(osh, p)) {
129ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		len = PKTLEN(osh, p);
130ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		total += len;
131ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
132ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (total);
134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
135b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* return the last buffer of chained pkt */
137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid *
138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktlast(osl_t *osh, void *p)
139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		;
142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (p);
144b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* count segments of a chained packet */
147b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint BCMFASTPATH
148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktsegcnt(osl_t *osh, void *p)
149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint cnt;
151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
152b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (cnt = 0; p; p = PKTNEXT(osh, p))
153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cnt++;
154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
155b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return cnt;
156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
157b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
158b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
159ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* count segments of a chained packet */
160ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtuint BCMFASTPATH
161ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtpktsegcnt_war(osl_t *osh, void *p)
162ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
163ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint cnt;
164ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 *pktdata;
165ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint len, remain, align64;
166ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
167ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	for (cnt = 0; p; p = PKTNEXT(osh, p)) {
168ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		cnt++;
169ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		len = PKTLEN(osh, p);
170ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (len > 128) {
171ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			pktdata = (uint8 *)PKTDATA(osh, p);	/* starting address of data */
172ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			/* Check for page boundary straddle (2048B) */
173ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff))
174ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				cnt++;
175ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
176ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			align64 = (uint)((uintptr)pktdata & 0x3f);	/* aligned to 64B */
177ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			align64 = (64 - align64) & 0x3f;
178ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			len -= align64;		/* bytes from aligned 64B to end */
179ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			/* if aligned to 128B, check for MOD 128 between 1 to 4B */
180ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			remain = len % 128;
181ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (remain > 0 && remain <= 4)
182ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				cnt++;		/* add extra seg */
183ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
184ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
185ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
186ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return cnt;
187ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
188ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
189ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtuint8 * BCMFASTPATH
19038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtpktdataoffset(osl_t *osh, void *p,  uint offset)
191ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
192ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint total = pkttotlen(osh, p);
193ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint pkt_off = 0, len = 0;
194ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 *pdata = (uint8 *) PKTDATA(osh, p);
195ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
196ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (offset > total)
197ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return NULL;
198ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
199ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	for (; p; p = PKTNEXT(osh, p)) {
200ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		pdata = (uint8 *) PKTDATA(osh, p);
201ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		pkt_off = offset - len;
202ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		len += PKTLEN(osh, p);
203ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (len > offset)
204ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			break;
205ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
206ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return (uint8*) (pdata+pkt_off);
207ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
208ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
20938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
21038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* given a offset in pdata, find the pkt seg hdr */
21138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid *
21238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtpktoffset(osl_t *osh, void *p,  uint offset)
21338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
21438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint total = pkttotlen(osh, p);
21538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint len = 0;
21638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
21738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (offset > total)
21838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return NULL;
21938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
22038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	for (; p; p = PKTNEXT(osh, p)) {
22138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		len += PKTLEN(osh, p);
22238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (len > offset)
22338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
22438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
22538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return p;
22638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
22738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
229b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * osl multiple-precedence packet queue
230b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * hi_prec is always >= the number of the highest non-empty precedence
231b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
232b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
233b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_penq(struct pktq *pq, int prec, void *p)
234b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
235b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
236b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
237b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
238b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */
239b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
240b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(!pktq_full(pq));
241b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(!pktq_pfull(pq, prec));
242b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
243b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
244b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
245b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (q->head)
246b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		PKTSETLINK(q->tail, p);
247b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
248b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->head = p;
249b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
250b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->tail = p;
251b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len++;
252b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
253b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len++;
254b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
255b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->hi_prec < prec)
256b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->hi_prec = (uint8)prec;
257b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
258b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
259b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
260b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
261b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
262b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_penq_head(struct pktq *pq, int prec, void *p)
263b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
264b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
265b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
266b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
267b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */
268b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
269b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(!pktq_full(pq));
270b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(!pktq_pfull(pq, prec));
271b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
272b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
273b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
274b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (q->head == NULL)
275b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->tail = p;
276b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
277b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(p, q->head);
278b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->head = p;
279b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len++;
280b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
281b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len++;
282b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
283b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->hi_prec < prec)
284b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->hi_prec = (uint8)prec;
285b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
286b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
287b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
288b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
289b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
290b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_pdeq(struct pktq *pq, int prec)
291b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
292b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
293b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p;
294b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
295b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
296b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
297b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
298b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
299b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((p = q->head) == NULL)
300b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
301b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
302b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
303b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->tail = NULL;
304b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
305b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
306b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
307b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
308b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
309b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(p, NULL);
310b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
311b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
312b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
313b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
314b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
315ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtpktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p)
316ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
317ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct pktq_prec *q;
318ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	void *p;
319ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
320ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
321ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
322ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	q = &pq->q[prec];
323ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
324ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (prev_p == NULL)
325ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return NULL;
326ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
327ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((p = PKTLINK(prev_p)) == NULL)
328ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return NULL;
329ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
330ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	q->len--;
331ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
332ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	pq->len--;
333ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
334ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	PKTSETLINK(prev_p, PKTLINK(p));
335ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	PKTSETLINK(p, NULL);
336ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
337ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return p;
338ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
339ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
340ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtvoid * BCMFASTPATH
34138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtpktq_pdeq_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg)
34238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
34338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	struct pktq_prec *q;
34438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	void *p, *prev = NULL;
34538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
34638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
34738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
34838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	q = &pq->q[prec];
34938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	p = q->head;
35038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
35138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while (p) {
35238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (fn == NULL || (*fn)(p, arg)) {
35338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
35438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		} else {
35538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			prev = p;
35638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			p = PKTLINK(p);
35738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
35838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
35938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (p == NULL)
36038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return NULL;
36138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
36238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (prev == NULL) {
36338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if ((q->head = PKTLINK(p)) == NULL)
36438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			q->tail = NULL;
36538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	} else {
36638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		PKTSETLINK(prev, PKTLINK(p));
36738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
36838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
36938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	q->len--;
37038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
37138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	pq->len--;
37238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
37338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	PKTSETLINK(p, NULL);
37438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
37538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return p;
37638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
37738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
37838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid * BCMFASTPATH
379b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_pdeq_tail(struct pktq *pq, int prec)
380b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
381b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
382b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p, *prev;
383b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
384b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
385b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
386b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
387b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
388b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((p = q->head) == NULL)
389b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
390b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
391b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prev = NULL; p != q->tail; p = PKTLINK(p))
392b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		prev = p;
393b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
394b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prev)
395b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		PKTSETLINK(prev, NULL);
396b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
397b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->head = NULL;
398b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
399b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->tail = prev;
400b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
401b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
402b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
403b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
404b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
405b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
406b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
407b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
408b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg)
409b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
410b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
411b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p, *prev = NULL;
412b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
413b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
414b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = q->head;
415b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (p) {
416b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (fn == NULL || (*fn)(p, arg)) {
417b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bool head = (p == q->head);
418b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (head)
419b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				q->head = PKTLINK(p);
420b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			else
421b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				PKTSETLINK(prev, PKTLINK(p));
422b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			PKTSETLINK(p, NULL);
423b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			PKTFREE(osh, p, dir);
424b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			q->len--;
425b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			pq->len--;
426b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p = (head ? q->head : PKTLINK(prev));
427b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
428b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			prev = p;
429b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p = PKTLINK(p);
430b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
431b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
432b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
433b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (q->head == NULL) {
434b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ASSERT(q->len == 0);
435b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->tail = NULL;
436b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
437b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
438b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
439b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbool BCMFASTPATH
440b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_pdel(struct pktq *pq, void *pktbuf, int prec)
441b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
442b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
443b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p;
444b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
445b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
446b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
447b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!pktbuf)
448b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return FALSE;
449b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
450b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
451b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
452b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (q->head == pktbuf) {
453b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if ((q->head = PKTLINK(pktbuf)) == NULL)
454b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			q->tail = NULL;
455b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
456b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p))
457b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			;
458b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (p == NULL)
459b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return FALSE;
460b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
461b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		PKTSETLINK(p, PKTLINK(pktbuf));
462b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (q->tail == pktbuf)
463b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			q->tail = p;
464b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
465b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
466b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
467b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
468b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(pktbuf, NULL);
469b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return TRUE;
470b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
471b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
472b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
473b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_init(struct pktq *pq, int num_prec, int max_len)
474b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
475b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
476b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
477b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
478b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
479b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* pq is variable size; only zero out what's requested */
480b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
481b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
482b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->num_prec = (uint16)num_prec;
483b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
484b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->max = (uint16)max_len;
485b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
486b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prec = 0; prec < num_prec; prec++)
487b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->q[prec].max = pq->max;
488b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
489b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
490ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtvoid
491ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtpktq_set_max_plen(struct pktq *pq, int prec, int max_len)
492ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
493ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
494ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
495ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (prec < pq->num_prec)
496ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		pq->q[prec].max = (uint16)max_len;
497ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
498ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
499b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
500b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_deq(struct pktq *pq, int *prec_out)
501b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
502b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
503b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p;
504b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
505b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
506b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->len == 0)
507b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
508b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
509b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
510b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->hi_prec--;
511b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
512b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
513b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
514b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((p = q->head) == NULL)
515b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
516b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
517b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
518b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->tail = NULL;
519b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
520b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
521b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
522b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
523b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
524b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prec_out)
525b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*prec_out = prec;
526b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
527b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(p, NULL);
528b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
529b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
530b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
531b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
532b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
533b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_deq_tail(struct pktq *pq, int *prec_out)
534b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
535b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
536b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p, *prev;
537b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
538b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
539b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->len == 0)
540b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
541b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
542b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prec = 0; prec < pq->hi_prec; prec++)
543b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (pq->q[prec].head)
544b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
545b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
546b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
547b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
548b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((p = q->head) == NULL)
549b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
550b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
551b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prev = NULL; p != q->tail; p = PKTLINK(p))
552b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		prev = p;
553b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
554b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prev)
555b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		PKTSETLINK(prev, NULL);
556b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
557b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->head = NULL;
558b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
559b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->tail = prev;
560b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
561b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
562b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
563b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
564b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prec_out)
565b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*prec_out = prec;
566b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
567b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(p, NULL);
568b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
569b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
570b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
571b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
572b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid *
573b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_peek(struct pktq *pq, int *prec_out)
574b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
575b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
576b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
577b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->len == 0)
578b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
579b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
580b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
581b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->hi_prec--;
582b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
583b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prec_out)
584b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*prec_out = prec;
585b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
586b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (pq->q[prec].head);
587b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
588b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
589b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid *
590b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_peek_tail(struct pktq *pq, int *prec_out)
591b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
592b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
593b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
594b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->len == 0)
595b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
596b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
597b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prec = 0; prec < pq->hi_prec; prec++)
598b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (pq->q[prec].head)
599b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
600b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
601b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prec_out)
602b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*prec_out = prec;
603b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
604b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (pq->q[prec].tail);
605b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
606b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
607b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
608b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg)
609b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
610b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
611ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
612ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Optimize flush, if pktq len = 0, just return.
613ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 * pktq len of 0 means pktq's prec q's are all empty.
614ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 */
615ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (pq->len == 0) {
616ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return;
617ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
618ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
619b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prec = 0; prec < pq->num_prec; prec++)
620b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pktq_pflush(osh, pq, prec, dir, fn, arg);
621b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (fn == NULL)
622b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ASSERT(pq->len == 0);
623b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
624b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
625b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Return sum of lengths of a specific set of precedences */
626b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
627b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_mlen(struct pktq *pq, uint prec_bmp)
628b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
629b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec, len;
630b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
631b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = 0;
632b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
633b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (prec = 0; prec <= pq->hi_prec; prec++)
634b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (prec_bmp & (1 << prec))
635b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len += pq->q[prec].len;
636b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
637b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return len;
638b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
639b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
640ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* Priority peek from a specific set of precedences */
641ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtvoid * BCMFASTPATH
642ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtpktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out)
643ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
644ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct pktq_prec *q;
645ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	void *p;
646ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int prec;
647ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
648ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (pq->len == 0)
649ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	{
650ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return NULL;
651ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
652ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
653ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		pq->hi_prec--;
654ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
655ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
656ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (prec-- == 0)
657ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return NULL;
658ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
659ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	q = &pq->q[prec];
660ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
661ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((p = q->head) == NULL)
662ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return NULL;
663ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
664ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (prec_out)
665ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		*prec_out = prec;
666ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
667ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return p;
668ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
669b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Priority dequeue from a specific set of precedences */
670b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid * BCMFASTPATH
671b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
672b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
673b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct pktq_prec *q;
674b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p;
675b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int prec;
676b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
677b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (pq->len == 0)
678b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
679b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
680b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
681b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pq->hi_prec--;
682b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
683ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0))
684b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (prec-- == 0)
685b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return NULL;
686b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
687b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q = &pq->q[prec];
688b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
689b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((p = q->head) == NULL)
690b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
691b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
692b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
693b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		q->tail = NULL;
694b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
695b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	q->len--;
696b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
697b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (prec_out)
698b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*prec_out = prec;
699b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
700b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pq->len--;
701b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
702b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETLINK(p, NULL);
703b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
704b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return p;
705b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
706b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
707b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BCMDRIVER */
708b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
70938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS)
710b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtconst unsigned char bcm_ctype[] = {
711b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
712ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 0-7 */
713b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
714ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_C,	/* 8-15 */
715ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 16-23 */
716ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 24-31 */
717ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,		/* 32-39 */
718ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 40-47 */
719ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,			/* 48-55 */
720ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 56-63 */
721b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
722b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_U|_BCM_X, _BCM_U, /* 64-71 */
723ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 72-79 */
724ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 80-87 */
725ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 88-95 */
726b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
727b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L|_BCM_X, _BCM_L, /* 96-103 */
728b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
729b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
730b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
731ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 128-143 */
732ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 144-159 */
733b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
734ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 160-175 */
735b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
736ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 176-191 */
737b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
738ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,	/* 192-207 */
739b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
740ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L,	/* 208-223 */
741b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
742ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,	/* 224-239 */
743b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
744b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
745b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
746b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
747b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtulong
748ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_strtoul(const char *cp, char **endp, uint base)
749b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
750b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ulong result, last_result = 0, value;
751b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool minus;
752b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
753b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	minus = FALSE;
754b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
755b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (bcm_isspace(*cp))
756b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cp++;
757b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
758b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (cp[0] == '+')
759b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cp++;
760b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else if (cp[0] == '-') {
761b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		minus = TRUE;
762b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cp++;
763b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
764b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
765b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (base == 0) {
766b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (cp[0] == '0') {
767b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if ((cp[1] == 'x') || (cp[1] == 'X')) {
768b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				base = 16;
769b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				cp = &cp[2];
770b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			} else {
771b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				base = 8;
772b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				cp = &cp[1];
773b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
774b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else
775b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			base = 10;
776b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
777b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cp = &cp[2];
778b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
779b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
780b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	result = 0;
781b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
782b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (bcm_isxdigit(*cp) &&
783ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	       (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
784b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		result = result*base + value;
785b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Detected overflow */
786b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (result < last_result && !minus)
787b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (ulong)-1;
788b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		last_result = result;
789b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cp++;
790b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
791b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
792b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (minus)
793b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		result = (ulong)(-(long)result);
794b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
795b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (endp)
796ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		*endp = DISCARD_QUAL(cp, char);
797b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
798b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (result);
799b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
800b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
801b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
802ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_atoi(const char *s)
803b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
804b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (int)bcm_strtoul(s, NULL, 10);
805b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
806b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
807b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* return pointer to location of substring 'needle' in 'haystack' */
808ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtchar *
809ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcmstrstr(const char *haystack, const char *needle)
810b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
811b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len, nlen;
812b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
813b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
814b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((haystack == NULL) || (needle == NULL))
815ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return DISCARD_QUAL(haystack, char);
816b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
817b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	nlen = strlen(needle);
818b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(haystack) - nlen + 1;
819b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
820b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < len; i++)
821b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (memcmp(needle, &haystack[i], nlen) == 0)
822ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return DISCARD_QUAL(&haystack[i], char);
823b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (NULL);
824b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
825b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
826ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtchar *
827b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmstrcat(char *dest, const char *src)
828b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
829b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p;
830b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
831b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = dest + strlen(dest);
832b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
833b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while ((*p++ = *src++) != '\0')
834b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		;
835b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
836b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (dest);
837b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
838b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
839ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtchar *
840b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmstrncat(char *dest, const char *src, uint size)
841b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
842b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endp;
843b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p;
844b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
845b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = dest + strlen(dest);
846b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	endp = p + size;
847b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
848b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (p != endp && (*p++ = *src++) != '\0')
849b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		;
850b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
851b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (dest);
852b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
853b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
854b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
855b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/****************************************************************************
856b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Function:   bcmstrtok
857b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
858b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Purpose:
859b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  Tokenizes a string. This function is conceptually similiar to ANSI C strtok(),
860b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  but allows strToken() to be used by different strings or callers at the same
861b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  time. Each call modifies '*string' by substituting a NULL character for the
862b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  first delimiter that is encountered, and updates 'string' to point to the char
863b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  after the delimiter. Leading delimiters are skipped.
864b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
865b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Parameters:
866b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  string      (mod) Ptr to string ptr, updated by token.
867b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  delimiters  (in)  Set of delimiter characters.
868b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*  tokdelim    (out) Character that delimits the returned token. (May
869b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*                    be set to NULL if token delimiter is not required).
870b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
871b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Returns:  Pointer to the next token found. NULL when no more tokens are found.
872b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*****************************************************************************
873b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*/
874b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *
875b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmstrtok(char **string, const char *delimiters, char *tokdelim)
876b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
877b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	unsigned char *str;
878b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	unsigned long map[8];
879b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int count;
880b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *nextoken;
881b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
882b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (tokdelim != NULL) {
883b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Prime the token delimiter */
884b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*tokdelim = '\0';
885b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
886b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
887b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Clear control map */
888b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (count = 0; count < 8; count++) {
889b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		map[count] = 0;
890b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
891b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
892b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Set bits in delimiter table */
893b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	do {
894b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		map[*delimiters >> 5] |= (1 << (*delimiters & 31));
895b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
896b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*delimiters++);
897b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
898b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	str = (unsigned char*)*string;
899b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
900b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Find beginning of token (skip over leading delimiters). Note that
901b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * there is no token iff this loop sets str to point to the terminal
902b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * null (*str == '\0')
903b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
904b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) {
905b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		str++;
906b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
907b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
908b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	nextoken = (char*)str;
909b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
910b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Find the end of the token. If it is not the end of the string,
911b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * put a null there.
912b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
913b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (; *str; str++) {
914b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (map[*str >> 5] & (1 << (*str & 31))) {
915b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (tokdelim != NULL) {
916b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				*tokdelim = *str;
917b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			}
918b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
919b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*str++ = '\0';
920b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
921b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
922b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
923b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
924b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*string = (char*)str;
925b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
926b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Determine if a token has been found. */
927b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (nextoken == (char *) str) {
928b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
929b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
930b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else {
931b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return nextoken;
932b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
933b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
934b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
935b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
936b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define xToLower(C) \
937b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C)
938b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
939b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
940b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/****************************************************************************
941b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Function:   bcmstricmp
942b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
943b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Purpose:    Compare to strings case insensitively.
944b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
945b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Parameters: s1 (in) First string to compare.
946b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             s2 (in) Second string to compare.
947b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
948b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
949b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             t1 > t2, when ignoring case sensitivity.
950b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*****************************************************************************
951b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*/
952b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
953b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmstricmp(const char *s1, const char *s2)
954b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
955b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char dc, sc;
956b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
957b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*s2 && *s1) {
958b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		dc = xToLower(*s1);
959b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sc = xToLower(*s2);
960b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (dc < sc) return -1;
961b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (dc > sc) return 1;
962b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		s1++;
963b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		s2++;
964b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
965b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
966b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*s1 && !*s2) return 1;
967b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*s1 && *s2) return -1;
968b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
969b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
970b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
971b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
972b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/****************************************************************************
973b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Function:   bcmstrnicmp
974b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
975b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Purpose:    Compare to strings case insensitively, upto a max of 'cnt'
976b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             characters.
977b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
978b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Parameters: s1  (in) First string to compare.
979b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             s2  (in) Second string to compare.
980b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             cnt (in) Max characters to compare.
981b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*
982b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
983b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*             t1 > t2, when ignoring case sensitivity.
984b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*****************************************************************************
985b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*/
986b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
987b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmstrnicmp(const char* s1, const char* s2, int cnt)
988b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
989b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char dc, sc;
990b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
991b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (*s2 && *s1 && cnt) {
992b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		dc = xToLower(*s1);
993b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		sc = xToLower(*s2);
994b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (dc < sc) return -1;
995b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (dc > sc) return 1;
996b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		s1++;
997b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		s2++;
998b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cnt--;
999b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1000b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1001b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!cnt) return 0;
1002b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (*s1 && !*s2) return 1;
1003b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!*s1 && *s2) return -1;
1004b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
1005b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1006b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1007b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
1008b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
1009ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_ether_atoe(const char *p, struct ether_addr *ea)
1010b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1011b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i = 0;
1012ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	char *ep;
1013b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1014b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (;;) {
1015ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16);
1016ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		p = ep;
1017b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!*p++ || i == 6)
1018b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1019b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1020b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1021b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (i == 6);
1022b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
102338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif	/* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */
1024b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1025b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1026b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
1027b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* registry routine buffer preparation utility functions:
1028b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * parameter order is like strncpy, but returns count
1029b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
1030b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1031b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtulong
1032b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtwchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen)
1033b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1034b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ulong copyct = 1;
1035b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ushort i;
1036b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1037b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (abuflen == 0)
1038b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
1039b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1040b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* wbuflen is in bytes */
1041b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	wbuflen /= sizeof(ushort);
1042b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1043b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < wbuflen; ++i) {
1044b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (--abuflen == 0)
1045b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1046b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*abuf++ = (char) *wbuf++;
1047b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		++copyct;
1048b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1049b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*abuf = '\0';
1050b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1051b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return copyct;
1052b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1053b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */
1054b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1055b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *
1056b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_ether_ntoa(const struct ether_addr *ea, char *buf)
1057b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1058ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	static const char hex[] =
1059ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	  {
1060ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		  '0', '1', '2', '3', '4', '5', '6', '7',
1061ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
1062ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	  };
1063ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	const uint8 *octet = ea->octet;
1064ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	char *p = buf;
1065ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int i;
1066ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1067ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	for (i = 0; i < 6; i++, octet++) {
1068ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		*p++ = hex[(*octet >> 4) & 0xf];
1069ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		*p++ = hex[*octet & 0xf];
1070ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		*p++ = ':';
1071ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1072ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1073ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	*(p-1) = '\0';
1074ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
1075b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (buf);
1076b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1077b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1078b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *
1079b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_ip_ntoa(struct ipv4_addr *ia, char *buf)
1080b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1081b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	snprintf(buf, 16, "%d.%d.%d.%d",
1082ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	         ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]);
1083b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (buf);
1084b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1085b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1086b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef BCMDRIVER
1087b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1088b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1089b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_mdelay(uint ms)
1090b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1091b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint i;
1092b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1093b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < ms; i++) {
1094b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		OSL_DELAY(1000);
1095b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1096b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1097b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1098b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1099b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1100b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1101b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1102b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(DHD_DEBUG)
1103b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* pretty hex print a pkt buffer chain */
1104b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1105b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtprpkt(const char *msg, osl_t *osh, void *p0)
1106b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1107b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	void *p;
1108b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1109b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (msg && (msg[0] != '\0'))
1110b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s:\n", msg);
1111b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1112b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (p = p0; p; p = PKTNEXT(osh, p))
1113b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p));
1114b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1115ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif
1116b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1117b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
1118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Also updates the inplace vlan tag if requested.
1119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * For debugging, it returns an indication of what it did.
1120b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint BCMFASTPATH
1122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtpktsetprio(void *pkt, bool update_vtag)
1123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct ether_header *eh;
1125b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct ethervlan_header *evh;
1126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 *pktdata;
1127b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int priority = 0;
1128b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int rc = 0;
1129b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1130ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	pktdata = (uint8 *)PKTDATA(NULL, pkt);
1131b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
1132b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	eh = (struct ether_header *) pktdata;
1134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
113538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) {
1136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint16 vlan_tag;
1137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		int vlan_prio, dscp_prio = 0;
1138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		evh = (struct ethervlan_header *)eh;
1140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		vlan_tag = ntoh16(evh->vlan_tag);
1142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
1143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
114438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (evh->ether_type == hton16(ETHER_TYPE_IP)) {
1145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			uint8 *ip_body = pktdata + sizeof(struct ethervlan_header);
1146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			uint8 tos_tc = IP_TOS46(ip_body);
1147b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
1148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* DSCP priority gets precedence over 802.1P (vlan tag) */
1151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (dscp_prio != 0) {
1152b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			priority = dscp_prio;
1153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			rc |= PKTPRIO_VDSCP;
1154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
1155b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			priority = vlan_prio;
1156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			rc |= PKTPRIO_VLAN;
1157b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1158b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/*
1159b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 * If the DSCP priority is not the same as the VLAN priority,
1160b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 * then overwrite the priority field in the vlan tag, with the
1161b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 * DSCP priority value. This is required for Linux APs because
1162b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 * the VLAN driver on Linux, overwrites the skb->priority field
1163b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 * with the priority value in the vlan tag
1164b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		 */
1165b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (update_vtag && (priority != vlan_prio)) {
1166b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
1167b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT;
1168b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			evh->vlan_tag = hton16(vlan_tag);
1169b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			rc |= PKTPRIO_UPD;
1170b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
117138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	} else if (eh->ether_type == hton16(ETHER_TYPE_IP)) {
1172b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint8 *ip_body = pktdata + sizeof(struct ether_header);
1173b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint8 tos_tc = IP_TOS46(ip_body);
1174b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
1175b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		rc |= PKTPRIO_DSCP;
1176b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1177b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1178b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(priority >= 0 && priority <= MAXPRIO);
1179b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	PKTSETPRIO(pkt, priority);
1180b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (rc | priority);
1181b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1182b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1183b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1184b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic char bcm_undeferrstr[32];
1185b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
1186b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1187b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Convert the error codes into related error strings  */
1188b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtconst char *
1189b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmerrorstr(int bcmerror)
1190b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1191b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* check if someone added a bcmerror code but forgot to add errorstring */
1192b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
1193b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1194b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (bcmerror > 0 || bcmerror < BCME_LAST) {
1195b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror);
1196b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return bcm_undeferrstr;
1197b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1198b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1199b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
1200b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1201b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return bcmerrorstrtable[-bcmerror];
1202b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1203b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1204b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1205b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1206b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* iovar table lookup */
1207b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtconst bcm_iovar_t*
1208b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
1209b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1210b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	const bcm_iovar_t *vi;
1211b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	const char *lookup_name;
1212b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1213b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* skip any ':' delimited option prefixes */
1214b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	lookup_name = strrchr(name, ':');
1215b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (lookup_name != NULL)
1216b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		lookup_name++;
1217b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
1218b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		lookup_name = name;
1219b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1220b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(table != NULL);
1221b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1222b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (vi = table; vi->name; vi++) {
1223b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!strcmp(vi->name, lookup_name))
1224b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return vi;
1225b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1226b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* ran to end of table */
1227b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1228b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return NULL; /* var name not found */
1229b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1230b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1231b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
1232b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
1233b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1234b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int bcmerror = 0;
1235b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1236b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* length check on io buf */
1237b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	switch (vi->type) {
1238b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_BOOL:
1239b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_INT8:
1240b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_INT16:
1241b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_INT32:
1242b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_UINT8:
1243b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_UINT16:
1244b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_UINT32:
1245b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* all integers are int32 sized args at the ioctl interface */
1246b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len < (int)sizeof(int)) {
1247b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bcmerror = BCME_BUFTOOSHORT;
1248b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1249b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
1250b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1251b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_BUFFER:
1252b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* buffer must meet minimum length requirement */
1253b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len < vi->minlen) {
1254b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bcmerror = BCME_BUFTOOSHORT;
1255b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1256b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
1257b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1258b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	case IOVT_VOID:
1259b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (!set) {
1260b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			/* Cannot return nil... */
1261b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bcmerror = BCME_UNSUPPORTED;
1262b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (len) {
1263b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			/* Set is an action w/o parameters */
1264b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bcmerror = BCME_BUFTOOLONG;
1265b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1266b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		break;
1267b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1268b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	default:
1269b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* unknown type for length check in iovar info */
1270b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		ASSERT(0);
1271b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bcmerror = BCME_UNSUPPORTED;
1272b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1273b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1274b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return bcmerror;
1275b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1276b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1277ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif	/* BCMDRIVER */
1278b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1279b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
128038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS)
1281b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*******************************************************************************
1282b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * crc8
1283b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1284b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Computes a crc8 over the input data using the polynomial:
1285b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1286b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *       x^8 + x^7 +x^6 + x^4 + x^2 + 1
1287b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1288b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * The caller provides the initial value (either CRC8_INIT_VALUE
1289b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * or the previous returned value) to allow for processing of
1290b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * discontiguous blocks of data.  When generating the CRC the
1291b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * caller is responsible for complementing the final return value
1292b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * and inserting it into the byte stream.  When checking, a final
1293b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * return value of CRC8_GOOD_VALUE indicates a valid CRC.
1294b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1295b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Reference: Dallas Semiconductor Application Note 27
1296b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
1297b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
1298b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
1299b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1300b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * ****************************************************************************
1301b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1302b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1303b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const uint8 crc8_table[256] = {
1304ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1305ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1306ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1307ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1308ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1309ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1310ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1311ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1312ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1313ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1314ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1315ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1316ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1317ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1318ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1319ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1320ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1321ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1322ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1323ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1324ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1325ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1326ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1327ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1328ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1329ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1330ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1331ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1332ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1333ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1334ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1335ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
1336b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
1337b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1338b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define CRC_INNER_LOOP(n, c, x) \
1339b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	(c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
1340b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1341b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint8
1342b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidthndcrc8(
1343ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 *pdata,	/* pointer to array of data to process */
1344ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint  nbytes,	/* number of input data bytes to process */
1345ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	uint8 crc	/* either CRC8_INIT_VALUE or previous return value */
1346b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt)
1347b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1348b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* hard code the crc loop instead of using CRC_INNER_LOOP macro
1349b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * to avoid the undefined and unnecessary (uint8 >> 8) operation.
1350b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
1351b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (nbytes-- > 0)
1352b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		crc = crc8_table[(crc ^ *pdata++) & 0xff];
1353b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1354b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return crc;
1355b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1356b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1357b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*******************************************************************************
1358b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * crc16
1359b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1360b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Computes a crc16 over the input data using the polynomial:
1361b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1362b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *       x^16 + x^12 +x^5 + 1
1363b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1364b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * The caller provides the initial value (either CRC16_INIT_VALUE
1365b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * or the previous returned value) to allow for processing of
1366b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * discontiguous blocks of data.  When generating the CRC the
1367b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * caller is responsible for complementing the final return value
1368b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * and inserting it into the byte stream.  When checking, a final
1369b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * return value of CRC16_GOOD_VALUE indicates a valid CRC.
1370b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1371b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Reference: Dallas Semiconductor Application Note 27
1372b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
1373b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
1374b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
1375b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt *
1376b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * ****************************************************************************
1377b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1378b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1379b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const uint16 crc16_table[256] = {
1380ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
1381ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
1382ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
1383ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
1384ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
1385ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
1386ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
1387ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
1388ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
1389ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
1390ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
1391ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
1392ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
1393ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
1394ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
1395ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
1396ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
1397ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
1398ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
1399ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
1400ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
1401ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
1402ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
1403ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
1404ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
1405ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
1406ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
1407ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
1408ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
1409ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
1410ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
1411ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
1412b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
1413b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1414b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint16
1415b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidthndcrc16(
1416ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    uint8 *pdata,  /* pointer to array of data to process */
1417ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    uint nbytes, /* number of input data bytes to process */
1418ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    uint16 crc     /* either CRC16_INIT_VALUE or previous return value */
1419b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt)
1420b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1421b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (nbytes-- > 0)
1422b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		CRC_INNER_LOOP(16, crc, *pdata++);
1423b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return crc;
1424b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1425b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1426b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const uint32 crc32_table[256] = {
1427ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
1428ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
1429ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
1430ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
1431ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
1432ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
1433ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
1434ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
1435ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
1436ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
1437ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
1438ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
1439ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
1440ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
1441ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
1442ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
1443ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
1444ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
1445ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
1446ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
1447ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
1448ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
1449ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
1450ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1451ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
1452ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
1453ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
1454ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
1455ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
1456ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1457ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
1458ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
1459ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
1460ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
1461ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
1462ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1463ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
1464ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
1465ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
1466ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
1467ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
1468ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1469ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
1470ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
1471ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
1472ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
1473ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
1474ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1475ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
1476ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
1477ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
1478ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
1479ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
1480ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1481ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
1482ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
1483ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
1484ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
1485ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
1486ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1487ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
1488ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
1489ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
1490ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
1491b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
1492b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1493b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
1494b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if
1495b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * accumulating over multiple pieces.
1496b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1497b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint32
1498b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidthndcrc32(uint8 *pdata, uint nbytes, uint32 crc)
1499b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1500b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 *pend;
1501b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	pend = pdata + nbytes;
1502b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (pdata < pend)
1503b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		CRC_INNER_LOOP(32, crc, *pdata++);
1504b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1505b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return crc;
1506b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1507b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1508b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef notdef
1509ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define CLEN 	1499 	/*  CRC Length */
1510ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define CBUFSIZ 	(CLEN+4)
1511ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define CNBUFS		5 /* # of bufs */
1512b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1513b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1514b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidttestcrc32(void)
1515b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1516b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint j, k, l;
1517b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 *buf;
1518b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len[CNBUFS];
1519b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint32 crcr;
1520b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint32 crc32tv[CNBUFS] =
1521b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		{0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
1522b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1523b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
1524b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1525b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* step through all possible alignments */
1526b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (l = 0; l <= 4; l++) {
1527b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (j = 0; j < CNBUFS; j++) {
1528b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len[j] = CLEN;
1529b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			for (k = 0; k < len[j]; k++)
1530b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				*(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
1531b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1532b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1533b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		for (j = 0; j < CNBUFS; j++) {
1534b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
1535b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			ASSERT(crcr == crc32tv[j]);
1536b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1537b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1538b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1539b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	MFREE(buf, CBUFSIZ*CNBUFS);
1540b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return;
1541b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1542b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* notdef */
1543b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1544b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
1545b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Advance from the current 1-byte tag/1-byte length/variable-length value
1546b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * triple, to the next, returning a pointer to the next.
1547b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * If the current or next TLV is invalid (does not fit in given buffer length),
1548b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * NULL is returned.
1549b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
1550b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * by the TLV parameter's length if it is valid.
1551b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1552b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_tlv_t *
1553b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_next_tlv(bcm_tlv_t *elt, int *buflen)
1554b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1555b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
1556b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1557b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate current elt */
1558b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!bcm_valid_tlv(elt, *buflen))
1559b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
1560b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1561b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* advance to next elt */
1562b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = elt->len;
1563b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	elt = (bcm_tlv_t*)(elt->data + len);
1564ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	*buflen -= (TLV_HDR_LEN + len);
1565b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1566b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* validate next elt */
1567b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (!bcm_valid_tlv(elt, *buflen))
1568b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return NULL;
1569b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1570b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return elt;
1571b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1572b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1573b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
1574b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Traverse a string of 1-byte tag/1-byte length/variable-length value
1575b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * triples, returning a pointer to the substring whose first element
1576b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * matches tag
1577b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1578b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_tlv_t *
1579b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_parse_tlvs(void *buf, int buflen, uint key)
1580b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1581b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bcm_tlv_t *elt;
1582b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int totlen;
1583b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1584b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	elt = (bcm_tlv_t*)buf;
1585b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	totlen = buflen;
1586b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1587b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* find tagged parameter */
1588ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while (totlen >= TLV_HDR_LEN) {
1589b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		int len = elt->len;
1590b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1591b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* validate remaining totlen */
1592ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((elt->id == key) &&
1593ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		    (totlen >= (len + TLV_HDR_LEN)))
1594b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (elt);
1595b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1596ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
1597ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		totlen -= (len + TLV_HDR_LEN);
1598b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1599b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1600b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return NULL;
1601b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1602b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1603b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
1604b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Traverse a string of 1-byte tag/1-byte length/variable-length value
1605b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * triples, returning a pointer to the substring whose first element
1606b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * matches tag.  Stop parsing when we see an element whose ID is greater
1607b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * than the target key.
1608b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1609b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_tlv_t *
1610b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
1611b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1612b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bcm_tlv_t *elt;
1613b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int totlen;
1614b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1615b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	elt = (bcm_tlv_t*)buf;
1616b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	totlen = buflen;
1617b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1618b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* find tagged parameter */
1619ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	while (totlen >= TLV_HDR_LEN) {
1620b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		uint id = elt->id;
1621b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		int len = elt->len;
1622b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1623b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* Punt if we start seeing IDs > than target key */
1624b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (id > key)
1625b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (NULL);
1626b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1627b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* validate remaining totlen */
1628ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((id == key) &&
1629ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		    (totlen >= (len + TLV_HDR_LEN)))
1630b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (elt);
1631b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1632ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
1633ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		totlen -= (len + TLV_HDR_LEN);
1634b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1635b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return NULL;
1636b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
163738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif	/* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */
1638b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1639b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \
1640b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	defined(DHD_DEBUG)
1641b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
164238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 flags, char* buf, int len)
164338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
164438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int i, slen = 0;
164538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 bit, mask;
164638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	const char *name;
164738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	mask = bd->mask;
164838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (len < 2 || !buf)
164938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return 0;
165038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
165138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	buf[0] = '\0';
165238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
165338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	for (i = 0;  (name = bd->bitfield[i].name) != NULL; i++) {
165438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		bit = bd->bitfield[i].bit;
165538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if ((flags & mask) == bit) {
165638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			if (len > (int)strlen(name)) {
165738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				slen = strlen(name);
165838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				strncpy(buf, name, slen+1);
165938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			}
166038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			break;
166138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
166238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
166338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return slen;
166438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
166538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
166638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtint
1667b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len)
1668b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1669b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
1670b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char* p = buf;
1671b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char hexstr[16];
1672b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int slen = 0, nlen = 0;
1673b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint32 bit;
1674b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	const char* name;
1675b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1676b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (len < 2 || !buf)
1677b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
1678b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1679b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	buf[0] = '\0';
1680b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1681b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; flags != 0; i++) {
1682b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bit = bd[i].bit;
1683b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		name = bd[i].name;
1684b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (bit == 0 && flags != 0) {
1685b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			/* print any unnamed bits */
1686b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			snprintf(hexstr, 16, "0x%X", flags);
1687b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			name = hexstr;
1688ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			flags = 0;	/* exit loop */
1689b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if ((flags & bit) == 0)
1690b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
1691b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		flags &= ~bit;
1692b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		nlen = strlen(name);
1693b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		slen += nlen;
1694b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* count btwn flag space */
1695b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (flags != 0)
1696b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			slen += 1;
1697b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* need NULL char as well */
1698b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len <= slen)
1699b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1700b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* copy NULL char but don't count it */
1701b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		strncpy(p, name, nlen + 1);
1702b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p += nlen;
1703b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* copy btwn flag space and NULL char */
1704b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (flags != 0)
1705b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += snprintf(p, 2, " ");
1706b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1707b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1708b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* indicate the str was too short */
1709b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (flags != 0) {
1710b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len < 2)
1711ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			p -= 2 - len;	/* overwrite last char */
1712b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p += snprintf(p, 2, ">");
1713b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1714b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1715b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (int)(p - buf);
1716b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1717b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1718b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* print bytes formatted as hex to a string. return the resulting string length */
1719b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
1720b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_format_hex(char *str, const void *bytes, int len)
1721b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1722b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
1723b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p = str;
1724b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	const uint8 *src = (const uint8*)bytes;
1725b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1726b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < len; i++) {
1727b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		p += snprintf(p, 3, "%02X", *src);
1728b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		src++;
1729b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1730b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (int)(p - str);
1731b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1732ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif
1733b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1734b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* pretty hex print a contiguous buffer */
1735b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1736b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtprhex(const char *msg, uchar *buf, uint nbytes)
1737b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1738b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char line[128], *p;
1739b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len = sizeof(line);
1740b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int nchar;
1741b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint i;
1742b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1743b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (msg && (msg[0] != '\0'))
1744b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s:\n", msg);
1745b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1746b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	p = line;
1747b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < nbytes; i++) {
1748b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (i % 16 == 0) {
1749ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			nchar = snprintf(p, len, "  %04d: ", i);	/* line prefix */
1750b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += nchar;
1751b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len -= nchar;
1752b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1753b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len > 0) {
1754b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			nchar = snprintf(p, len, "%02x ", buf[i]);
1755b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += nchar;
1756b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len -= nchar;
1757b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1758b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1759b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (i % 16 == 15) {
1760ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			printf("%s\n", line);		/* flush line */
1761b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p = line;
1762b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len = sizeof(line);
1763b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1764b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1765b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1766b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* flush last partial line */
1767b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (p != line)
1768b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s\n", line);
1769b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1770b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1771b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const char *crypto_algo_names[] = {
1772b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"NONE",
1773b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"WEP1",
1774b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"TKIP",
1775b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"WEP128",
1776b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"AES_CCM",
1777b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"AES_OCB_MSDU",
1778b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"AES_OCB_MPDU",
1779b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"NALG"
1780b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"UNDEF",
1781b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"UNDEF",
1782b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"UNDEF",
1783b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	"UNDEF"
1784b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
1785b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1786b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtconst char *
1787b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_crypto_algo_name(uint algo)
1788b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1789b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR";
1790b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1791b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1792b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1793b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *
1794b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_chipname(uint chipid, char *buf, uint len)
1795b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1796b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	const char *fmt;
1797b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1798b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
1799b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	snprintf(buf, len, fmt, chipid);
1800b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return buf;
1801b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1802b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1803b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Produce a human-readable string for boardrev */
1804b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtchar *
1805b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_brev_str(uint32 brev, char *buf)
1806b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1807b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (brev < 0x100)
1808b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
1809b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	else
1810b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff);
1811b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1812b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (buf);
1813b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1814b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1815b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */
1816b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1817b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* dump large strings to console */
1818b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1819b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtprintbig(char *buf)
1820b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1821b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len, max_len;
1822b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char c;
1823b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1824b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(buf);
1825b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1826b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	max_len = BUFSIZE_TODUMP_ATONCE;
1827b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1828b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (len > max_len) {
1829b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		c = buf[max_len];
1830b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf[max_len] = '\0';
1831b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%s", buf);
1832b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf[max_len] = c;
1833b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1834b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf += max_len;
1835b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len -= max_len;
1836b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1837b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* print the remaining string */
1838b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("%s\n", buf);
1839b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return;
1840b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1841b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1842b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* routine to dump fields in a fileddesc structure */
1843b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint
1844b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array,
1845b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *buf, uint32 bufsize)
1846b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1847b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint  filled_len;
1848b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int len;
1849b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	struct fielddesc *cur_ptr;
1850b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1851b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	filled_len = 0;
1852b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	cur_ptr = fielddesc_array;
1853b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1854b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (bufsize > 1) {
1855b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (cur_ptr->nameandfmt == NULL)
1856b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
1857b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		len = snprintf(buf, bufsize, cur_ptr->nameandfmt,
1858ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		               read_rtn(arg0, arg1, cur_ptr->offset));
1859b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* check for snprintf overflow or error */
1860b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (len < 0 || (uint32)len >= bufsize)
1861b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			len = bufsize - 1;
1862b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		buf += len;
1863b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		bufsize -= len;
1864b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		filled_len += len;
1865b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		cur_ptr++;
1866b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1867b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return filled_len;
1868b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1869b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1870b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint
1871b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
1872b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1873b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint len;
1874b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1875b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len = strlen(name) + 1;
1876b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1877b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if ((len + datalen) > buflen)
1878b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
1879b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1880b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	strncpy(buf, name, buflen);
1881b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1882b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* append data onto the end of the name string */
1883b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	memcpy(&buf[len], data, datalen);
1884b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	len += datalen;
1885b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1886b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return len;
1887b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1888b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1889b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Quarter dBm units to mW
1890b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
1891b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Table is offset so the last entry is largest mW value that fits in
1892b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * a uint16.
1893b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1894b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1895ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define QDBM_OFFSET 153		/* Offset for first entry */
1896ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define QDBM_TABLE_LEN 40	/* Table size */
1897b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1898b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
1899b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
1900b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1901b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
1902b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1903b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Largest mW value that will round down to the last table entry,
1904b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * QDBM_OFFSET + QDBM_TABLE_LEN-1.
1905b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
1906b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt */
1907b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
1908b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1909b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtstatic const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
1910ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* qdBm: 	+0 	+1 	+2 	+3 	+4 	+5 	+6 	+7 */
1911ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* 153: */      6683,	7079,	7499,	7943,	8414,	8913,	9441,	10000,
1912ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* 161: */      10593,	11220,	11885,	12589,	13335,	14125,	14962,	15849,
1913ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* 169: */      16788,	17783,	18836,	19953,	21135,	22387,	23714,	25119,
1914ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* 177: */      26607,	28184,	29854,	31623,	33497,	35481,	37584,	39811,
1915ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* 185: */      42170,	44668,	47315,	50119,	53088,	56234,	59566,	63096
1916b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt};
1917b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1918b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint16
1919b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_qdbm_to_mw(uint8 qdbm)
1920b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1921b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint factor = 1;
1922b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int idx = qdbm - QDBM_OFFSET;
1923b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1924b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (idx >= QDBM_TABLE_LEN) {
1925b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		/* clamp to max uint16 mW value */
1926b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0xFFFF;
1927b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1928b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1929b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* scale the qdBm index up to the range of the table 0-40
1930b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * where an offset of 40 qdBm equals a factor of 10 mW.
1931b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
1932b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (idx < 0) {
1933b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		idx += 40;
1934b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		factor *= 10;
1935b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1936b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1937b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* return the mW value scaled down to the correct factor of 10,
1938b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * adding in factor/2 to get proper rounding.
1939b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
1940b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return ((nqdBm_to_mW_map[idx] + factor/2) / factor);
1941b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1942b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1943b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint8
1944b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_mw_to_qdbm(uint16 mw)
1945b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1946b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 qdbm;
1947b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int offset;
1948b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint mw_uint = mw;
1949b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint boundary;
1950b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1951b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* handle boundary case */
1952b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (mw_uint <= 1)
1953b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		return 0;
1954b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1955b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	offset = QDBM_OFFSET;
1956b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1957b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* move mw into the range of the table */
1958b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
1959b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		mw_uint *= 10;
1960b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		offset -= 40;
1961b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1962b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1963b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) {
1964b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] -
1965ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		                                    nqdBm_to_mW_map[qdbm])/2;
1966ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (mw_uint < boundary) break;
1967b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1968b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1969b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	qdbm += (uint8)offset;
1970b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1971b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (qdbm);
1972b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1973b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1974b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1975b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtuint
1976b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_bitcount(uint8 *bitmap, uint length)
1977b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1978b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint bitcount = 0, i;
1979b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint8 tmp;
1980b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < length; i++) {
1981b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		tmp = bitmap[i];
1982b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		while (tmp) {
1983b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			bitcount++;
1984b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			tmp &= (tmp - 1);
1985b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
1986b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
1987b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return bitcount;
1988b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1989b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1990b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#ifdef BCMDRIVER
1991b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
1992b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Initialization of bcmstrbuf structure */
1993b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
1994b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_binit(struct bcmstrbuf *b, char *buf, uint size)
1995b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
1996b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	b->origsize = b->size = size;
1997b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	b->origbuf = b->buf = buf;
1998b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
1999b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2000b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/* Buffer sprintf wrapper to guard against buffer overflow */
2001b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
2002b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
2003b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2004b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	va_list ap;
2005b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int r;
2006b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2007b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	va_start(ap, fmt);
2008ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
2009b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	r = vsnprintf(b->buf, b->size, fmt, ap);
2010b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2011b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	/* Non Ansi C99 compliant returns -1,
2012b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * Ansi compliant return r >= b->size,
2013b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 * bcmstdlib returns 0, handle all
2014b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	 */
2015ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* r == 0 is also the case when strlen(fmt) is zero.
2016ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 * typically the case when "" is passed as argument.
2017ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 */
2018ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((r == -1) || (r >= (int)b->size)) {
2019b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		b->size = 0;
2020b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	} else {
2021b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		b->size -= r;
2022b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		b->buf += r;
2023b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2024b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2025b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	va_end(ap);
2026b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2027b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return r;
2028b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2029b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2030b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
2031ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len)
2032ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
2033ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int i;
2034ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
2035ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (msg != NULL && msg[0] != '\0')
2036ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		bcm_bprintf(b, "%s", msg);
2037ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	for (i = 0; i < len; i ++)
2038ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		bcm_bprintf(b, "%02X", buf[i]);
2039ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (newline)
2040ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		bcm_bprintf(b, "\n");
2041ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
2042ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
2043ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtvoid
2044b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_inc_bytes(uchar *num, int num_bytes, uint8 amount)
2045b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2046b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
2047b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2048b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < num_bytes; i++) {
2049b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		num[i] += amount;
2050b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (num[i] >= amount)
2051b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			break;
2052b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		amount = 1;
2053b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2054b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2055b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2056b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
2057ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes)
2058b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2059b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
2060b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2061b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = nbytes - 1; i >= 0; i--) {
2062b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (arg1[i] != arg2[i])
2063b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			return (arg1[i] - arg2[i]);
2064b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2065b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return 0;
2066b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2067b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2068b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtvoid
2069ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtbcm_print_bytes(const char *name, const uchar *data, int len)
2070b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2071b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int i;
2072b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int per_line = 0;
2073b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2074b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("%s: %d \n", name ? name : "", len);
2075b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < len; i++) {
2076b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		printf("%02x ", *data++);
2077b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		per_line++;
2078b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (per_line == 16) {
2079b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			per_line = 0;
2080b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			printf("\n");
2081b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2082b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2083b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	printf("\n");
2084b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
208538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
208638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* Look for vendor-specific IE with specified OUI and optional type */
208738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbcm_tlv_t *
208838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtfind_vendor_ie(void *tlvs, int tlvs_len, const char *voui, uint8 *type, int type_len)
208938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
209038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	bcm_tlv_t *ie;
209138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint8 ie_len;
209238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
209338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ie = (bcm_tlv_t*)tlvs;
209438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
209538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* make sure we are looking at a valid IE */
209638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ie == NULL ||
209738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	    !bcm_valid_tlv(ie, tlvs_len))
209838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return NULL;
209938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
210038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* Walk through the IEs looking for an OUI match */
210138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	do {
210238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ie_len = ie->len;
210338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if ((ie->id == DOT11_MNG_PROPR_ID) &&
210438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		    (ie_len >= (DOT11_OUI_LEN + type_len)) &&
210538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		    !bcmp(ie->data, voui, DOT11_OUI_LEN))
210638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		{
210738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			/* compare optional type */
210838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			if (type_len == 0 ||
210938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			    !bcmp(&ie->data[DOT11_OUI_LEN], type, type_len)) {
211038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				return (ie);		/* a match */
211138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			}
211238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		}
211338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	} while ((ie = bcm_next_tlv(ie, &tlvs_len)) != NULL);
211438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
211538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return NULL;
211638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
211738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
2118b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \
2119b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
2120ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define SSID_FMT_BUF_LEN	((4 * DOT11_MAX_SSID_LEN) + 1)
2121b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2122b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtint
2123b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtbcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len)
2124b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2125b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	uint i, c;
2126b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *p = buf;
2127b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *endp = buf + SSID_FMT_BUF_LEN;
2128b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2129b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN;
2130b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2131b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (i = 0; i < ssid_len; i++) {
2132b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		c = (uint)ssid[i];
2133b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (c == '\\') {
2134b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*p++ = '\\';
2135b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*p++ = '\\';
2136b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else if (bcm_isprint((uchar)c)) {
2137b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*p++ = (char)c;
2138b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		} else {
2139b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			p += snprintf(p, (endp - p), "\\x%02X", c);
2140b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2141b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2142b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	*p = '\0';
2143b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	ASSERT(p < endp);
2144b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2145b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return (int)(p - buf);
2146b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
2147ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif
2148b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2149b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt#endif /* BCMDRIVER */
2150b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2151b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt/*
2152b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file and ending in a NUL.
2153b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * also accepts nvram files which are already in the format of <var1>=<value>\0\<var2>=<value2>\0
2154b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs.
2155b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt * Shortens buffer as needed and pads with NULs.  End of buffer is marked by two NULs.
2156b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt*/
2157b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2158b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtunsigned int
2159b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidtprocess_nvram_vars(char *varbuf, unsigned int len)
2160b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt{
2161b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	char *dp;
2162b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	bool findNewline;
2163b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	int column;
2164b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	unsigned int buf_len, n;
2165b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	unsigned int pad = 0;
2166b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2167b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	dp = varbuf;
2168b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2169b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	findNewline = FALSE;
2170b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	column = 0;
2171b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2172b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	for (n = 0; n < len; n++) {
2173b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (varbuf[n] == '\r')
2174b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
2175b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (findNewline && varbuf[n] != '\n')
2176b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
2177b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		findNewline = FALSE;
2178b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (varbuf[n] == '#') {
2179b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			findNewline = TRUE;
2180b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
2181b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2182b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (varbuf[n] == '\n') {
2183b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			if (column == 0)
2184b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt				continue;
2185b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			*dp++ = 0;
2186b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			column = 0;
2187b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			continue;
2188b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2189b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*dp++ = varbuf[n];
2190b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		column++;
2191b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2192b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	buf_len = (unsigned int)(dp - varbuf);
2193b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	if (buf_len % 4) {
2194b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		pad = 4 - buf_len % 4;
2195b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		if (pad && (buf_len + pad <= len)) {
2196b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt			buf_len += pad;
2197b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		}
2198b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	}
2199b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2200b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	while (dp < varbuf + n)
2201b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt		*dp++ = 0;
2202b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt
2203b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt	return buf_len;
2204b6825ab724b9d671db9f26faae035f2d5ade04b6Dmitry Shmidt}
220538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
220638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* calculate a * b + c */
220738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid
220838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbcm_uint64_multiple_add(uint32* r_high, uint32* r_low, uint32 a, uint32 b, uint32 c)
220938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
221038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#define FORMALIZE(var) {cc += (var & 0x80000000) ? 1 : 0; var &= 0x7fffffff;}
221138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 r1, r0;
221238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 a1, a0, b1, b0, t, cc = 0;
221338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
221438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	a1 = a >> 16;
221538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	a0 = a & 0xffff;
221638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	b1 = b >> 16;
221738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	b0 = b & 0xffff;
221838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
221938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 = a0 * b0;
222038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(r0);
222138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
222238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	t = (a1 * b0) << 16;
222338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(t);
222438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
222538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 += t;
222638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(r0);
222738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
222838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	t = (a0 * b1) << 16;
222938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(t);
223038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
223138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 += t;
223238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(r0);
223338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
223438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(c);
223538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
223638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 += c;
223738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	FORMALIZE(r0);
223838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
223938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 |= (cc % 2) ? 0x80000000 : 0;
224038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r1 = a1 * b1 + ((a1 * b0) >> 16) + ((b1 * a0) >> 16) + (cc / 2);
224138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
224238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	*r_high = r1;
224338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	*r_low = r0;
224438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
224538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
224638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* calculate a / b */
224738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid
224838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbcm_uint64_divide(uint32* r, uint32 a_high, uint32 a_low, uint32 b)
224938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
225038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	uint32 a1 = a_high, a0 = a_low, r0 = 0;
225138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
225238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (b < 2)
225338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return;
225438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
225538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	while (a1 != 0) {
225638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		r0 += (0xffffffff / b) * a1;
225738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		bcm_uint64_multiple_add(&a1, &a0, ((0xffffffff % b) + 1) % b, a1, a0);
225838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
225938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
226038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	r0 += a0 / b;
226138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	*r = r0;
226238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
226338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
226438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#ifndef setbit     /* As in the header file */
226538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#ifdef BCMUTILS_BIT_MACROS_USE_FUNCS
226638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* Set bit in byte array. */
226738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid
226838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtsetbit(void *array, uint bit)
226938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
227038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	((uint8 *)array)[bit / NBBY] |= 1 << (bit % NBBY);
227138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
227238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
227338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* Clear bit in byte array. */
227438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtvoid
227538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtclrbit(void *array, uint bit)
227638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
227738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	((uint8 *)array)[bit / NBBY] &= ~(1 << (bit % NBBY));
227838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
227938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* Test if bit is set in byte array. */
228138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbool
228238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtisset(const void *array, uint bit)
228338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
228438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return (((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY)));
228538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
228638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
228738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt/* Test if bit is clear in byte array. */
228838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtbool
228938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtisclr(const void *array, uint bit)
229038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
229138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ((((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY))) == 0);
229238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
229338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* BCMUTILS_BIT_MACROS_USE_FUNCS */
229438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* setbit */
2295