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