18ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
28ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Driver O/S-independent utility routines
38ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
4832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt * Copyright (C) 1999-2012, Broadcom Corporation
58ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
6832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt *      Unless you and Broadcom execute a separate written software license
78ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * agreement governing use of this software, this software is licensed to you
88ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * under the terms of the GNU General Public License version 2 (the "GPL"),
98ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * available at http://www.broadcom.com/licenses/GPLv2.php, with the
108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * following added to such license:
118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *      As a special exception, the copyright holders of this software give you
138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * permission to link this software with independent modules, and to copy and
148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * distribute the resulting executable under terms of your choice, provided that
158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * you also meet, for each linked independent module, the terms and conditions of
168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * the license of that module.  An independent module is a module which is not
178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * derived from this software.  The special exception does not apply to any
188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * modifications of the software.
198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *      Notwithstanding the above, under no circumstances may you combine this
218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * software in any way with any other Broadcom software provided under a license
228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * other than the GPL, without Broadcom's express prior written consent.
234a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt * $Id: bcmutils.c 312855 2012-02-04 02:01:18Z $
248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
26832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#include <bcm_cfg.h>
278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <typedefs.h>
288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmdefs.h>
298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <stdarg.h>
308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMDRIVER
318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <osl.h>
338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmutils.h>
348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else /* !BCMDRIVER */
368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <stdio.h>
388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <string.h>
398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmutils.h>
408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(BCMEXTSUP)
428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcm_osl.h>
438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif
448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* !BCMDRIVER */
478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmendian.h>
498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmdevs.h>
508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <proto/ethernet.h>
518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <proto/vlan.h>
528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <proto/bcmip.h>
538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <proto/802.1d.h>
548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <proto/802.11.h>
558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid *_bcmutils_dummy_fn = NULL;
568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
57832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMDRIVER
598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* copy a pkt buffer chain into a buffer */
638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint
648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint n, ret = 0;
678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (len < 0)
69832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		len = 4096;	/* "infinite" */
708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* skip 'offset' bytes */
728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; p && offset; p = PKTNEXT(osh, p)) {
738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (offset < (uint)PKTLEN(osh, p))
748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		offset -= PKTLEN(osh, p);
768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!p)
798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* copy the data */
828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; p && len; p = PKTNEXT(osh, p)) {
838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		bcopy(PKTDATA(osh, p) + offset, buf, n);
858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf += n;
868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		len -= n;
878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		ret += n;
888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		offset = 0;
898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return ret;
928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* copy a buffer into a pkt buffer chain */
958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint
968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf)
978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint n, ret = 0;
998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* skip 'offset' bytes */
1018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; p && offset; p = PKTNEXT(osh, p)) {
1028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (offset < (uint)PKTLEN(osh, p))
1038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
1048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		offset -= PKTLEN(osh, p);
1058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
1068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!p)
1088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
1098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* copy the data */
1118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; p && len; p = PKTNEXT(osh, p)) {
1128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
1138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		bcopy(buf, PKTDATA(osh, p) + offset, n);
1148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf += n;
1158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		len -= n;
1168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		ret += n;
1178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		offset = 0;
1188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
1198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return ret;
1218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
1228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* return total length of buffer chain */
1268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint BCMFASTPATH
1278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpkttotlen(osl_t *osh, void *p)
1288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
1298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint total;
130832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	int len;
1318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	total = 0;
133832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	for (; p; p = PKTNEXT(osh, p)) {
134832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		len = PKTLEN(osh, p);
135832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		total += len;
136832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
137832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
1388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (total);
1398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
1408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* return the last buffer of chained pkt */
1428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid *
1438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktlast(osl_t *osh, void *p)
1448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
1458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
1468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		;
1478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (p);
1498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
1508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* count segments of a chained packet */
1528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint BCMFASTPATH
1538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktsegcnt(osl_t *osh, void *p)
1548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
1558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint cnt;
1568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (cnt = 0; p; p = PKTNEXT(osh, p))
1588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cnt++;
1598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return cnt;
1618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
1628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
164832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* count segments of a chained packet */
165832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtuint BCMFASTPATH
166832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtpktsegcnt_war(osl_t *osh, void *p)
167832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
168832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint cnt;
169832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint8 *pktdata;
170832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint len, remain, align64;
171832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
172832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	for (cnt = 0; p; p = PKTNEXT(osh, p)) {
173832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		cnt++;
174832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		len = PKTLEN(osh, p);
175832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if (len > 128) {
176832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			pktdata = (uint8 *)PKTDATA(osh, p);	/* starting address of data */
1774a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt			/* Check for page boundary straddle (2048B) */
1784a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt			if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff))
1794a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt				cnt++;
1804a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt
181832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			align64 = (uint)((uintptr)pktdata & 0x3f);	/* aligned to 64B */
182832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			align64 = (64 - align64) & 0x3f;
183832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			len -= align64;		/* bytes from aligned 64B to end */
184832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			/* if aligned to 128B, check for MOD 128 between 1 to 4B */
185832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			remain = len % 128;
186832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			if (remain > 0 && remain <= 4)
187832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt				cnt++;		/* add extra seg */
188832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		}
189832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
190832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
191832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	return cnt;
192832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
193832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
194832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtuint8 * BCMFASTPATH
195832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtpktoffset(osl_t *osh, void *p,  uint offset)
196832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
197832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint total = pkttotlen(osh, p);
198832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint pkt_off = 0, len = 0;
199832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint8 *pdata = (uint8 *) PKTDATA(osh, p);
200832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
201832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (offset > total)
202832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return NULL;
203832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
204832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	for (; p; p = PKTNEXT(osh, p)) {
205832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		pdata = (uint8 *) PKTDATA(osh, p);
206832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		pkt_off = offset - len;
207832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		len += PKTLEN(osh, p);
208832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if (len > offset)
209832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			break;
210832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
211832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	return (uint8*) (pdata+pkt_off);
212832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
213832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
2148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
2158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * osl multiple-precedence packet queue
2168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * hi_prec is always >= the number of the highest non-empty precedence
2178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
2188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
2198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_penq(struct pktq *pq, int prec, void *p)
2208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
2218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
2228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
2248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */
2258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(!pktq_full(pq));
2278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(!pktq_pfull(pq, prec));
2288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
2308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (q->head)
2328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		PKTSETLINK(q->tail, p);
2338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else
2348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->head = p;
2358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->tail = p;
2378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len++;
2388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len++;
2408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->hi_prec < prec)
2428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->hi_prec = (uint8)prec;
2438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
2458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
2468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
2488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_penq_head(struct pktq *pq, int prec, void *p)
2498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
2508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
2518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
2538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(PKTLINK(p) == NULL);         /* queueing chains not allowed */
2548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(!pktq_full(pq));
2568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(!pktq_pfull(pq, prec));
2578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
2598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (q->head == NULL)
2618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->tail = p;
2628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(p, q->head);
2648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->head = p;
2658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len++;
2668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len++;
2688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->hi_prec < prec)
2708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->hi_prec = (uint8)prec;
2718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
2738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
2748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
2768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_pdeq(struct pktq *pq, int prec)
2778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
2788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
2798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p;
2808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
2828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
2848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((p = q->head) == NULL)
2868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
2878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
2898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->tail = NULL;
2908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
2928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
2948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(p, NULL);
2968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
2978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
2988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
2998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
301832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtpktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p)
302832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
303832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	struct pktq_prec *q;
304832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	void *p;
305832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
306832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
307832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
308832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	q = &pq->q[prec];
309832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
310832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (prev_p == NULL)
311832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return NULL;
312832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
313832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if ((p = PKTLINK(prev_p)) == NULL)
314832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return NULL;
315832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
316832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	q->len--;
317832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
318832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	pq->len--;
319832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
320832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	PKTSETLINK(prev_p, PKTLINK(p));
321832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	PKTSETLINK(p, NULL);
322832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
323832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	return p;
324832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
325832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
326832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtvoid * BCMFASTPATH
3278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_pdeq_tail(struct pktq *pq, int prec)
3288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
3298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
3308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p, *prev;
3318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
3338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
3358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((p = q->head) == NULL)
3378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
3388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prev = NULL; p != q->tail; p = PKTLINK(p))
3408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		prev = p;
3418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prev)
3438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		PKTSETLINK(prev, NULL);
3448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else
3458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->head = NULL;
3468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->tail = prev;
3488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
3498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
3518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
3538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
3548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
3568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg)
3578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
3588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
3598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p, *prev = NULL;
3608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
3628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	p = q->head;
3638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (p) {
3648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (fn == NULL || (*fn)(p, arg)) {
3658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bool head = (p == q->head);
3668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			if (head)
3678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				q->head = PKTLINK(p);
3688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			else
3698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				PKTSETLINK(prev, PKTLINK(p));
3708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			PKTSETLINK(p, NULL);
3718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			PKTFREE(osh, p, dir);
3728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			q->len--;
3738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			pq->len--;
3748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p = (head ? q->head : PKTLINK(prev));
3758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else {
3768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			prev = p;
3778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p = PKTLINK(p);
3788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
3798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
3808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (q->head == NULL) {
3828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		ASSERT(q->len == 0);
3838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->tail = NULL;
3848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
3858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
3868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbool BCMFASTPATH
3888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_pdel(struct pktq *pq, void *pktbuf, int prec)
3898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
3908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
3918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p;
3928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
3948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!pktbuf)
3968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return FALSE;
3978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
3988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
3998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (q->head == pktbuf) {
4018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if ((q->head = PKTLINK(pktbuf)) == NULL)
4028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			q->tail = NULL;
4038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	} else {
4048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p))
4058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			;
4068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (p == NULL)
4078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return FALSE;
4088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		PKTSETLINK(p, PKTLINK(pktbuf));
4108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (q->tail == pktbuf)
4118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			q->tail = p;
4128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
4138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
4158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
4168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(pktbuf, NULL);
4178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return TRUE;
4188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
4198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
4218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_init(struct pktq *pq, int num_prec, int max_len)
4228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
4238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
4248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
4268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* pq is variable size; only zero out what's requested */
4288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
4298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->num_prec = (uint16)num_prec;
4318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->max = (uint16)max_len;
4338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prec = 0; prec < num_prec; prec++)
4358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->q[prec].max = pq->max;
4368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
4378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
438832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtvoid
439832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtpktq_set_max_plen(struct pktq *pq, int prec, int max_len)
440832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
441832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	ASSERT(prec >= 0 && prec < pq->num_prec);
442832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
443832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (prec < pq->num_prec)
444832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		pq->q[prec].max = (uint16)max_len;
445832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
446832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
4478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
4488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_deq(struct pktq *pq, int *prec_out)
4498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
4508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
4518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p;
4528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
4538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->len == 0)
4558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
4568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
4588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->hi_prec--;
4598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
4618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((p = q->head) == NULL)
4638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
4648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
4668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->tail = NULL;
4678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
4698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
4718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prec_out)
4738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*prec_out = prec;
4748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(p, NULL);
4768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
4788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
4798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
4818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_deq_tail(struct pktq *pq, int *prec_out)
4828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
4838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
4848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p, *prev;
4858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
4868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->len == 0)
4888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
4898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prec = 0; prec < pq->hi_prec; prec++)
4918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (pq->q[prec].head)
4928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
4938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
4958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((p = q->head) == NULL)
4978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
4988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
4998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prev = NULL; p != q->tail; p = PKTLINK(p))
5008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		prev = p;
5018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prev)
5038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		PKTSETLINK(prev, NULL);
5048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else
5058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->head = NULL;
5068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->tail = prev;
5088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
5098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
5118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prec_out)
5138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*prec_out = prec;
5148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(p, NULL);
5168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
5188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
5198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid *
5218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_peek(struct pktq *pq, int *prec_out)
5228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
5238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
5248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->len == 0)
5268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
5278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
5298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->hi_prec--;
5308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prec_out)
5328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*prec_out = prec;
5338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (pq->q[prec].head);
5358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
5368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid *
5388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_peek_tail(struct pktq *pq, int *prec_out)
5398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
5408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
5418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->len == 0)
5438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
5448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prec = 0; prec < pq->hi_prec; prec++)
5468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (pq->q[prec].head)
5478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
5488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prec_out)
5508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*prec_out = prec;
5518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (pq->q[prec].tail);
5538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
5548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
5568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg)
5578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
5588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
559832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
560832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	/* Optimize flush, if pktq len = 0, just return.
561832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	 * pktq len of 0 means pktq's prec q's are all empty.
562832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	 */
563832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (pq->len == 0) {
564832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return;
565832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
566832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
5678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prec = 0; prec < pq->num_prec; prec++)
5688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pktq_pflush(osh, pq, prec, dir, fn, arg);
5698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (fn == NULL)
5708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		ASSERT(pq->len == 0);
5718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
5728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Return sum of lengths of a specific set of precedences */
5748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
5758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_mlen(struct pktq *pq, uint prec_bmp)
5768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
5778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec, len;
5788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len = 0;
5808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (prec = 0; prec <= pq->hi_prec; prec++)
5828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (prec_bmp & (1 << prec))
5838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len += pq->q[prec].len;
5848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
5858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return len;
5868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
5878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
588832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* Priority peek from a specific set of precedences */
589832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtvoid * BCMFASTPATH
590832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtpktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out)
591832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
592832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	struct pktq_prec *q;
593832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	void *p;
594832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	int prec;
595832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
596832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (pq->len == 0)
597832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	{
598832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return NULL;
599832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
600832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
601832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		pq->hi_prec--;
602832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
603832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
604832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if (prec-- == 0)
605832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			return NULL;
606832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
607832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	q = &pq->q[prec];
608832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
609832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if ((p = q->head) == NULL)
610832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return NULL;
611832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
612832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (prec_out)
613832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		*prec_out = prec;
614832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
615832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	return p;
616832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
6178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Priority dequeue from a specific set of precedences */
6188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid * BCMFASTPATH
6198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
6208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
6218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct pktq_prec *q;
6228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p;
6238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int prec;
6248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (pq->len == 0)
6268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
6278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
6298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pq->hi_prec--;
6308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6314a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt	while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0))
6328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (prec-- == 0)
6338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return NULL;
6348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q = &pq->q[prec];
6368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((p = q->head) == NULL)
6388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
6398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((q->head = PKTLINK(p)) == NULL)
6418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		q->tail = NULL;
6428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	q->len--;
6448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (prec_out)
6468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*prec_out = prec;
6478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pq->len--;
6498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETLINK(p, NULL);
6518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return p;
6538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
6548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMDRIVER */
6568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtconst unsigned char bcm_ctype[] = {
6588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
659832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 0-7 */
6608ce1727333a1c411bb88330d69f82386a118c6bfDmitry 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,
661832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_C,	/* 8-15 */
662832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 16-23 */
663832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 24-31 */
664832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,		/* 32-39 */
665832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 40-47 */
666832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,			/* 48-55 */
667832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 56-63 */
6688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
6698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_U|_BCM_X, _BCM_U, /* 64-71 */
670832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 72-79 */
671832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 80-87 */
672832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 88-95 */
6738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
6748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L|_BCM_X, _BCM_L, /* 96-103 */
6758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
6768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
6778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
678832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 128-143 */
679832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 144-159 */
6808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
681832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 160-175 */
6828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
683832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 176-191 */
6848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
685832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,	/* 192-207 */
6868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
687832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L,	/* 208-223 */
6888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
689832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,	/* 224-239 */
6908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
6918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
6928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
6938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
6948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtulong
695832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_strtoul(const char *cp, char **endp, uint base)
6968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
6978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ulong result, last_result = 0, value;
6988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	bool minus;
6998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	minus = FALSE;
7018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (bcm_isspace(*cp))
7038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cp++;
7048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (cp[0] == '+')
7068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cp++;
7078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else if (cp[0] == '-') {
7088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		minus = TRUE;
7098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cp++;
7108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
7118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (base == 0) {
7138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (cp[0] == '0') {
7148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			if ((cp[1] == 'x') || (cp[1] == 'X')) {
7158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				base = 16;
7168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				cp = &cp[2];
7178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			} else {
7188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				base = 8;
7198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				cp = &cp[1];
7208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			}
7218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else
7228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			base = 10;
7238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	} else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
7248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cp = &cp[2];
7258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
7268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	result = 0;
7288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (bcm_isxdigit(*cp) &&
730832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	       (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
7318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		result = result*base + value;
7328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* Detected overflow */
7338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (result < last_result && !minus)
7348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return (ulong)-1;
7358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		last_result = result;
7368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cp++;
7378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
7388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (minus)
7408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		result = (ulong)(-(long)result);
7418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (endp)
743832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		*endp = DISCARD_QUAL(cp, char);
7448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (result);
7468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
7478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
749832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_atoi(const char *s)
7508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
7518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (int)bcm_strtoul(s, NULL, 10);
7528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
7538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* return pointer to location of substring 'needle' in 'haystack' */
755832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchar *
756832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcmstrstr(const char *haystack, const char *needle)
7578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
7588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int len, nlen;
7598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
7608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((haystack == NULL) || (needle == NULL))
762832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		return DISCARD_QUAL(haystack, char);
7638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	nlen = strlen(needle);
7658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len = strlen(haystack) - nlen + 1;
7668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < len; i++)
7688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (memcmp(needle, &haystack[i], nlen) == 0)
769832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			return DISCARD_QUAL(&haystack[i], char);
7708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (NULL);
7718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
7728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
773832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchar *
7748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmstrcat(char *dest, const char *src)
7758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
7768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *p;
7778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	p = dest + strlen(dest);
7798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while ((*p++ = *src++) != '\0')
7818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		;
7828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (dest);
7848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
7858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
786832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchar *
7878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmstrncat(char *dest, const char *src, uint size)
7888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
7898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *endp;
7908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *p;
7918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	p = dest + strlen(dest);
7938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	endp = p + size;
7948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (p != endp && (*p++ = *src++) != '\0')
7968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		;
7978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
7988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (dest);
7998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
8008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/****************************************************************************
8038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Function:   bcmstrtok
8048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Purpose:
8068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  Tokenizes a string. This function is conceptually similiar to ANSI C strtok(),
8078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  but allows strToken() to be used by different strings or callers at the same
8088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  time. Each call modifies '*string' by substituting a NULL character for the
8098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  first delimiter that is encountered, and updates 'string' to point to the char
8108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  after the delimiter. Leading delimiters are skipped.
8118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Parameters:
8138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  string      (mod) Ptr to string ptr, updated by token.
8148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  delimiters  (in)  Set of delimiter characters.
8158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*  tokdelim    (out) Character that delimits the returned token. (May
8168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*                    be set to NULL if token delimiter is not required).
8178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Returns:  Pointer to the next token found. NULL when no more tokens are found.
8198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*****************************************************************************
8208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*/
8218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar *
8228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmstrtok(char **string, const char *delimiters, char *tokdelim)
8238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
8248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	unsigned char *str;
8258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	unsigned long map[8];
8268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int count;
8278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *nextoken;
8288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (tokdelim != NULL) {
8308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* Prime the token delimiter */
8318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*tokdelim = '\0';
8328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Clear control map */
8358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (count = 0; count < 8; count++) {
8368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		map[count] = 0;
8378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Set bits in delimiter table */
8408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	do {
8418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		map[*delimiters >> 5] |= (1 << (*delimiters & 31));
8428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (*delimiters++);
8448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	str = (unsigned char*)*string;
8468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Find beginning of token (skip over leading delimiters). Note that
8488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * there is no token iff this loop sets str to point to the terminal
8498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * null (*str == '\0')
8508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
8518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) {
8528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		str++;
8538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	nextoken = (char*)str;
8568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Find the end of the token. If it is not the end of the string,
8588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * put a null there.
8598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
8608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (; *str; str++) {
8618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (map[*str >> 5] & (1 << (*str & 31))) {
8628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			if (tokdelim != NULL) {
8638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				*tokdelim = *str;
8648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			}
8658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			*str++ = '\0';
8678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
8688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
8698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	*string = (char*)str;
8728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Determine if a token has been found. */
8748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (nextoken == (char *) str) {
8758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
8768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else {
8788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return nextoken;
8798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
8808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
8818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define xToLower(C) \
8848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C)
8858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
8878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/****************************************************************************
8888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Function:   bcmstricmp
8898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Purpose:    Compare to strings case insensitively.
8918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Parameters: s1 (in) First string to compare.
8938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             s2 (in) Second string to compare.
8948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
8958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
8968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             t1 > t2, when ignoring case sensitivity.
8978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*****************************************************************************
8988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*/
8998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
9008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmstricmp(const char *s1, const char *s2)
9018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
9028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char dc, sc;
9038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (*s2 && *s1) {
9058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		dc = xToLower(*s1);
9068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		sc = xToLower(*s2);
9078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (dc < sc) return -1;
9088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (dc > sc) return 1;
9098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		s1++;
9108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		s2++;
9118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
9128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (*s1 && !*s2) return 1;
9148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!*s1 && *s2) return -1;
9158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return 0;
9168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
9178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/****************************************************************************
9208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Function:   bcmstrnicmp
9218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
9228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Purpose:    Compare to strings case insensitively, upto a max of 'cnt'
9238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             characters.
9248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
9258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Parameters: s1  (in) First string to compare.
9268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             s2  (in) Second string to compare.
9278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             cnt (in) Max characters to compare.
9288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*
9298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
9308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*             t1 > t2, when ignoring case sensitivity.
9318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*****************************************************************************
9328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*/
9338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
9348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmstrnicmp(const char* s1, const char* s2, int cnt)
9358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
9368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char dc, sc;
9378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (*s2 && *s1 && cnt) {
9398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		dc = xToLower(*s1);
9408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		sc = xToLower(*s2);
9418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (dc < sc) return -1;
9428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (dc > sc) return 1;
9438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		s1++;
9448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		s2++;
9458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cnt--;
9468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
9478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!cnt) return 0;
9498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (*s1 && !*s2) return 1;
9508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!*s1 && *s2) return -1;
9518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return 0;
9528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
9538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
9558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
956832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_ether_atoe(const char *p, struct ether_addr *ea)
9578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
9588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i = 0;
959832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	char *ep;
9608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (;;) {
962832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16);
963832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		p = ep;
9648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (!*p++ || i == 6)
9658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
9668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
9678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (i == 6);
9698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
9708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
9738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* registry routine buffer preparation utility functions:
9748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * parameter order is like strncpy, but returns count
9758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
9768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
9778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtulong
9788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen)
9798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
9808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ulong copyct = 1;
9818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ushort i;
9828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (abuflen == 0)
9848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
9858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* wbuflen is in bytes */
9878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	wbuflen /= sizeof(ushort);
9888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < wbuflen; ++i) {
9908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (--abuflen == 0)
9918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
9928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*abuf++ = (char) *wbuf++;
9938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		++copyct;
9948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
9958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	*abuf = '\0';
9968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
9978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return copyct;
9988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
9998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */
10008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar *
10028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_ether_ntoa(const struct ether_addr *ea, char *buf)
10038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
1004832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	static const char hex[] =
1005832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	  {
1006832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		  '0', '1', '2', '3', '4', '5', '6', '7',
1007832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
1008832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	  };
1009832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	const uint8 *octet = ea->octet;
1010832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	char *p = buf;
1011832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	int i;
1012832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
1013832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	for (i = 0; i < 6; i++, octet++) {
1014832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		*p++ = hex[(*octet >> 4) & 0xf];
1015832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		*p++ = hex[*octet & 0xf];
1016832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		*p++ = ':';
1017832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	}
1018832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
1019832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	*(p-1) = '\0';
1020832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
10218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (buf);
10228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
10238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar *
10258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_ip_ntoa(struct ipv4_addr *ia, char *buf)
10268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
10278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	snprintf(buf, 16, "%d.%d.%d.%d",
1028832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	         ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]);
10298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (buf);
10308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
10318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMDRIVER
10338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
10358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_mdelay(uint ms)
10368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
10378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint i;
10388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < ms; i++) {
10408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		OSL_DELAY(1000);
10418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
10428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
10438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(DHD_DEBUG)
10498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* pretty hex print a pkt buffer chain */
10508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
10518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtprpkt(const char *msg, osl_t *osh, void *p0)
10528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
10538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	void *p;
10548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (msg && (msg[0] != '\0'))
10568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		printf("%s:\n", msg);
10578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (p = p0; p; p = PKTNEXT(osh, p))
10598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p));
10608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
1061832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#endif
10628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
10648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Also updates the inplace vlan tag if requested.
10658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * For debugging, it returns an indication of what it did.
10668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
10678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint BCMFASTPATH
10688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtpktsetprio(void *pkt, bool update_vtag)
10698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
10708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct ether_header *eh;
10718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct ethervlan_header *evh;
10728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint8 *pktdata;
10738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int priority = 0;
10748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int rc = 0;
10758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1076832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	pktdata = (uint8 *)PKTDATA(NULL, pkt);
10778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
10788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	eh = (struct ether_header *) pktdata;
10808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) {
10828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		uint16 vlan_tag;
10838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		int vlan_prio, dscp_prio = 0;
10848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		evh = (struct ethervlan_header *)eh;
10868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		vlan_tag = ntoh16(evh->vlan_tag);
10888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
10898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) {
10918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			uint8 *ip_body = pktdata + sizeof(struct ethervlan_header);
10928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			uint8 tos_tc = IP_TOS46(ip_body);
10938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
10948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
10958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
10968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* DSCP priority gets precedence over 802.1P (vlan tag) */
10978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (dscp_prio != 0) {
10988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			priority = dscp_prio;
10998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			rc |= PKTPRIO_VDSCP;
11008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else {
11018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			priority = vlan_prio;
11028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			rc |= PKTPRIO_VLAN;
11038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
11048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/*
11058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 * If the DSCP priority is not the same as the VLAN priority,
11068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 * then overwrite the priority field in the vlan tag, with the
11078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 * DSCP priority value. This is required for Linux APs because
11088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 * the VLAN driver on Linux, overwrites the skb->priority field
11098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 * with the priority value in the vlan tag
11108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		 */
11118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (update_vtag && (priority != vlan_prio)) {
11128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
11138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT;
11148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			evh->vlan_tag = hton16(vlan_tag);
11158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			rc |= PKTPRIO_UPD;
11168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
11178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	} else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
11188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		uint8 *ip_body = pktdata + sizeof(struct ether_header);
11198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		uint8 tos_tc = IP_TOS46(ip_body);
11208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
11218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		rc |= PKTPRIO_DSCP;
11228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
11238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(priority >= 0 && priority <= MAXPRIO);
11258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	PKTSETPRIO(pkt, priority);
11268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (rc | priority);
11278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
11288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic char bcm_undeferrstr[32];
11318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
11328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Convert the error codes into related error strings  */
11348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtconst char *
11358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmerrorstr(int bcmerror)
11368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
11378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* check if someone added a bcmerror code but forgot to add errorstring */
11388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
11398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (bcmerror > 0 || bcmerror < BCME_LAST) {
11418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror);
11428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return bcm_undeferrstr;
11438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
11448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
11468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return bcmerrorstrtable[-bcmerror];
11488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
11498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* iovar table lookup */
11538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtconst bcm_iovar_t*
11548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
11558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
11568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	const bcm_iovar_t *vi;
11578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	const char *lookup_name;
11588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* skip any ':' delimited option prefixes */
11608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	lookup_name = strrchr(name, ':');
11618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (lookup_name != NULL)
11628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		lookup_name++;
11638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else
11648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		lookup_name = name;
11658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(table != NULL);
11678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (vi = table; vi->name; vi++) {
11698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (!strcmp(vi->name, lookup_name))
11708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return vi;
11718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
11728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* ran to end of table */
11738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return NULL; /* var name not found */
11758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
11768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
11788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
11798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
11808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int bcmerror = 0;
11818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* length check on io buf */
11838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	switch (vi->type) {
11848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_BOOL:
11858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_INT8:
11868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_INT16:
11878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_INT32:
11888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_UINT8:
11898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_UINT16:
11908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_UINT32:
11918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* all integers are int32 sized args at the ioctl interface */
11928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len < (int)sizeof(int)) {
11938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bcmerror = BCME_BUFTOOSHORT;
11948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
11958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		break;
11968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
11978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_BUFFER:
11988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* buffer must meet minimum length requirement */
11998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len < vi->minlen) {
12008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bcmerror = BCME_BUFTOOSHORT;
12018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
12028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		break;
12038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	case IOVT_VOID:
12058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (!set) {
12068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			/* Cannot return nil... */
12078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bcmerror = BCME_UNSUPPORTED;
12088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else if (len) {
12098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			/* Set is an action w/o parameters */
12108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bcmerror = BCME_BUFTOOLONG;
12118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
12128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		break;
12138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	default:
12158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* unknown type for length check in iovar info */
12168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		ASSERT(0);
12178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		bcmerror = BCME_UNSUPPORTED;
12188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
12198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return bcmerror;
12218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
12228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1223832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#endif	/* BCMDRIVER */
12248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*******************************************************************************
12278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * crc8
12288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
12298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Computes a crc8 over the input data using the polynomial:
12308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
12318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *       x^8 + x^7 +x^6 + x^4 + x^2 + 1
12328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
12338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * The caller provides the initial value (either CRC8_INIT_VALUE
12348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * or the previous returned value) to allow for processing of
12358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * discontiguous blocks of data.  When generating the CRC the
12368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * caller is responsible for complementing the final return value
12378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * and inserting it into the byte stream.  When checking, a final
12388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * return value of CRC8_GOOD_VALUE indicates a valid CRC.
12398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
12408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Reference: Dallas Semiconductor Application Note 27
12418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
12428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
12438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
12448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
12458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * ****************************************************************************
12468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
12478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const uint8 crc8_table[256] = {
1249832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1250832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1251832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1252832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1253832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1254832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1255832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1256832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1257832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1258832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1259832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1260832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1261832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1262832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1263832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1264832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1265832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1266832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1267832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1268832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1269832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1270832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1271832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1272832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1273832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1274832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1275832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1276832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1277832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1278832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1279832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1280832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
12818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
12828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define CRC_INNER_LOOP(n, c, x) \
12848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	(c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
12858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint8
12878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidthndcrc8(
1288832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint8 *pdata,	/* pointer to array of data to process */
1289832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint  nbytes,	/* number of input data bytes to process */
1290832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	uint8 crc	/* either CRC8_INIT_VALUE or previous return value */
12918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt)
12928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
12938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* hard code the crc loop instead of using CRC_INNER_LOOP macro
12948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * to avoid the undefined and unnecessary (uint8 >> 8) operation.
12958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
12968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (nbytes-- > 0)
12978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		crc = crc8_table[(crc ^ *pdata++) & 0xff];
12988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
12998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return crc;
13008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
13018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
13028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*******************************************************************************
13038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * crc16
13048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
13058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Computes a crc16 over the input data using the polynomial:
13068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
13078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *       x^16 + x^12 +x^5 + 1
13088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
13098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * The caller provides the initial value (either CRC16_INIT_VALUE
13108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * or the previous returned value) to allow for processing of
13118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * discontiguous blocks of data.  When generating the CRC the
13128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * caller is responsible for complementing the final return value
13138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * and inserting it into the byte stream.  When checking, a final
13148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * return value of CRC16_GOOD_VALUE indicates a valid CRC.
13158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
13168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Reference: Dallas Semiconductor Application Note 27
13178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
13188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
13198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
13208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt *
13218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * ****************************************************************************
13228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
13238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
13248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const uint16 crc16_table[256] = {
1325832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
1326832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
1327832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
1328832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
1329832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
1330832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
1331832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
1332832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
1333832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
1334832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
1335832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
1336832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
1337832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
1338832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
1339832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
1340832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
1341832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
1342832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
1343832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
1344832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
1345832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
1346832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
1347832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
1348832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
1349832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
1350832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
1351832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
1352832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
1353832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
1354832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
1355832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
1356832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
13578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
13588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
13598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint16
13608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidthndcrc16(
1361832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    uint8 *pdata,  /* pointer to array of data to process */
1362832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    uint nbytes, /* number of input data bytes to process */
1363832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    uint16 crc     /* either CRC16_INIT_VALUE or previous return value */
13648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt)
13658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
13668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (nbytes-- > 0)
13678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		CRC_INNER_LOOP(16, crc, *pdata++);
13688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return crc;
13698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
13708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
13718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const uint32 crc32_table[256] = {
1372832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
1373832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
1374832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
1375832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
1376832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
1377832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
1378832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
1379832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
1380832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
1381832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
1382832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
1383832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
1384832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
1385832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
1386832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
1387832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
1388832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
1389832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
1390832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
1391832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
1392832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
1393832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
1394832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
1395832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1396832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
1397832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
1398832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
1399832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
1400832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
1401832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1402832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
1403832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
1404832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
1405832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
1406832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
1407832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1408832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
1409832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
1410832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
1411832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
1412832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
1413832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1414832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
1415832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
1416832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
1417832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
1418832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
1419832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1420832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
1421832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
1422832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
1423832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
1424832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
1425832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1426832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
1427832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
1428832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
1429832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
1430832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
1431832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1432832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
1433832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
1434832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
1435832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
14368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
14378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
14398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if
14408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * accumulating over multiple pieces.
14418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
14428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint32
14438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidthndcrc32(uint8 *pdata, uint nbytes, uint32 crc)
14448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
14458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint8 *pend;
14468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	pend = pdata + nbytes;
14478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (pdata < pend)
14488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		CRC_INNER_LOOP(32, crc, *pdata++);
14498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return crc;
14518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
14528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef notdef
1454832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define CLEN 	1499 	/*  CRC Length */
1455832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define CBUFSIZ 	(CLEN+4)
1456832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define CNBUFS		5 /* # of bufs */
14578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
14598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidttestcrc32(void)
14608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
14618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint j, k, l;
14628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint8 *buf;
14638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint len[CNBUFS];
14648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint32 crcr;
14658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint32 crc32tv[CNBUFS] =
14668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		{0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
14678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
14698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* step through all possible alignments */
14718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (l = 0; l <= 4; l++) {
14728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		for (j = 0; j < CNBUFS; j++) {
14738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len[j] = CLEN;
14748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			for (k = 0; k < len[j]; k++)
14758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				*(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
14768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
14778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		for (j = 0; j < CNBUFS; j++) {
14798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
14808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			ASSERT(crcr == crc32tv[j]);
14818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
14828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
14838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	MFREE(buf, CBUFSIZ*CNBUFS);
14858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return;
14868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
14878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* notdef */
14888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
14898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
14908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Advance from the current 1-byte tag/1-byte length/variable-length value
14918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * triple, to the next, returning a pointer to the next.
14928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * If the current or next TLV is invalid (does not fit in given buffer length),
14938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * NULL is returned.
14948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
14958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * by the TLV parameter's length if it is valid.
14968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
14978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_tlv_t *
14988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_next_tlv(bcm_tlv_t *elt, int *buflen)
14998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
15008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int len;
15018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* validate current elt */
15038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!bcm_valid_tlv(elt, *buflen))
15048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
15058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* advance to next elt */
15078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len = elt->len;
15088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	elt = (bcm_tlv_t*)(elt->data + len);
1509832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	*buflen -= (TLV_HDR_LEN + len);
15108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* validate next elt */
15128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (!bcm_valid_tlv(elt, *buflen))
15138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return NULL;
15148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return elt;
15168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
15178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
15198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Traverse a string of 1-byte tag/1-byte length/variable-length value
15208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * triples, returning a pointer to the substring whose first element
15218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * matches tag
15228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
15238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_tlv_t *
15248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_parse_tlvs(void *buf, int buflen, uint key)
15258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
15268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	bcm_tlv_t *elt;
15278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int totlen;
15288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	elt = (bcm_tlv_t*)buf;
15308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	totlen = buflen;
15318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* find tagged parameter */
1533832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	while (totlen >= TLV_HDR_LEN) {
15348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		int len = elt->len;
15358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* validate remaining totlen */
1537832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if ((elt->id == key) &&
1538832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		    (totlen >= (len + TLV_HDR_LEN)))
15398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return (elt);
15408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1541832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
1542832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		totlen -= (len + TLV_HDR_LEN);
15438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
15448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return NULL;
15468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
15478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
15498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Traverse a string of 1-byte tag/1-byte length/variable-length value
15508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * triples, returning a pointer to the substring whose first element
15518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * matches tag.  Stop parsing when we see an element whose ID is greater
15528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * than the target key.
15538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
15548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_tlv_t *
15558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
15568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
15578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	bcm_tlv_t *elt;
15588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int totlen;
15598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	elt = (bcm_tlv_t*)buf;
15618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	totlen = buflen;
15628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* find tagged parameter */
1564832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	while (totlen >= TLV_HDR_LEN) {
15658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		uint id = elt->id;
15668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		int len = elt->len;
15678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* Punt if we start seeing IDs > than target key */
15698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (id > key)
15708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return (NULL);
15718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* validate remaining totlen */
1573832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if ((id == key) &&
1574832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		    (totlen >= (len + TLV_HDR_LEN)))
15758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return (elt);
15768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1577832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
1578832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		totlen -= (len + TLV_HDR_LEN);
15798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
15808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return NULL;
15818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
15828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \
15848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	defined(DHD_DEBUG)
15858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
15868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len)
15878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
15888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
15898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char* p = buf;
15908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char hexstr[16];
15918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int slen = 0, nlen = 0;
15928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint32 bit;
15938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	const char* name;
15948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (len < 2 || !buf)
15968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
15978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
15988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	buf[0] = '\0';
15998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; flags != 0; i++) {
16018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		bit = bd[i].bit;
16028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		name = bd[i].name;
16038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (bit == 0 && flags != 0) {
16048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			/* print any unnamed bits */
16058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			snprintf(hexstr, 16, "0x%X", flags);
16068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			name = hexstr;
1607832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			flags = 0;	/* exit loop */
16088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else if ((flags & bit) == 0)
16098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			continue;
16108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		flags &= ~bit;
16118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		nlen = strlen(name);
16128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		slen += nlen;
16138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* count btwn flag space */
16148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (flags != 0)
16158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			slen += 1;
16168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* need NULL char as well */
16178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len <= slen)
16188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
16198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* copy NULL char but don't count it */
16208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		strncpy(p, name, nlen + 1);
16218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		p += nlen;
16228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* copy btwn flag space and NULL char */
16238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (flags != 0)
16248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p += snprintf(p, 2, " ");
16258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
16268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* indicate the str was too short */
16288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (flags != 0) {
16298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len < 2)
1630832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			p -= 2 - len;	/* overwrite last char */
16318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		p += snprintf(p, 2, ">");
16328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
16338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (int)(p - buf);
16358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
16368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* print bytes formatted as hex to a string. return the resulting string length */
16388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
16398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_format_hex(char *str, const void *bytes, int len)
16408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
16418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
16428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *p = str;
16438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	const uint8 *src = (const uint8*)bytes;
16448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < len; i++) {
16468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		p += snprintf(p, 3, "%02X", *src);
16478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		src++;
16488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
16498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (int)(p - str);
16508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
16518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif
16528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* pretty hex print a contiguous buffer */
16548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
16558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtprhex(const char *msg, uchar *buf, uint nbytes)
16568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
16578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char line[128], *p;
16588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int len = sizeof(line);
16598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int nchar;
16608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint i;
16618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (msg && (msg[0] != '\0'))
16638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		printf("%s:\n", msg);
16648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	p = line;
16668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < nbytes; i++) {
16678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (i % 16 == 0) {
1668832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			nchar = snprintf(p, len, "  %04d: ", i);	/* line prefix */
16698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p += nchar;
16708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len -= nchar;
16718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
16728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len > 0) {
16738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			nchar = snprintf(p, len, "%02x ", buf[i]);
16748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p += nchar;
16758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len -= nchar;
16768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
16778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (i % 16 == 15) {
1679832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt			printf("%s\n", line);		/* flush line */
16808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p = line;
16818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len = sizeof(line);
16828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
16838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
16848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* flush last partial line */
16868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (p != line)
16878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		printf("%s\n", line);
16888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
16898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
16908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const char *crypto_algo_names[] = {
16918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"NONE",
16928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"WEP1",
16938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"TKIP",
16948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"WEP128",
16958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"AES_CCM",
16968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"AES_OCB_MSDU",
16978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"AES_OCB_MPDU",
16988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"NALG"
16998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"UNDEF",
17008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"UNDEF",
17018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"UNDEF",
17028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	"UNDEF"
17038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
17048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtconst char *
17068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_crypto_algo_name(uint algo)
17078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR";
17098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
17108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar *
17138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_chipname(uint chipid, char *buf, uint len)
17148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	const char *fmt;
17168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
17188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	snprintf(buf, len, fmt, chipid);
17198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return buf;
17208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
17218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Produce a human-readable string for boardrev */
17238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar *
17248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_brev_str(uint32 brev, char *buf)
17258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (brev < 0x100)
17278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
17288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	else
17298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff);
17308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (buf);
17328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
17338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */
17358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* dump large strings to console */
17378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
17388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtprintbig(char *buf)
17398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint len, max_len;
17418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char c;
17428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len = strlen(buf);
17448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	max_len = BUFSIZE_TODUMP_ATONCE;
17468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (len > max_len) {
17488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		c = buf[max_len];
17498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf[max_len] = '\0';
17508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		printf("%s", buf);
17518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf[max_len] = c;
17528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf += max_len;
17548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		len -= max_len;
17558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
17568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* print the remaining string */
17578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	printf("%s\n", buf);
17588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return;
17598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
17608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* routine to dump fields in a fileddesc structure */
17628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint
17638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array,
17648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *buf, uint32 bufsize)
17658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint  filled_len;
17678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int len;
17688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	struct fielddesc *cur_ptr;
17698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	filled_len = 0;
17718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	cur_ptr = fielddesc_array;
17728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (bufsize > 1) {
17748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (cur_ptr->nameandfmt == NULL)
17758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
17768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		len = snprintf(buf, bufsize, cur_ptr->nameandfmt,
1777832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		               read_rtn(arg0, arg1, cur_ptr->offset));
17788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* check for snprintf overflow or error */
17798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (len < 0 || (uint32)len >= bufsize)
17808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			len = bufsize - 1;
17818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		buf += len;
17828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		bufsize -= len;
17838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		filled_len += len;
17848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		cur_ptr++;
17858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
17868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return filled_len;
17878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
17888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint
17908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
17918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
17928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint len;
17938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len = strlen(name) + 1;
17958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if ((len + datalen) > buflen)
17978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
17988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
17998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	strncpy(buf, name, buflen);
18008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* append data onto the end of the name string */
18028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	memcpy(&buf[len], data, datalen);
18038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	len += datalen;
18048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return len;
18068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
18078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Quarter dBm units to mW
18098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
18108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Table is offset so the last entry is largest mW value that fits in
18118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * a uint16.
18128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
18138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
1814832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define QDBM_OFFSET 153		/* Offset for first entry */
1815832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define QDBM_TABLE_LEN 40	/* Table size */
18168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
18188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
18198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
18208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
18218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Largest mW value that will round down to the last table entry,
18238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * QDBM_OFFSET + QDBM_TABLE_LEN-1.
18248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
18258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */
18268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
18278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
1829832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* qdBm: 	+0 	+1 	+2 	+3 	+4 	+5 	+6 	+7 */
1830832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* 153: */      6683,	7079,	7499,	7943,	8414,	8913,	9441,	10000,
1831832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* 161: */      10593,	11220,	11885,	12589,	13335,	14125,	14962,	15849,
1832832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* 169: */      16788,	17783,	18836,	19953,	21135,	22387,	23714,	25119,
1833832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* 177: */      26607,	28184,	29854,	31623,	33497,	35481,	37584,	39811,
1834832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt/* 185: */      42170,	44668,	47315,	50119,	53088,	56234,	59566,	63096
18358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt};
18368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint16
18388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_qdbm_to_mw(uint8 qdbm)
18398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
18408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint factor = 1;
18418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int idx = qdbm - QDBM_OFFSET;
18428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (idx >= QDBM_TABLE_LEN) {
18448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		/* clamp to max uint16 mW value */
18458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0xFFFF;
18468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
18478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* scale the qdBm index up to the range of the table 0-40
18498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * where an offset of 40 qdBm equals a factor of 10 mW.
18508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
18518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (idx < 0) {
18528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		idx += 40;
18538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		factor *= 10;
18548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
18558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* return the mW value scaled down to the correct factor of 10,
18578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * adding in factor/2 to get proper rounding.
18588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
18598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return ((nqdBm_to_mW_map[idx] + factor/2) / factor);
18608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
18618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint8
18638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_mw_to_qdbm(uint16 mw)
18648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
18658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint8 qdbm;
18668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int offset;
18678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint mw_uint = mw;
18688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint boundary;
18698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* handle boundary case */
18718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (mw_uint <= 1)
18728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		return 0;
18738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	offset = QDBM_OFFSET;
18758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* move mw into the range of the table */
18778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
18788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		mw_uint *= 10;
18798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		offset -= 40;
18808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
18818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) {
18838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] -
1884832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		                                    nqdBm_to_mW_map[qdbm])/2;
1885832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		if (mw_uint < boundary) break;
18868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
18878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	qdbm += (uint8)offset;
18898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (qdbm);
18918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
18928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
18948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint
18958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_bitcount(uint8 *bitmap, uint length)
18968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
18978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint bitcount = 0, i;
18988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint8 tmp;
18998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < length; i++) {
19008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		tmp = bitmap[i];
19018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		while (tmp) {
19028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			bitcount++;
19038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			tmp &= (tmp - 1);
19048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
19058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
19068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return bitcount;
19078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
19088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMDRIVER
19108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Initialization of bcmstrbuf structure */
19128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
19138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_binit(struct bcmstrbuf *b, char *buf, uint size)
19148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
19158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	b->origsize = b->size = size;
19168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	b->origbuf = b->buf = buf;
19178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
19188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Buffer sprintf wrapper to guard against buffer overflow */
19208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
19218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
19228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
19238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	va_list ap;
19248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int r;
19258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	va_start(ap, fmt);
1927832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
19288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	r = vsnprintf(b->buf, b->size, fmt, ap);
19298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	/* Non Ansi C99 compliant returns -1,
19318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * Ansi compliant return r >= b->size,
19328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 * bcmstdlib returns 0, handle all
19338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	 */
1934832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	/* r == 0 is also the case when strlen(fmt) is zero.
1935832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	 * typically the case when "" is passed as argument.
1936832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	 */
1937832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if ((r == -1) || (r >= (int)b->size)) {
19388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		b->size = 0;
19398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	} else {
19408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		b->size -= r;
19418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		b->buf += r;
19428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
19438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	va_end(ap);
19458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return r;
19478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
19488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
1950832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len)
1951832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{
1952832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	int i;
1953832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
1954832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (msg != NULL && msg[0] != '\0')
1955832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		bcm_bprintf(b, "%s", msg);
1956832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	for (i = 0; i < len; i ++)
1957832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		bcm_bprintf(b, "%02X", buf[i]);
1958832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt	if (newline)
1959832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt		bcm_bprintf(b, "\n");
1960832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}
1961832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt
1962832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtvoid
19638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_inc_bytes(uchar *num, int num_bytes, uint8 amount)
19648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
19658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
19668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < num_bytes; i++) {
19688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		num[i] += amount;
19698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (num[i] >= amount)
19708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			break;
19718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		amount = 1;
19728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
19738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
19748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
1976832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes)
19778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
19788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
19798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = nbytes - 1; i >= 0; i--) {
19818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (arg1[i] != arg2[i])
19828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			return (arg1[i] - arg2[i]);
19838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
19848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return 0;
19858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
19868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid
1988832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbcm_print_bytes(const char *name, const uchar *data, int len)
19898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
19908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int i;
19918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int per_line = 0;
19928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
19938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	printf("%s: %d \n", name ? name : "", len);
19948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < len; i++) {
19958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		printf("%02x ", *data++);
19968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		per_line++;
19978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (per_line == 16) {
19988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			per_line = 0;
19998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			printf("\n");
20008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
20018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
20028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	printf("\n");
20038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
20048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \
20058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
2006832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define SSID_FMT_BUF_LEN	((4 * DOT11_MAX_SSID_LEN) + 1)
20078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint
20098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len)
20108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
20118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	uint i, c;
20128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *p = buf;
20138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *endp = buf + SSID_FMT_BUF_LEN;
20148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN;
20168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (i = 0; i < ssid_len; i++) {
20188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		c = (uint)ssid[i];
20198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (c == '\\') {
20208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			*p++ = '\\';
20218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			*p++ = '\\';
20228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else if (bcm_isprint((uchar)c)) {
20238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			*p++ = (char)c;
20248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		} else {
20258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			p += snprintf(p, (endp - p), "\\x%02X", c);
20268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
20278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
20288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	*p = '\0';
20298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	ASSERT(p < endp);
20308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return (int)(p - buf);
20328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
20338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif
20348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMDRIVER */
20368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/*
20388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file and ending in a NUL.
20398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * also accepts nvram files which are already in the format of <var1>=<value>\0\<var2>=<value2>\0
20408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs.
20418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Shortens buffer as needed and pads with NULs.  End of buffer is marked by two NULs.
20428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt*/
20438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtunsigned int
20458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtprocess_nvram_vars(char *varbuf, unsigned int len)
20468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{
20478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	char *dp;
20488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	bool findNewline;
20498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	int column;
20508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	unsigned int buf_len, n;
20518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	unsigned int pad = 0;
20528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	dp = varbuf;
20548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	findNewline = FALSE;
20568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	column = 0;
20578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	for (n = 0; n < len; n++) {
20598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (varbuf[n] == '\r')
20608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			continue;
20618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (findNewline && varbuf[n] != '\n')
20628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			continue;
20638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		findNewline = FALSE;
20648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (varbuf[n] == '#') {
20658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			findNewline = TRUE;
20668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			continue;
20678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
20688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (varbuf[n] == '\n') {
20698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			if (column == 0)
20708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt				continue;
20718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			*dp++ = 0;
20728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			column = 0;
20738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			continue;
20748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
20758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*dp++ = varbuf[n];
20768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		column++;
20778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
20788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	buf_len = (unsigned int)(dp - varbuf);
20798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	if (buf_len % 4) {
20808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		pad = 4 - buf_len % 4;
20818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		if (pad && (buf_len + pad <= len)) {
20828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt			buf_len += pad;
20838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		}
20848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	}
20858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	while (dp < varbuf + n)
20878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt		*dp++ = 0;
20888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt
20898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt	return buf_len;
20908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}
2091