net: wifi: rockchip: update broadcom drivers for kernel4.4
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rkwifi / bcmdhd / include / bcmutils.h
index d23444ce4382246c5e8971e1bc24115c0498d620..7dc741697343980376a2fc2c12022bf9e0f88a10 100755 (executable)
@@ -1,26 +1,52 @@
 /*
  * Misc useful os-independent macros and functions.
  *
- * $Copyright Open Broadcom Corporation$
+ * Copyright (C) 1999-2016, Broadcom Corporation
+ * 
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ * 
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ * 
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: bcmutils.h 504037 2014-09-22 19:03:15Z $
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: bcmutils.h 563776 2015-06-15 15:51:15Z $
  */
 
 #ifndef        _bcmutils_h_
 #define        _bcmutils_h_
 
-#define bcm_strcpy_s(dst, noOfElements, src)            strcpy((dst), (src))
-#define bcm_strncpy_s(dst, noOfElements, src, count)    strncpy((dst), (src), (count))
-#define bcm_strcat_s(dst, noOfElements, src)            strcat((dst), (src))
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
-#ifdef PKTQ_LOG
-#include <wlioctl.h>
-#endif
+#define bcm_strncpy_s(dst, noOfElements, src, count)    strncpy((dst), (src), (count))
+#define bcm_strncat_s(dst, noOfElements, src, count)    strncat((dst), (src), (count))
+#define bcm_snprintf_s snprintf
+#define bcm_sprintf_s snprintf
+
+/*
+ * #define bcm_strcpy_s(dst, count, src)            strncpy((dst), (src), (count))
+ * Use bcm_strcpy_s instead as it is a safer option
+ * bcm_strcat_s: Use bcm_strncat_s as a safer option
+ *
+ */
 
 /* ctype replacement */
 #define _BCM_U 0x01    /* upper */
@@ -51,6 +77,8 @@ extern const unsigned char bcm_ctype[];
 
 #define CIRCULAR_ARRAY_FULL(rd_idx, wr_idx, max) ((wr_idx + 1)%max == rd_idx)
 
+#define KB(bytes)      (((bytes) + 1023) / 1024)
+
 /* Buffer structure for collecting string-formatted data
 * using bcm_bprintf() API.
 * Use bcm_binit() to initialize before use
@@ -63,6 +91,9 @@ struct bcmstrbuf {
        unsigned int origsize;  /* unmodified orignal buffer size in bytes */
 };
 
+#define BCMSTRBUF_LEN(b)       (b->size)
+#define BCMSTRBUF_BUF(b)       (b->buf)
+
 /* ** driver-only section ** */
 #ifdef BCMDRIVER
 #include <osl.h>
@@ -118,6 +149,7 @@ extern int ether_isnulladdr(const void *ea);
 #define BCM_RXCPL_CLR_VALID_INFO(a)    ((a)->rxcpl_id.flags &= ~BCM_RXCPL_FLAGS_RXCPLVALID)
 #define BCM_RXCPL_VALID_INFO(a) (((a)->rxcpl_id.flags & BCM_RXCPL_FLAGS_RXCPLVALID) ? TRUE : FALSE)
 
+#define UP_TABLE_MAX   ((IPV4_TOS_DSCP_MASK >> IPV4_TOS_DSCP_SHIFT) + 1)       /* 64 max */
 
 struct reorder_rxcpl_id_list {
        uint16 head;
@@ -174,6 +206,8 @@ extern uint pktsegcnt(osl_t *osh, void *p);
 extern uint pktsegcnt_war(osl_t *osh, void *p);
 extern uint8 *pktdataoffset(osl_t *osh, void *p,  uint offset);
 extern void *pktoffset(osl_t *osh, void *p,  uint offset);
+/* Add to adjust 802.1x priority */
+extern void pktset8021xprio(void *pkt, int prio);
 
 /* Get priority from a packet and pass it back in scb (or equiv) */
 #define        PKTPRIO_VDSCP   0x100           /* DSCP prio found after VLAN tag */
@@ -198,6 +232,7 @@ extern void *pktoffset(osl_t *osh, void *p,  uint offset);
 #define DSCP_EF                0x2E
 
 extern uint pktsetprio(void *pkt, bool update_vtag);
+extern uint pktsetprio_qms(void *pkt, uint8* up_table, bool update_vtag);
 extern bool pktgetdscp(uint8 *pktdata, uint pktlen, uint8 *dscp);
 
 /* string */
@@ -246,7 +281,7 @@ extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
 #define bcmtslog(tstamp, fmt, a1, a2)
 #define bcmprinttslogs()
 #define bcmprinttstamp(us)
-#define bcmdumptslog(buf, size)
+#define bcmdumptslog(b)
 
 extern char *bcm_nvram_vars(uint *length);
 extern int bcm_nvram_cache(void *sih);
@@ -390,7 +425,8 @@ extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len);
 #define BCME_MICERR                            -50             /* Integrity/MIC error */
 #define BCME_REPLAY                            -51             /* Replay */
 #define BCME_IE_NOTFOUND               -52             /* IE not found */
-#define BCME_LAST                      BCME_IE_NOTFOUND
+#define BCME_DATA_NOTFOUND             -53             /* Complete data not found in buffer */
+#define BCME_LAST                      BCME_DATA_NOTFOUND
 
 #define BCME_NOTENABLED BCME_DISABLED
 
@@ -449,6 +485,7 @@ extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len);
        "MIC error", \
        "Replay", \
        "IE not found", \
+       "Data not found", \
 }
 
 #ifndef ABS
@@ -652,12 +689,12 @@ typedef struct bcm_bit_desc_ex {
 #define ETHER_ADDR_STR_LEN     18      /* 18-bytes of Ethernet address buffer length */
 
 static INLINE uint32 /* 32bit word aligned xor-32 */
-bcm_compute_xor32(volatile uint32 *u32, int num_u32)
+bcm_compute_xor32(volatile uint32 *u32_val, int num_u32)
 {
-       int i;
+       int idx;
        uint32 xor32 = 0;
-       for (i = 0; i < num_u32; i++)
-               xor32 ^= *(u32 + i);
+       for (idx = 0; idx < num_u32; idx++)
+               xor32 ^= *(u32_val + idx);
        return xor32;
 }
 
@@ -710,6 +747,8 @@ extern void prhex(const char *msg, uchar *buf, uint len);
 
 /* IE parsing */
 
+/* packing is required if struct is passed across the bus */
+#include <packed_section_start.h>
 /* tag_ID/length/value_buffer tuple */
 typedef struct bcm_tlv {
        uint8   id;
@@ -718,11 +757,13 @@ typedef struct bcm_tlv {
 } bcm_tlv_t;
 
 /* bcm tlv w/ 16 bit id/len */
-typedef struct bcm_xtlv {
+typedef BWL_PRE_PACKED_STRUCT struct bcm_xtlv {
        uint16  id;
        uint16  len;
        uint8   data[1];
-} bcm_xtlv_t;
+} BWL_POST_PACKED_STRUCT bcm_xtlv_t;
+#include <packed_section_end.h>
+
 
 /* descriptor of xtlv data src or dst  */
 typedef struct {
@@ -731,34 +772,37 @@ typedef struct {
        void    *ptr; /* ptr to memory location */
 } xtlv_desc_t;
 
-/*  set a var from xtlv buffer */
-typedef int
-(bcm_set_var_from_tlv_cbfn_t)(void *ctx, void **tlv_buf, uint16 type, uint16 len);
-
-struct bcm_tlvbuf {
-    uint16 size;
-    uint8 *head; /* point to head of buffer */
-    uint8 *buf; /* current position of buffer */
-       /* followed by the allocated buffer */
+/* xtlv options */
+#define BCM_XTLV_OPTION_NONE   0x0000
+#define BCM_XTLV_OPTION_ALIGN32        0x0001
+
+typedef uint16 bcm_xtlv_opts_t;
+struct bcm_xtlvbuf {
+       bcm_xtlv_opts_t opts;
+       uint16 size;
+       uint8 *head; /* point to head of buffer */
+       uint8 *buf; /* current position of buffer */
+       /* allocated buffer may follow, but not necessarily */
 };
+typedef struct bcm_xtlvbuf bcm_xtlvbuf_t;
 
 #define BCM_TLV_MAX_DATA_SIZE (255)
 #define BCM_XTLV_MAX_DATA_SIZE (65535)
 #define BCM_TLV_HDR_SIZE (OFFSETOF(bcm_tlv_t, data))
 
 #define BCM_XTLV_HDR_SIZE (OFFSETOF(bcm_xtlv_t, data))
+/* LEN only stores the value's length without padding */
 #define BCM_XTLV_LEN(elt) ltoh16_ua(&(elt->len))
 #define BCM_XTLV_ID(elt) ltoh16_ua(&(elt->id))
-#define BCM_XTLV_SIZE(elt) (BCM_XTLV_HDR_SIZE + BCM_XTLV_LEN(elt))
+/* entire size of the XTLV including header, data, and optional padding */
+#define BCM_XTLV_SIZE(elt, opts) bcm_xtlv_size(elt, opts)
+#define bcm_valid_xtlv(elt, buflen, opts) (elt && ((int)(buflen) >= (int)BCM_XTLV_SIZE(elt, opts)))
 
 /* Check that bcm_tlv_t fits into the given buflen */
 #define bcm_valid_tlv(elt, buflen) (\
         ((int)(buflen) >= (int)BCM_TLV_HDR_SIZE) && \
         ((int)(buflen) >= (int)(BCM_TLV_HDR_SIZE + (elt)->len)))
 
-#define bcm_valid_xtlv(elt, buflen) (\
-        ((int)(buflen) >= (int)BCM_XTLV_HDR_SIZE) && \
-        ((int)(buflen) >= (int)BCM_XTLV_SIZE(elt)))
 
 extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
 extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
@@ -777,28 +821,66 @@ extern uint8 *bcm_copy_tlv(const void *src, uint8 *dst);
 extern uint8 *bcm_copy_tlv_safe(const void *src, uint8 *dst, int dst_maxlen);
 
 /* xtlv */
-extern bcm_xtlv_t *bcm_next_xtlv(bcm_xtlv_t *elt, int *buflen);
-extern struct bcm_tlvbuf *bcm_xtlv_buf_alloc(void *osh, uint16 len);
-extern void bcm_xtlv_buf_free(void *osh, struct bcm_tlvbuf *tbuf);
-extern uint16 bcm_xtlv_buf_len(struct bcm_tlvbuf *tbuf);
-extern uint16 bcm_xtlv_buf_rlen(struct bcm_tlvbuf *tbuf);
-extern uint8 *bcm_xtlv_buf(struct bcm_tlvbuf *tbuf);
-extern uint8 *bcm_xtlv_head(struct bcm_tlvbuf *tbuf);
-extern int bcm_xtlv_put_data(struct bcm_tlvbuf *tbuf, uint16 type, const void *data, uint16 dlen);
-extern int bcm_xtlv_put_8(struct bcm_tlvbuf *tbuf, uint16 type, const int8 data);
-extern int bcm_xtlv_put_16(struct bcm_tlvbuf *tbuf, uint16 type, const int16 data);
-extern int bcm_xtlv_put_32(struct bcm_tlvbuf *tbuf, uint16 type, const int32 data);
-extern int bcm_unpack_xtlv_entry(void **tlv_buf, uint16 xpct_type, uint16 xpct_len, void *dst);
-extern int bcm_skip_xtlv(void **tlv_buf);
-extern int bcm_pack_xtlv_entry(void **tlv_buf, uint16 *buflen, uint16 type, uint16 len, void *src);
-extern int bcm_unpack_xtlv_buf(void *ctx,
-       void *tlv_buf, uint16 buflen, bcm_set_var_from_tlv_cbfn_t *cbfn);
-extern int
-bcm_unpack_xtlv_buf_to_mem(void *tlv_buf, int *buflen, xtlv_desc_t *items);
-extern int
-bcm_pack_xtlv_buf_from_mem(void **tlv_buf, uint16 *buflen, xtlv_desc_t *items);
-extern int
-bcm_pack_xtlv_entry_from_hex_string(void **tlv_buf, uint16 *buflen, uint16 type, char *hex);
+
+/* return the next xtlv element, and update buffer len (remaining). Buffer length
+ * updated includes padding as specified by options
+ */
+extern bcm_xtlv_t *bcm_next_xtlv(bcm_xtlv_t *elt, int *buflen, bcm_xtlv_opts_t opts);
+
+/* initialize an xtlv buffer. Use options specified for packing/unpacking using
+ * the buffer. Caller is responsible for allocating both buffers.
+ */
+extern int bcm_xtlv_buf_init(bcm_xtlvbuf_t *tlv_buf, uint8 *buf, uint16 len,
+       bcm_xtlv_opts_t opts);
+
+extern uint16 bcm_xtlv_buf_len(struct bcm_xtlvbuf *tbuf);
+extern uint16 bcm_xtlv_buf_rlen(struct bcm_xtlvbuf *tbuf);
+extern uint8 *bcm_xtlv_buf(struct bcm_xtlvbuf *tbuf);
+extern uint8 *bcm_xtlv_head(struct bcm_xtlvbuf *tbuf);
+extern int bcm_xtlv_put_data(bcm_xtlvbuf_t *tbuf, uint16 type, const void *data, uint16 dlen);
+extern int bcm_xtlv_put_8(bcm_xtlvbuf_t *tbuf, uint16 type, const int8 data);
+extern int bcm_xtlv_put_16(bcm_xtlvbuf_t *tbuf, uint16 type, const int16 data);
+extern int bcm_xtlv_put_32(bcm_xtlvbuf_t *tbuf, uint16 type, const int32 data);
+extern int bcm_unpack_xtlv_entry(uint8 **buf, uint16 xpct_type, uint16 xpct_len,
+       void *dst, bcm_xtlv_opts_t opts);
+extern int bcm_pack_xtlv_entry(uint8 **buf, uint16 *buflen, uint16 type, uint16 len,
+       void *src, bcm_xtlv_opts_t opts);
+extern int bcm_xtlv_size(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts);
+
+/* callback for unpacking xtlv from a buffer into context. */
+typedef int (bcm_xtlv_unpack_cbfn_t)(void *ctx, uint8 *buf, uint16 type, uint16 len);
+
+/* unpack a tlv buffer using buffer, options, and callback */
+extern int bcm_unpack_xtlv_buf(void *ctx, uint8 *buf, uint16 buflen,
+       bcm_xtlv_opts_t opts, bcm_xtlv_unpack_cbfn_t *cbfn);
+
+/* unpack a set of tlvs from the buffer using provided xtlv desc */
+extern int bcm_unpack_xtlv_buf_to_mem(void *buf, int *buflen, xtlv_desc_t *items,
+       bcm_xtlv_opts_t opts);
+
+/* pack a set of tlvs into buffer using provided xtlv desc */
+extern int bcm_pack_xtlv_buf_from_mem(void **buf, uint16 *buflen, xtlv_desc_t *items,
+       bcm_xtlv_opts_t opts);
+
+/* return data pointer of a given ID from xtlv buffer
+ * xtlv data length is given to *datalen_out, if the pointer is valid
+ */
+extern void *bcm_get_data_from_xtlv_buf(uint8 *tlv_buf, uint16 buflen, uint16 id,
+       uint16 *datalen_out, bcm_xtlv_opts_t opts);
+
+/* callback to return next tlv id and len to pack, if there is more tlvs to come and
+ * options e.g. alignment
+ */
+typedef bool (*bcm_pack_xtlv_next_info_cbfn_t)(void *ctx, uint16 *tlv_id, uint16 *tlv_len);
+
+/* callback to pack the tlv into length validated buffer */
+typedef void (*bcm_pack_xtlv_pack_next_cbfn_t)(void *ctx,
+       uint16 tlv_id, uint16 tlv_len, uint8* buf);
+
+/* pack a set of tlvs into buffer using get_next to interate */
+int bcm_pack_xtlv_buf(void *ctx, void *tlv_buf, uint16 buflen,
+       bcm_xtlv_opts_t opts, bcm_pack_xtlv_next_info_cbfn_t get_next,
+       bcm_pack_xtlv_pack_next_cbfn_t pack_next, int *outlen);
 
 /* bcmerror */
 extern const char *bcmerrorstr(int bcmerror);
@@ -813,12 +895,13 @@ typedef uint32 mbool;
 /* generic datastruct to help dump routines */
 struct fielddesc {
        const char *nameandfmt;
-       uint32  offset;
-       uint32  len;
+       uint32 offset;
+       uint32 len;
 };
 
 extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
-extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len);
+extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline,
+       const uint8 *buf, int len);
 
 extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount);
 extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes);
@@ -834,10 +917,54 @@ extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
 /* power conversion */
 extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
 extern uint8 bcm_mw_to_qdbm(uint16 mw);
-extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
+extern uint bcm_mkiovar(const char *name, char *data, uint datalen, char *buf, uint len);
 
 unsigned int process_nvram_vars(char *varbuf, unsigned int len);
 
+/* trace any object allocation / free, with / without features (flags) set to the object */
+
+#define BCM_OBJDBG_ADD           1
+#define BCM_OBJDBG_REMOVE        2
+#define BCM_OBJDBG_ADD_PKT       3
+
+/* object feature: set or clear flags */
+#define BCM_OBJECT_FEATURE_FLAG       1
+#define BCM_OBJECT_FEATURE_PKT_STATE  2
+/* object feature: flag bits */
+#define BCM_OBJECT_FEATURE_0     (1 << 0)
+#define BCM_OBJECT_FEATURE_1     (1 << 1)
+#define BCM_OBJECT_FEATURE_2     (1 << 2)
+/* object feature: clear flag bits field set with this flag */
+#define BCM_OBJECT_FEATURE_CLEAR (1 << 31)
+#ifdef BCM_OBJECT_TRACE
+#define bcm_pkt_validate_chk(obj)      do { \
+       void * pkttag; \
+       bcm_object_trace_chk(obj, 0, 0, \
+               __FUNCTION__, __LINE__); \
+       if ((pkttag = PKTTAG(obj))) { \
+               bcm_object_trace_chk(obj, 1, DHD_PKTTAG_SN(pkttag), \
+                       __FUNCTION__, __LINE__); \
+       } \
+} while (0)
+extern void bcm_object_trace_opr(void *obj, uint32 opt, const char *caller, int line);
+extern void bcm_object_trace_upd(void *obj, void *obj_new);
+extern void bcm_object_trace_chk(void *obj, uint32 chksn, uint32 sn,
+       const char *caller, int line);
+extern void bcm_object_feature_set(void *obj, uint32 type, uint32 value);
+extern int  bcm_object_feature_get(void *obj, uint32 type, uint32 value);
+extern void bcm_object_trace_init(void);
+extern void bcm_object_trace_deinit(void);
+#else
+#define bcm_pkt_validate_chk(obj)
+#define bcm_object_trace_opr(a, b, c, d)
+#define bcm_object_trace_upd(a, b)
+#define bcm_object_trace_chk(a, b, c, d, e)
+#define bcm_object_feature_set(a, b, c)
+#define bcm_object_feature_get(a, b, c)
+#define bcm_object_trace_init()
+#define bcm_object_trace_deinit()
+#endif /* BCM_OBJECT_TRACE */
+
 /* calculate a * b + c */
 extern void bcm_uint64_multiple_add(uint32* r_high, uint32* r_low, uint32 a, uint32 b, uint32 c);
 /* calculate a / b */
@@ -857,20 +984,20 @@ _CSBTBL[256] =
 };
 
 static INLINE uint32 /* Uses table _CSBTBL for fast counting of 1's in a u32 */
-bcm_cntsetbits(const uint32 u32)
+bcm_cntsetbits(const uint32 u32arg)
 {
        /* function local scope declaration of const _CSBTBL[] */
-       const uint8 * p = (const uint8 *)&u32;
+       const uint8 * p = (const uint8 *)&u32arg;
        return (_CSBTBL[p[0]] + _CSBTBL[p[1]] + _CSBTBL[p[2]] + _CSBTBL[p[3]]);
 }
 
 
 static INLINE int /* C equivalent count of leading 0's in a u32 */
-C_bcm_count_leading_zeros(uint32 u32)
+C_bcm_count_leading_zeros(uint32 u32arg)
 {
        int shifts = 0;
-       while (u32) {
-               shifts++; u32 >>= 1;
+       while (u32arg) {
+               shifts++; u32arg >>= 1;
        }
        return (32U - shifts);
 }
@@ -885,29 +1012,38 @@ C_bcm_count_leading_zeros(uint32 u32)
  */
 
 #if defined(__arm__)
-
 #if defined(__ARM_ARCH_7M__) /* Cortex M3 */
 #define __USE_ASM_CLZ__
 #endif /* __ARM_ARCH_7M__ */
-
 #if defined(__ARM_ARCH_7R__) /* Cortex R4 */
 #define __USE_ASM_CLZ__
 #endif /* __ARM_ARCH_7R__ */
-
 #endif /* __arm__ */
 
 static INLINE int
-bcm_count_leading_zeros(uint32 u32)
+bcm_count_leading_zeros(uint32 u32arg)
 {
 #if defined(__USE_ASM_CLZ__)
        int zeros;
-       __asm__ volatile("clz    %0, %1 \n" : "=r" (zeros) : "r"  (u32));
+       __asm__ volatile("clz    %0, %1 \n" : "=r" (zeros) : "r"  (u32arg));
        return zeros;
 #else  /* C equivalent */
-       return C_bcm_count_leading_zeros(u32);
+       return C_bcm_count_leading_zeros(u32arg);
 #endif  /* C equivalent */
 }
 
+/*
+ * Macro to count leading zeroes
+ *
+ */
+#if defined(__GNUC__)
+#define CLZ(x) __builtin_clzl(x)
+#elif defined(__arm__)
+#define CLZ(x) __clz(x)
+#else
+#define CLZ(x) bcm_count_leading_zeros(x)
+#endif /* __GNUC__ */
+
 /* INTERFACE: Multiword bitmap based small id allocator. */
 struct bcm_mwbmap;     /* forward declaration for use as an opaque mwbmap handle */
 
@@ -945,6 +1081,7 @@ extern void bcm_mwbmap_audit(struct bcm_mwbmap * mwbmap_hdl);
 /* INTERFACE: Simple unique 16bit Id Allocator using a stack implementation. */
 
 #define ID16_INVALID                ((uint16)(~0))
+#define ID16_UNDEFINED              (ID16_INVALID)
 
 /*
  * Construct a 16bit id allocator, managing 16bit ids in the range:
@@ -968,7 +1105,6 @@ extern uint32 id16_map_failures(void * id16_map_hndl);
 /* Audit the 16bit id allocator state. */
 extern bool id16_map_audit(void * id16_map_hndl);
 /* End - Simple 16bit Id Allocator. */
-
 #endif /* BCMDRIVER */
 
 extern void bcm_uint64_right_shift(uint32* r, uint32 a_high, uint32 a_low, uint32 b);
@@ -1153,4 +1289,16 @@ typedef struct _counter_tbl_t {
 void counter_printlog(counter_tbl_t *ctr_tbl);
 #endif /* DEBUG_COUNTER */
 
+/* Given a number 'n' returns 'm' that is next larger power of 2 after n */
+static INLINE uint32 next_larger_power2(uint32 num)
+{
+       num--;
+       num |= (num >> 1);
+       num |= (num >> 2);
+       num |= (num >> 4);
+       num |= (num >> 8);
+       num |= (num >> 16);
+       return (num + 1);
+}
+
 #endif /* _bcmutils_h_ */