📄 bcmutils.c
字号:
/* * Misc useful OS-independent routines. * * Copyright 2005-2006, Broadcom Corporation * All Rights Reserved. * * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * $Id$ */#include <typedefs.h>#include <bcmdefs.h>#ifdef BCMDRIVER#include <osl.h>#include <sbutils.h>#include <bcmnvram.h>#else#include <stdio.h>#include <string.h>#endif /* BCMDRIVER */#include <bcmutils.h>#include <bcmendian.h>#include <bcmdevs.h>#include <proto/ethernet.h>#include <proto/vlan.h>#include <proto/bcmip.h>#include <proto/802.1d.h>#ifdef BCMDRIVER/* copy a pkt buffer chain into a buffer */uintpktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf){ uint n, ret = 0; if (len < 0) len = 4096; /* "infinite" */ /* skip 'offset' bytes */ for (; p && offset; p = PKTNEXT(osh, p)) { if (offset < (uint)PKTLEN(osh, p)) break; offset -= PKTLEN(osh, p); } if (!p) return 0; /* copy the data */ for (; p && len; p = PKTNEXT(osh, p)) { n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); bcopy(PKTDATA(osh, p) + offset, buf, n); buf += n; len -= n; ret += n; offset = 0; } return ret;}/* return total length of buffer chain */uintpkttotlen(osl_t *osh, void *p){ uint total; total = 0; for (; p; p = PKTNEXT(osh, p)) total += PKTLEN(osh, p); return (total);}/* return the last buffer of chained pkt */void *pktlast(osl_t *osh, void *p){ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) ; return (p);}/* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty queue */void *pktq_penq(struct pktq *pq, int prec, void *p){ struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head) PKTSETLINK(q->tail, p); else q->head = p; q->tail = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; return p;}void *pktq_penq_head(struct pktq *pq, int prec, void *p){ struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head == NULL) q->tail = p; PKTSETLINK(p, q->head); q->head = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; return p;}void *pktq_pdeq(struct pktq *pq, int prec){ struct pktq_prec *q; void *p; ASSERT(prec >= 0 && prec < pq->num_prec); q = &pq->q[prec]; if ((p = q->head) == NULL) return NULL; if ((q->head = PKTLINK(p)) == NULL) q->tail = NULL; q->len--; pq->len--; PKTSETLINK(p, NULL); return p;}void *pktq_pdeq_tail(struct pktq *pq, int prec){ struct pktq_prec *q; void *p, *prev; ASSERT(prec >= 0 && prec < pq->num_prec); q = &pq->q[prec]; if ((p = q->head) == NULL) return NULL; for (prev = NULL; p != q->tail; p = PKTLINK(p)) prev = p; if (prev) PKTSETLINK(prev, NULL); else q->head = NULL; q->tail = prev; q->len--; pq->len--; return p;}voidpktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir){ struct pktq_prec *q; void *p; q = &pq->q[prec]; p = q->head; while (p) { q->head = PKTLINK(p); PKTSETLINK(p, NULL); PKTFREE(osh, p, dir); q->len--; pq->len--; p = q->head; } ASSERT(q->len == 0); q->tail = NULL;}boolpktq_pdel(struct pktq *pq, void *pktbuf, int prec){ struct pktq_prec *q; void *p; ASSERT(prec >= 0 && prec < pq->num_prec); if (!pktbuf) return FALSE; q = &pq->q[prec]; if (q->head == pktbuf) { if ((q->head = PKTLINK(pktbuf)) == NULL) q->tail = NULL; } else { for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) ; if (p == NULL) return FALSE; PKTSETLINK(p, PKTLINK(pktbuf)); if (q->tail == pktbuf) q->tail = p; } q->len--; pq->len--; PKTSETLINK(pktbuf, NULL); return TRUE;}voidpktq_init(struct pktq *pq, int num_prec, int max_len){ int prec; ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); bzero(pq, sizeof(*pq)); pq->num_prec = (uint16)num_prec; pq->max = (uint16)max_len; for (prec = 0; prec < num_prec; prec++) pq->q[prec].max = pq->max;}void *pktq_deq(struct pktq *pq, int *prec_out){ struct pktq_prec *q; void *p; int prec; if (pq->len == 0) return NULL; while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) pq->hi_prec--; q = &pq->q[prec]; if ((p = q->head) == NULL) return NULL; if ((q->head = PKTLINK(p)) == NULL) q->tail = NULL; q->len--; pq->len--; if (prec_out) *prec_out = prec; PKTSETLINK(p, NULL); return p;}void *pktq_deq_tail(struct pktq *pq, int *prec_out){ struct pktq_prec *q; void *p, *prev; int prec; if (pq->len == 0) return NULL; for (prec = 0; prec < pq->hi_prec; prec++) if (pq->q[prec].head) break; q = &pq->q[prec]; if ((p = q->head) == NULL) return NULL; for (prev = NULL; p != q->tail; p = PKTLINK(p)) prev = p; if (prev) PKTSETLINK(prev, NULL); else q->head = NULL; q->tail = prev; q->len--; pq->len--; if (prec_out) *prec_out = prec; PKTSETLINK(p, NULL); return p;}void *pktq_peek(struct pktq *pq, int *prec_out){ int prec; if (pq->len == 0) return NULL; while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) pq->hi_prec--; if (prec_out) *prec_out = prec; return (pq->q[prec].head);}void *pktq_peek_tail(struct pktq *pq, int *prec_out){ int prec; if (pq->len == 0) return NULL; for (prec = 0; prec < pq->hi_prec; prec++) if (pq->q[prec].head) break; if (prec_out) *prec_out = prec; return (pq->q[prec].tail);}voidpktq_flush(osl_t *osh, struct pktq *pq, bool dir){ int prec; for (prec = 0; prec < pq->num_prec; prec++) pktq_pflush(osh, pq, prec, dir); ASSERT(pq->len == 0);}/* Return sum of lengths of a specific set of precedences */intpktq_mlen(struct pktq *pq, uint prec_bmp){ int prec, len; len = 0; for (prec = 0; prec <= pq->hi_prec; prec++) if (prec_bmp & (1 << prec)) len += pq->q[prec].len; return len;}/* Priority dequeue from a specific set of precedences */void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out){ struct pktq_prec *q; void *p; int prec; if (pq->len == 0) return NULL; while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) pq->hi_prec--; while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) if (prec-- == 0) return NULL; q = &pq->q[prec]; if ((p = q->head) == NULL) return NULL; if ((q->head = PKTLINK(p)) == NULL) q->tail = NULL; q->len--; if (prec_out) *prec_out = prec; pq->len--; PKTSETLINK(p, NULL); return p;}unsigned char bcm_ctype[] = { _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, _BCM_C, /* 8-15 */ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -