xref: /linux/drivers/net/wireless/broadcom/brcm80211/include/brcmu_utils.h (revision 0898782247ae533d1f4e47a06bc5d4870931b284)
1*7e5677deSArend van Spriel // SPDX-License-Identifier: ISC
205491d2cSKalle Valo /*
305491d2cSKalle Valo  * Copyright (c) 2010 Broadcom Corporation
405491d2cSKalle Valo  */
505491d2cSKalle Valo 
605491d2cSKalle Valo #ifndef	_BRCMU_UTILS_H_
705491d2cSKalle Valo #define	_BRCMU_UTILS_H_
805491d2cSKalle Valo 
905491d2cSKalle Valo #include <linux/skbuff.h>
1005491d2cSKalle Valo 
1105491d2cSKalle Valo /*
1205491d2cSKalle Valo  * Spin at most 'us' microseconds while 'exp' is true.
1305491d2cSKalle Valo  * Caller should explicitly test 'exp' when this completes
1405491d2cSKalle Valo  * and take appropriate error action if 'exp' is still true.
1505491d2cSKalle Valo  */
1605491d2cSKalle Valo #define SPINWAIT(exp, us) { \
1705491d2cSKalle Valo 	uint countdown = (us) + 9; \
1805491d2cSKalle Valo 	while ((exp) && (countdown >= 10)) {\
1905491d2cSKalle Valo 		udelay(10); \
2005491d2cSKalle Valo 		countdown -= 10; \
2105491d2cSKalle Valo 	} \
2205491d2cSKalle Valo }
2305491d2cSKalle Valo 
2405491d2cSKalle Valo /* osl multi-precedence packet queue */
2505491d2cSKalle Valo #define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
2605491d2cSKalle Valo #define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
2705491d2cSKalle Valo 
2805491d2cSKalle Valo #define BCME_STRLEN		64	/* Max string length for BCM errors */
2905491d2cSKalle Valo 
3005491d2cSKalle Valo /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
3105491d2cSKalle Valo #define	PKTBUFSZ	2048
3205491d2cSKalle Valo 
3305491d2cSKalle Valo #ifndef setbit
3405491d2cSKalle Valo #ifndef NBBY			/* the BSD family defines NBBY */
3505491d2cSKalle Valo #define	NBBY	8		/* 8 bits per byte */
3605491d2cSKalle Valo #endif				/* #ifndef NBBY */
3705491d2cSKalle Valo #define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
3805491d2cSKalle Valo #define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
3905491d2cSKalle Valo #define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
4005491d2cSKalle Valo #define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
4105491d2cSKalle Valo #endif				/* setbit */
4205491d2cSKalle Valo 
4305491d2cSKalle Valo #define	NBITS(type)	(sizeof(type) * 8)
4405491d2cSKalle Valo #define NBITVAL(nbits)	(1 << (nbits))
4505491d2cSKalle Valo #define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
4605491d2cSKalle Valo #define	NBITMASK(nbits)	MAXBITVAL(nbits)
4705491d2cSKalle Valo #define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
4805491d2cSKalle Valo 
4905491d2cSKalle Valo /* crc defines */
5005491d2cSKalle Valo #define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
5105491d2cSKalle Valo #define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
5205491d2cSKalle Valo 
5305491d2cSKalle Valo /* 18-bytes of Ethernet address buffer length */
5405491d2cSKalle Valo #define ETHER_ADDR_STR_LEN	18
5505491d2cSKalle Valo 
5605491d2cSKalle Valo struct pktq_prec {
5705491d2cSKalle Valo 	struct sk_buff_head skblist;
5805491d2cSKalle Valo 	u16 max;		/* maximum number of queued packets */
5905491d2cSKalle Valo };
6005491d2cSKalle Valo 
6105491d2cSKalle Valo /* multi-priority pkt queue */
6205491d2cSKalle Valo struct pktq {
6305491d2cSKalle Valo 	u16 num_prec;	/* number of precedences in use */
6405491d2cSKalle Valo 	u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
6505491d2cSKalle Valo 	u16 max;	/* total max packets */
6605491d2cSKalle Valo 	u16 len;	/* total number of packets */
6705491d2cSKalle Valo 	/*
6805491d2cSKalle Valo 	 * q array must be last since # of elements can be either
6905491d2cSKalle Valo 	 * PKTQ_MAX_PREC or 1
7005491d2cSKalle Valo 	 */
7105491d2cSKalle Valo 	struct pktq_prec q[PKTQ_MAX_PREC];
7205491d2cSKalle Valo };
7305491d2cSKalle Valo 
7405491d2cSKalle Valo /* operations on a specific precedence in packet queue */
7505491d2cSKalle Valo 
pktq_plen(struct pktq * pq,int prec)7605491d2cSKalle Valo static inline int pktq_plen(struct pktq *pq, int prec)
7705491d2cSKalle Valo {
7805491d2cSKalle Valo 	return pq->q[prec].skblist.qlen;
7905491d2cSKalle Valo }
8005491d2cSKalle Valo 
pktq_pavail(struct pktq * pq,int prec)8105491d2cSKalle Valo static inline int pktq_pavail(struct pktq *pq, int prec)
8205491d2cSKalle Valo {
8305491d2cSKalle Valo 	return pq->q[prec].max - pq->q[prec].skblist.qlen;
8405491d2cSKalle Valo }
8505491d2cSKalle Valo 
pktq_pfull(struct pktq * pq,int prec)8605491d2cSKalle Valo static inline bool pktq_pfull(struct pktq *pq, int prec)
8705491d2cSKalle Valo {
8805491d2cSKalle Valo 	return pq->q[prec].skblist.qlen >= pq->q[prec].max;
8905491d2cSKalle Valo }
9005491d2cSKalle Valo 
pktq_pempty(struct pktq * pq,int prec)9105491d2cSKalle Valo static inline bool pktq_pempty(struct pktq *pq, int prec)
9205491d2cSKalle Valo {
9305491d2cSKalle Valo 	return skb_queue_empty(&pq->q[prec].skblist);
9405491d2cSKalle Valo }
9505491d2cSKalle Valo 
pktq_ppeek(struct pktq * pq,int prec)9605491d2cSKalle Valo static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
9705491d2cSKalle Valo {
9805491d2cSKalle Valo 	return skb_peek(&pq->q[prec].skblist);
9905491d2cSKalle Valo }
10005491d2cSKalle Valo 
pktq_ppeek_tail(struct pktq * pq,int prec)10105491d2cSKalle Valo static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
10205491d2cSKalle Valo {
10305491d2cSKalle Valo 	return skb_peek_tail(&pq->q[prec].skblist);
10405491d2cSKalle Valo }
10505491d2cSKalle Valo 
10605491d2cSKalle Valo struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p);
10705491d2cSKalle Valo struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
10805491d2cSKalle Valo 				     struct sk_buff *p);
10905491d2cSKalle Valo struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
11005491d2cSKalle Valo struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
11105491d2cSKalle Valo struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
11205491d2cSKalle Valo 				      bool (*match_fn)(struct sk_buff *p,
11305491d2cSKalle Valo 						       void *arg),
11405491d2cSKalle Valo 				      void *arg);
11505491d2cSKalle Valo 
11605491d2cSKalle Valo /* packet primitives */
11705491d2cSKalle Valo struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
11805491d2cSKalle Valo void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
11905491d2cSKalle Valo 
12005491d2cSKalle Valo /* Empty the queue at particular precedence level */
12105491d2cSKalle Valo /* callback function fn(pkt, arg) returns true if pkt belongs to if */
12205491d2cSKalle Valo void brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
12305491d2cSKalle Valo 		       bool (*fn)(struct sk_buff *, void *), void *arg);
12405491d2cSKalle Valo 
12505491d2cSKalle Valo /* operations on a set of precedences in packet queue */
12605491d2cSKalle Valo 
12705491d2cSKalle Valo int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
12805491d2cSKalle Valo struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
12905491d2cSKalle Valo 
13005491d2cSKalle Valo /* operations on packet queue as a whole */
13105491d2cSKalle Valo 
pktq_len(struct pktq * pq)13205491d2cSKalle Valo static inline int pktq_len(struct pktq *pq)
13305491d2cSKalle Valo {
13405491d2cSKalle Valo 	return (int)pq->len;
13505491d2cSKalle Valo }
13605491d2cSKalle Valo 
pktq_max(struct pktq * pq)13705491d2cSKalle Valo static inline int pktq_max(struct pktq *pq)
13805491d2cSKalle Valo {
13905491d2cSKalle Valo 	return (int)pq->max;
14005491d2cSKalle Valo }
14105491d2cSKalle Valo 
pktq_avail(struct pktq * pq)14205491d2cSKalle Valo static inline int pktq_avail(struct pktq *pq)
14305491d2cSKalle Valo {
14405491d2cSKalle Valo 	return (int)(pq->max - pq->len);
14505491d2cSKalle Valo }
14605491d2cSKalle Valo 
pktq_full(struct pktq * pq)14705491d2cSKalle Valo static inline bool pktq_full(struct pktq *pq)
14805491d2cSKalle Valo {
14905491d2cSKalle Valo 	return pq->len >= pq->max;
15005491d2cSKalle Valo }
15105491d2cSKalle Valo 
pktq_empty(struct pktq * pq)15205491d2cSKalle Valo static inline bool pktq_empty(struct pktq *pq)
15305491d2cSKalle Valo {
15405491d2cSKalle Valo 	return pq->len == 0;
15505491d2cSKalle Valo }
15605491d2cSKalle Valo 
15705491d2cSKalle Valo void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
15805491d2cSKalle Valo /* prec_out may be NULL if caller is not interested in return value */
15905491d2cSKalle Valo struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
16005491d2cSKalle Valo void brcmu_pktq_flush(struct pktq *pq, bool dir,
16105491d2cSKalle Valo 		      bool (*fn)(struct sk_buff *, void *), void *arg);
16205491d2cSKalle Valo 
16305491d2cSKalle Valo /* externs */
16405491d2cSKalle Valo /* ip address */
16505491d2cSKalle Valo struct ipv4_addr;
16605491d2cSKalle Valo 
16705491d2cSKalle Valo /*
16805491d2cSKalle Valo  * bitfield macros using masking and shift
16905491d2cSKalle Valo  *
17005491d2cSKalle Valo  * remark: the mask parameter should be a shifted mask.
17105491d2cSKalle Valo  */
brcmu_maskset32(u32 * var,u32 mask,u8 shift,u32 value)17205491d2cSKalle Valo static inline void brcmu_maskset32(u32 *var, u32 mask, u8 shift, u32 value)
17305491d2cSKalle Valo {
17405491d2cSKalle Valo 	value = (value << shift) & mask;
17505491d2cSKalle Valo 	*var = (*var & ~mask) | value;
17605491d2cSKalle Valo }
brcmu_maskget32(u32 var,u32 mask,u8 shift)17705491d2cSKalle Valo static inline u32 brcmu_maskget32(u32 var, u32 mask, u8 shift)
17805491d2cSKalle Valo {
17905491d2cSKalle Valo 	return (var & mask) >> shift;
18005491d2cSKalle Valo }
brcmu_maskset16(u16 * var,u16 mask,u8 shift,u16 value)18105491d2cSKalle Valo static inline void brcmu_maskset16(u16 *var, u16 mask, u8 shift, u16 value)
18205491d2cSKalle Valo {
18305491d2cSKalle Valo 	value = (value << shift) & mask;
18405491d2cSKalle Valo 	*var = (*var & ~mask) | value;
18505491d2cSKalle Valo }
brcmu_maskget16(u16 var,u16 mask,u8 shift)18605491d2cSKalle Valo static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift)
18705491d2cSKalle Valo {
18805491d2cSKalle Valo 	return (var & mask) >> shift;
18905491d2cSKalle Valo }
19005491d2cSKalle Valo 
19105491d2cSKalle Valo /* externs */
19205491d2cSKalle Valo /* format/print */
19305491d2cSKalle Valo #ifdef DEBUG
19405491d2cSKalle Valo void brcmu_prpkt(const char *msg, struct sk_buff *p0);
19505491d2cSKalle Valo #else
19605491d2cSKalle Valo #define brcmu_prpkt(a, b)
19705491d2cSKalle Valo #endif				/* DEBUG */
19805491d2cSKalle Valo 
19905491d2cSKalle Valo #ifdef DEBUG
20005491d2cSKalle Valo __printf(3, 4)
20105491d2cSKalle Valo void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
20205491d2cSKalle Valo #else
20305491d2cSKalle Valo __printf(3, 4)
20405491d2cSKalle Valo static inline
brcmu_dbg_hex_dump(const void * data,size_t size,const char * fmt,...)20505491d2cSKalle Valo void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
20605491d2cSKalle Valo {
20705491d2cSKalle Valo }
20805491d2cSKalle Valo #endif
20905491d2cSKalle Valo 
21005491d2cSKalle Valo #define BRCMU_BOARDREV_LEN	8
21105491d2cSKalle Valo #define BRCMU_DOTREV_LEN	16
21205491d2cSKalle Valo 
21305491d2cSKalle Valo char *brcmu_boardrev_str(u32 brev, char *buf);
21405491d2cSKalle Valo char *brcmu_dotrev_str(u32 dotrev, char *buf);
21505491d2cSKalle Valo 
21605491d2cSKalle Valo #endif				/* _BRCMU_UTILS_H_ */
217