Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | // SPDX-License-Identifier: ISC /* * Copyright (c) 2010 Broadcom Corporation */ #ifndef _BRCMU_UTILS_H_ #define _BRCMU_UTILS_H_ #include <linux/skbuff.h> /* * Spin at most 'us' microseconds while 'exp' is true. * Caller should explicitly test 'exp' when this completes * and take appropriate error action if 'exp' is still true. */ #define SPINWAIT(exp, us) { \ uint countdown = (us) + 9; \ while ((exp) && (countdown >= 10)) {\ udelay(10); \ countdown -= 10; \ } \ } /* osl multi-precedence packet queue */ #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ #define BCME_STRLEN 64 /* Max string length for BCM errors */ /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ #define PKTBUFSZ 2048 #ifndef setbit #ifndef NBBY /* the BSD family defines NBBY */ #define NBBY 8 /* 8 bits per byte */ #endif /* #ifndef NBBY */ #define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) #endif /* setbit */ #define NBITS(type) (sizeof(type) * 8) #define NBITVAL(nbits) (1 << (nbits)) #define MAXBITVAL(nbits) ((1 << (nbits)) - 1) #define NBITMASK(nbits) MAXBITVAL(nbits) #define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) /* crc defines */ #define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ #define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ /* 18-bytes of Ethernet address buffer length */ #define ETHER_ADDR_STR_LEN 18 struct pktq_prec { struct sk_buff_head skblist; u16 max; /* maximum number of queued packets */ }; /* multi-priority pkt queue */ struct pktq { u16 num_prec; /* number of precedences in use */ u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ u16 max; /* total max packets */ u16 len; /* total number of packets */ /* * q array must be last since # of elements can be either * PKTQ_MAX_PREC or 1 */ struct pktq_prec q[PKTQ_MAX_PREC]; }; /* operations on a specific precedence in packet queue */ static inline int pktq_plen(struct pktq *pq, int prec) { return pq->q[prec].skblist.qlen; } static inline int pktq_pavail(struct pktq *pq, int prec) { return pq->q[prec].max - pq->q[prec].skblist.qlen; } static inline bool pktq_pfull(struct pktq *pq, int prec) { return pq->q[prec].skblist.qlen >= pq->q[prec].max; } static inline bool pktq_pempty(struct pktq *pq, int prec) { return skb_queue_empty(&pq->q[prec].skblist); } static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) { return skb_peek(&pq->q[prec].skblist); } static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) { return skb_peek_tail(&pq->q[prec].skblist); } struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p); struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p); struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, bool (*match_fn)(struct sk_buff *p, void *arg), void *arg); /* packet primitives */ struct sk_buff *brcmu_pkt_buf_get_skb(uint len); void brcmu_pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ /* callback function fn(pkt, arg) returns true if pkt belongs to if */ void brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, bool (*fn)(struct sk_buff *, void *), void *arg); /* operations on a set of precedences in packet queue */ int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* operations on packet queue as a whole */ static inline int pktq_len(struct pktq *pq) { return (int)pq->len; } static inline int pktq_max(struct pktq *pq) { return (int)pq->max; } static inline int pktq_avail(struct pktq *pq) { return (int)(pq->max - pq->len); } static inline bool pktq_full(struct pktq *pq) { return pq->len >= pq->max; } static inline bool pktq_empty(struct pktq *pq) { return pq->len == 0; } void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); void brcmu_pktq_flush(struct pktq *pq, bool dir, bool (*fn)(struct sk_buff *, void *), void *arg); /* externs */ /* ip address */ struct ipv4_addr; /* * bitfield macros using masking and shift * * remark: the mask parameter should be a shifted mask. */ static inline void brcmu_maskset32(u32 *var, u32 mask, u8 shift, u32 value) { value = (value << shift) & mask; *var = (*var & ~mask) | value; } static inline u32 brcmu_maskget32(u32 var, u32 mask, u8 shift) { return (var & mask) >> shift; } static inline void brcmu_maskset16(u16 *var, u16 mask, u8 shift, u16 value) { value = (value << shift) & mask; *var = (*var & ~mask) | value; } static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift) { return (var & mask) >> shift; } /* externs */ /* format/print */ #ifdef DEBUG void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) #endif /* DEBUG */ #ifdef DEBUG __printf(3, 4) void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); #else __printf(3, 4) static inline void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) { } #endif #define BRCMU_BOARDREV_LEN 8 #define BRCMU_DOTREV_LEN 16 char *brcmu_boardrev_str(u32 brev, char *buf); char *brcmu_dotrev_str(u32 dotrev, char *buf); #endif /* _BRCMU_UTILS_H_ */ |