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