net: wifi: rockchip: update broadcom drivers for kernel4.4
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rkwifi / bcmdhd / bcmutils.c
index aafa451469ba191a5196ad67d91ad85a1e3ca322..74b03ddbfba4e776cce6eaf84138a7e3a4a75073 100755 (executable)
@@ -1,8 +1,30 @@
 /*
  * Driver O/S-independent utility routines
  *
- * $Copyright Open Broadcom Corporation$
- * $Id: bcmutils.c 496061 2014-08-11 06:14:48Z $
+ * 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.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: bcmutils.c 591286 2015-10-07 11:59:26Z $
  */
 
 #include <bcm_cfg.h>
 void *_bcmutils_dummy_fn = NULL;
 
 
-#ifdef CUSTOM_DSCP_TO_PRIO_MAPPING
-#define CUST_IPV4_TOS_PREC_MASK 0x3F
-#define DCSP_MAX_VALUE 64
-/* 0:BE,1:BK,2:RESV(BK):,3:EE,:4:CL,5:VI,6:VO,7:NC */
-int dscp2priomap[DCSP_MAX_VALUE]=
-{
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, /* BK->BE */
-       2, 0, 0, 0, 0, 0, 0, 0,
-       3, 0, 0, 0, 0, 0, 0, 0,
-       4, 0, 0, 0, 0, 0, 0, 0,
-       5, 0, 0, 0, 0, 0, 0, 0,
-       6, 0, 0, 0, 0, 0, 0, 0,
-       7, 0, 0, 0, 0, 0, 0, 0
-};
-#endif /* CUSTOM_DSCP_TO_PRIO_MAPPING */
 
 
 #ifdef BCMDRIVER
@@ -792,6 +798,11 @@ pktsetprio(void *pkt, bool update_vtag)
                        evh->vlan_tag = hton16(vlan_tag);
                        rc |= PKTPRIO_UPD;
                }
+#ifdef DHD_LOSSLESS_ROAMING
+       } else if (eh->ether_type == hton16(ETHER_TYPE_802_1X)) {
+               priority = PRIO_8021D_NC;
+               rc = PKTPRIO_DSCP;
+#endif /* DHD_LOSSLESS_ROAMING */
        } else if ((eh->ether_type == hton16(ETHER_TYPE_IP)) ||
                (eh->ether_type == hton16(ETHER_TYPE_IPV6))) {
                uint8 *ip_body = pktdata + sizeof(struct ether_header);
@@ -815,12 +826,7 @@ pktsetprio(void *pkt, bool update_vtag)
                        priority = PRIO_8021D_EE;
                        break;
                default:
-#ifndef CUSTOM_DSCP_TO_PRIO_MAPPING
                        priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
-#else
-                       priority = (int)dscp2priomap[((tos_tc >> IPV4_TOS_DSCP_SHIFT)
-                               & CUST_IPV4_TOS_PREC_MASK)];
-#endif
                        break;
                }
 
@@ -832,6 +838,51 @@ pktsetprio(void *pkt, bool update_vtag)
        return (rc | priority);
 }
 
+/* lookup user priority for specified DSCP */
+static uint8
+dscp2up(uint8 *up_table, uint8 dscp)
+{
+       uint8 user_priority = 255;
+
+       /* lookup up from table if parameters valid */
+       if (up_table != NULL && dscp < UP_TABLE_MAX) {
+               user_priority = up_table[dscp];
+       }
+
+       /* 255 is unused value so return up from dscp */
+       if (user_priority == 255) {
+               user_priority = dscp >> (IPV4_TOS_PREC_SHIFT - IPV4_TOS_DSCP_SHIFT);
+       }
+
+       return user_priority;
+}
+
+/* set user priority by QoS Map Set table (UP table), table size is UP_TABLE_MAX */
+uint BCMFASTPATH
+pktsetprio_qms(void *pkt, uint8* up_table, bool update_vtag)
+{
+       if (up_table) {
+               uint8 *pktdata;
+               uint pktlen;
+               uint8 dscp;
+               uint user_priority = 0;
+               uint rc = 0;
+
+               pktdata = (uint8 *)PKTDATA(OSH_NULL, pkt);
+               pktlen = PKTLEN(OSH_NULL, pkt);
+
+               if (pktgetdscp(pktdata, pktlen, &dscp)) {
+                       rc = PKTPRIO_DSCP;
+                       user_priority = dscp2up(up_table, dscp);
+                       PKTSETPRIO(pkt, user_priority);
+               }
+
+               return (rc | user_priority);
+       } else {
+               return pktsetprio(pkt, update_vtag);
+       }
+}
+
 /* Returns TRUE and DSCP if IP header found, FALSE otherwise.
  */
 bool BCMFASTPATH
@@ -868,6 +919,23 @@ pktgetdscp(uint8 *pktdata, uint pktlen, uint8 *dscp)
        return rc;
 }
 
+/* Add to adjust the 802.1x priority */
+void
+pktset8021xprio(void *pkt, int prio)
+{
+       struct ether_header *eh;
+       uint8 *pktdata;
+       if(prio == PKTPRIO(pkt))
+               return;
+       pktdata = (uint8 *)PKTDATA(OSH_NULL, pkt);
+       ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
+       eh = (struct ether_header *) pktdata;
+       if (eh->ether_type == hton16(ETHER_TYPE_802_1X)) {
+               ASSERT(prio >= 0 && prio <= MAXPRIO);
+               PKTSETPRIO(pkt, prio);
+       }
+}
+
 /* The 0.5KB string table is not removed by compiler even though it's unused */
 
 static char bcm_undeferrstr[32];
@@ -966,6 +1034,415 @@ bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
 
 #endif /* BCMDRIVER */
 
+#ifdef BCM_OBJECT_TRACE
+
+#define BCM_OBJECT_MERGE_SAME_OBJ      0
+
+/* some place may add / remove the object to trace list for Linux: */
+/* add:    osl_alloc_skb dev_alloc_skb skb_realloc_headroom dhd_start_xmit */
+/* remove: osl_pktfree dev_kfree_skb netif_rx */
+
+#define BCM_OBJDBG_COUNT          (1024 * 100)
+static spinlock_t dbgobj_lock;
+#define        BCM_OBJDBG_LOCK_INIT()    spin_lock_init(&dbgobj_lock)
+#define        BCM_OBJDBG_LOCK_DESTROY()
+#define        BCM_OBJDBG_LOCK           spin_lock_irqsave
+#define        BCM_OBJDBG_UNLOCK         spin_unlock_irqrestore
+
+#define BCM_OBJDBG_ADDTOHEAD      0
+#define BCM_OBJDBG_ADDTOTAIL      1
+
+#define BCM_OBJDBG_CALLER_LEN     32
+struct bcm_dbgobj {
+       struct bcm_dbgobj *prior;
+       struct bcm_dbgobj *next;
+       uint32 flag;
+       void   *obj;
+       uint32 obj_sn;
+       uint32 obj_state;
+       uint32 line;
+       char   caller[BCM_OBJDBG_CALLER_LEN];
+};
+
+static struct bcm_dbgobj *dbgobj_freehead = NULL;
+static struct bcm_dbgobj *dbgobj_freetail = NULL;
+static struct bcm_dbgobj *dbgobj_objhead = NULL;
+static struct bcm_dbgobj *dbgobj_objtail = NULL;
+
+static uint32 dbgobj_sn = 0;
+static int dbgobj_count = 0;
+static struct bcm_dbgobj bcm_dbg_objs[BCM_OBJDBG_COUNT];
+
+void
+bcm_object_trace_init(void)
+{
+       int i = 0;
+       BCM_OBJDBG_LOCK_INIT();
+       memset(&bcm_dbg_objs, 0x00, sizeof(struct bcm_dbgobj) * BCM_OBJDBG_COUNT);
+       dbgobj_freehead = &bcm_dbg_objs[0];
+       dbgobj_freetail = &bcm_dbg_objs[BCM_OBJDBG_COUNT - 1];
+
+       for (i = 0; i < BCM_OBJDBG_COUNT; ++i) {
+               bcm_dbg_objs[i].next = (i == (BCM_OBJDBG_COUNT - 1)) ?
+                       dbgobj_freehead : &bcm_dbg_objs[i + 1];
+               bcm_dbg_objs[i].prior = (i == 0) ?
+                       dbgobj_freetail : &bcm_dbg_objs[i - 1];
+       }
+}
+
+void
+bcm_object_trace_deinit(void)
+{
+       if (dbgobj_objhead || dbgobj_objtail) {
+               printf("%s: not all objects are released\n", __FUNCTION__);
+               ASSERT(0);
+       }
+       BCM_OBJDBG_LOCK_DESTROY();
+}
+
+static void
+bcm_object_rm_list(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+       struct bcm_dbgobj *dbgobj)
+{
+       if ((dbgobj == *head) && (dbgobj == *tail)) {
+               *head = NULL;
+               *tail = NULL;
+       } else if (dbgobj == *head) {
+               *head = (*head)->next;
+       } else if (dbgobj == *tail) {
+               *tail = (*tail)->prior;
+       }
+       dbgobj->next->prior = dbgobj->prior;
+       dbgobj->prior->next = dbgobj->next;
+}
+
+static void
+bcm_object_add_list(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+       struct bcm_dbgobj *dbgobj, int addtotail)
+{
+       if (!(*head) && !(*tail)) {
+               *head = dbgobj;
+               *tail = dbgobj;
+               dbgobj->next = dbgobj;
+               dbgobj->prior = dbgobj;
+       } else if ((*head) && (*tail)) {
+               (*tail)->next = dbgobj;
+               (*head)->prior = dbgobj;
+               dbgobj->next = *head;
+               dbgobj->prior = *tail;
+               if (addtotail == BCM_OBJDBG_ADDTOTAIL)
+                       *tail = dbgobj;
+               else
+                       *head = dbgobj;
+       } else {
+               ASSERT(0); /* can't be this case */
+       }
+}
+
+static INLINE void
+bcm_object_movetoend(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+       struct bcm_dbgobj *dbgobj, int movetotail)
+{
+       if ((*head) && (*tail)) {
+               if (movetotail == BCM_OBJDBG_ADDTOTAIL) {
+                       if (dbgobj != (*tail)) {
+                               bcm_object_rm_list(head, tail, dbgobj);
+                               bcm_object_add_list(head, tail, dbgobj, movetotail);
+                       }
+               } else {
+                       if (dbgobj != (*head)) {
+                               bcm_object_rm_list(head, tail, dbgobj);
+                               bcm_object_add_list(head, tail, dbgobj, movetotail);
+                       }
+               }
+       } else {
+               ASSERT(0); /* can't be this case */
+       }
+}
+
+void
+bcm_object_trace_opr(void *obj, uint32 opt, const char *caller, int line)
+{
+       struct bcm_dbgobj *dbgobj;
+       unsigned long flags;
+
+       BCM_REFERENCE(flags);
+       BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+       if (opt == BCM_OBJDBG_ADD_PKT ||
+               opt == BCM_OBJDBG_ADD) {
+               dbgobj = dbgobj_objtail;
+               while (dbgobj) {
+                       if (dbgobj->obj == obj) {
+                               printf("%s: obj %p allocated from %s(%d),"
+                                       " allocate again from %s(%d)\n",
+                                       __FUNCTION__, dbgobj->obj,
+                                       dbgobj->caller, dbgobj->line,
+                                       caller, line);
+                               ASSERT(0);
+                               goto EXIT;
+                       }
+                       dbgobj = dbgobj->prior;
+                       if (dbgobj == dbgobj_objtail)
+                               break;
+               }
+
+#if BCM_OBJECT_MERGE_SAME_OBJ
+               dbgobj = dbgobj_freetail;
+               while (dbgobj) {
+                       if (dbgobj->obj == obj) {
+                               goto FREED_ENTRY_FOUND;
+                       }
+                       dbgobj = dbgobj->prior;
+                       if (dbgobj == dbgobj_freetail)
+                               break;
+               }
+#endif /* BCM_OBJECT_MERGE_SAME_OBJ */
+
+               dbgobj = dbgobj_freehead;
+#if BCM_OBJECT_MERGE_SAME_OBJ
+FREED_ENTRY_FOUND:
+#endif /* BCM_OBJECT_MERGE_SAME_OBJ */
+               if (!dbgobj) {
+                       printf("%s: already got %d objects ?????????????????????\n",
+                               __FUNCTION__, BCM_OBJDBG_COUNT);
+                       ASSERT(0);
+                       goto EXIT;
+               }
+
+               bcm_object_rm_list(&dbgobj_freehead, &dbgobj_freetail, dbgobj);
+               dbgobj->obj = obj;
+               strncpy(dbgobj->caller, caller, BCM_OBJDBG_CALLER_LEN);
+               dbgobj->caller[BCM_OBJDBG_CALLER_LEN-1] = '\0';
+               dbgobj->line = line;
+               dbgobj->flag = 0;
+               if (opt == BCM_OBJDBG_ADD_PKT) {
+                       dbgobj->obj_sn = dbgobj_sn++;
+                       dbgobj->obj_state = 0;
+                       /* first 4 bytes is pkt sn */
+                       if (((unsigned long)PKTTAG(obj)) & 0x3)
+                               printf("pkt tag address not aligned by 4: %p\n", PKTTAG(obj));
+                       *(uint32*)PKTTAG(obj) = dbgobj->obj_sn;
+               }
+               bcm_object_add_list(&dbgobj_objhead, &dbgobj_objtail, dbgobj,
+                       BCM_OBJDBG_ADDTOTAIL);
+
+               dbgobj_count++;
+
+       } else if (opt == BCM_OBJDBG_REMOVE) {
+               dbgobj = dbgobj_objtail;
+               while (dbgobj) {
+                       if (dbgobj->obj == obj) {
+                               if (dbgobj->flag) {
+                                       printf("%s: rm flagged obj %p flag 0x%08x from %s(%d)\n",
+                                               __FUNCTION__, obj, dbgobj->flag, caller, line);
+                               }
+                               bcm_object_rm_list(&dbgobj_objhead, &dbgobj_objtail, dbgobj);
+                               memset(dbgobj->caller, 0x00, BCM_OBJDBG_CALLER_LEN);
+                               strncpy(dbgobj->caller, caller, BCM_OBJDBG_CALLER_LEN);
+                               dbgobj->caller[BCM_OBJDBG_CALLER_LEN-1] = '\0';
+                               dbgobj->line = line;
+                               bcm_object_add_list(&dbgobj_freehead, &dbgobj_freetail, dbgobj,
+                                       BCM_OBJDBG_ADDTOTAIL);
+                               dbgobj_count--;
+                               goto EXIT;
+                       }
+                       dbgobj = dbgobj->prior;
+                       if (dbgobj == dbgobj_objtail)
+                               break;
+               }
+
+               dbgobj = dbgobj_freetail;
+               while (dbgobj && dbgobj->obj) {
+                       if (dbgobj->obj == obj) {
+                               printf("%s: obj %p already freed from from %s(%d),"
+                                       " try free again from %s(%d)\n",
+                                       __FUNCTION__, obj,
+                                       dbgobj->caller, dbgobj->line,
+                                       caller, line);
+                               //ASSERT(0); /* release same obj more than one time? */
+                               goto EXIT;
+                       }
+                       dbgobj = dbgobj->prior;
+                       if (dbgobj == dbgobj_freetail)
+                               break;
+               }
+
+               printf("%s: ################### release none-existing obj %p from %s(%d)\n",
+                       __FUNCTION__, obj, caller, line);
+               //ASSERT(0); /* release same obj more than one time? */
+
+       }
+
+EXIT:
+       BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+       return;
+}
+
+void
+bcm_object_trace_upd(void *obj, void *obj_new)
+{
+       struct bcm_dbgobj *dbgobj;
+       unsigned long flags;
+
+       BCM_REFERENCE(flags);
+       BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+       dbgobj = dbgobj_objtail;
+       while (dbgobj) {
+               if (dbgobj->obj == obj) {
+                       dbgobj->obj = obj_new;
+                       if (dbgobj != dbgobj_objtail) {
+                               bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+                                       dbgobj, BCM_OBJDBG_ADDTOTAIL);
+                       }
+                       goto EXIT;
+               }
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_objtail)
+                       break;
+       }
+
+EXIT:
+       BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+       return;
+}
+
+void
+bcm_object_trace_chk(void *obj, uint32 chksn, uint32 sn,
+       const char *caller, int line)
+{
+       struct bcm_dbgobj *dbgobj;
+       unsigned long flags;
+
+       BCM_REFERENCE(flags);
+       BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+       dbgobj = dbgobj_objtail;
+       while (dbgobj) {
+               if ((dbgobj->obj == obj) &&
+                       ((!chksn) || (dbgobj->obj_sn == sn))) {
+                       if (dbgobj != dbgobj_objtail) {
+                               bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+                                       dbgobj, BCM_OBJDBG_ADDTOTAIL);
+                       }
+                       goto EXIT;
+               }
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_objtail)
+                       break;
+       }
+
+       dbgobj = dbgobj_freetail;
+       while (dbgobj) {
+               if ((dbgobj->obj == obj) &&
+                       ((!chksn) || (dbgobj->obj_sn == sn))) {
+                       printf("%s: (%s:%d) obj %p (sn %d state %d) was freed from %s(%d)\n",
+                               __FUNCTION__, caller, line,
+                               dbgobj->obj, dbgobj->obj_sn, dbgobj->obj_state,
+                               dbgobj->caller, dbgobj->line);
+                       goto EXIT;
+               }
+               else if (dbgobj->obj == NULL) {
+                       break;
+               }
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_freetail)
+                       break;
+       }
+
+       printf("%s: obj %p not found, check from %s(%d), chksn %s, sn %d\n",
+               __FUNCTION__, obj, caller, line, chksn ? "yes" : "no", sn);
+       dbgobj = dbgobj_objtail;
+       while (dbgobj) {
+               printf("%s: (%s:%d) obj %p sn %d was allocated from %s(%d)\n",
+                               __FUNCTION__, caller, line,
+                               dbgobj->obj, dbgobj->obj_sn, dbgobj->caller, dbgobj->line);
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_objtail)
+                       break;
+       }
+
+EXIT:
+       BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+       return;
+}
+
+void
+bcm_object_feature_set(void *obj, uint32 type, uint32 value)
+{
+       struct bcm_dbgobj *dbgobj;
+       unsigned long flags;
+
+       BCM_REFERENCE(flags);
+       BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+       dbgobj = dbgobj_objtail;
+       while (dbgobj) {
+               if (dbgobj->obj == obj) {
+                       if (type == BCM_OBJECT_FEATURE_FLAG) {
+                               if (value & BCM_OBJECT_FEATURE_CLEAR)
+                                       dbgobj->flag &= ~(value);
+                               else
+                                       dbgobj->flag |= (value);
+                       } else if (type == BCM_OBJECT_FEATURE_PKT_STATE) {
+                               dbgobj->obj_state = value;
+                       }
+                       if (dbgobj != dbgobj_objtail) {
+                               bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+                                       dbgobj, BCM_OBJDBG_ADDTOTAIL);
+                       }
+                       goto EXIT;
+               }
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_objtail)
+                       break;
+       }
+
+       printf("%s: obj %p not found in active list\n", __FUNCTION__, obj);
+       ASSERT(0);
+
+EXIT:
+       BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+       return;
+}
+
+int
+bcm_object_feature_get(void *obj, uint32 type, uint32 value)
+{
+       int rtn = 0;
+       struct bcm_dbgobj *dbgobj;
+       unsigned long flags;
+
+       BCM_REFERENCE(flags);
+       BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+       dbgobj = dbgobj_objtail;
+       while (dbgobj) {
+               if (dbgobj->obj == obj) {
+                       if (type == BCM_OBJECT_FEATURE_FLAG) {
+                               rtn = (dbgobj->flag & value) & (~BCM_OBJECT_FEATURE_CLEAR);
+                       }
+                       if (dbgobj != dbgobj_objtail) {
+                               bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+                                       dbgobj, BCM_OBJDBG_ADDTOTAIL);
+                       }
+                       goto EXIT;
+               }
+               dbgobj = dbgobj->prior;
+               if (dbgobj == dbgobj_objtail)
+                       break;
+       }
+
+       printf("%s: obj %p not found in active list\n", __FUNCTION__, obj);
+       ASSERT(0);
+
+EXIT:
+       BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+       return rtn;
+}
+
+#endif /* BCM_OBJECT_TRACE */
 
 uint8 *
 bcm_write_tlv(int type, const void *data, int datalen, uint8 *dst)
@@ -1375,7 +1852,9 @@ bcm_parse_tlvs(void *buf, int buflen, uint key)
        bcm_tlv_t *elt;
        int totlen;
 
-       elt = (bcm_tlv_t*)buf;
+       if ((elt = (bcm_tlv_t*)buf) == NULL) {
+               return NULL;
+       }
        totlen = buflen;
 
        /* find tagged parameter */
@@ -1519,8 +1998,6 @@ bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len)
 
        /* indicate the str was too short */
        if (flags != 0) {
-               if (len < 2)
-                       p -= 2 - len;   /* overwrite last char */
                p += snprintf(p, 2, ">");
        }
 
@@ -1558,7 +2035,7 @@ prhex(const char *msg, uchar *buf, uint nbytes)
        p = line;
        for (i = 0; i < nbytes; i++) {
                if (i % 16 == 0) {
-                       nchar = snprintf(p, len, "  %04d: ", i);        /* line prefix */
+                       nchar = snprintf(p, len, "  %04x: ", i);        /* line prefix */
                        p += nchar;
                        len -= nchar;
                }
@@ -1588,18 +2065,11 @@ static const char *crypto_algo_names[] = {
        "AES_CCM",
        "AES_OCB_MSDU",
        "AES_OCB_MPDU",
-#ifdef BCMCCX
-       "CKIP",
-       "CKIP_MMH",
-       "WEP_MMH",
-       "NALG",
-#else
        "NALG",
        "UNDEF",
        "UNDEF",
        "UNDEF",
-#endif /* BCMCCX */
-       "WAPI",
+       "UNDEF"
        "PMK",
        "BIP",
        "AES_GCM",
@@ -1696,7 +2166,7 @@ bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc
 }
 
 uint
-bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+bcm_mkiovar(const char *name, char *data, uint datalen, char *buf, uint buflen)
 {
        uint len;
 
@@ -1815,7 +2285,10 @@ bcm_bitcount(uint8 *bitmap, uint length)
        return bitcount;
 }
 
-#ifdef BCMDRIVER
+#if defined(BCMDRIVER) || defined(WL_UNITTEST)
+
+/* triggers bcm_bprintf to print to kernel log */
+bool bcm_bprintf_bypass = FALSE;
 
 /* Initialization of bcmstrbuf structure */
 void
@@ -1835,6 +2308,10 @@ bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
        va_start(ap, fmt);
 
        r = vsnprintf(b->buf, b->size, fmt, ap);
+       if (bcm_bprintf_bypass == TRUE) {
+               printf(b->buf);
+               goto exit;
+       }
 
        /* Non Ansi C99 compliant returns -1,
         * Ansi compliant return r >= b->size,
@@ -1850,13 +2327,14 @@ bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
                b->buf += r;
        }
 
+exit:
        va_end(ap);
 
        return r;
 }
 
 void
-bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len)
+bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, const uint8 *buf, int len)
 {
        int i;
 
@@ -1974,7 +2452,7 @@ bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len)
 }
 #endif 
 
-#endif /* BCMDRIVER */
+#endif /* BCMDRIVER || WL_UNITTEST */
 
 /*
  * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file and ending in a NUL.
@@ -2162,11 +2640,11 @@ set_bitrange(void *array, uint start, uint end, uint maxbit)
 }
 
 void
-bcm_bitprint32(const uint32 u32)
+bcm_bitprint32(const uint32 u32arg)
 {
        int i;
        for (i = NBITS(uint32) - 1; i >= 0; i--) {
-               isbitset(u32, i) ? printf("1") : printf("0");
+               isbitset(u32arg, i) ? printf("1") : printf("0");
                if ((i % NBBY) == 0) printf(" ");
        }
        printf("\n");
@@ -2192,8 +2670,7 @@ bcm_ip_cksum(uint8 *buf, uint32 len, uint32 sum)
 
        return ((uint16)~sum);
 }
-
-#ifdef BCMDRIVER
+#if defined(BCMDRIVER) && !defined(_CFEZ_)
 /*
  * Hierarchical Multiword bitmap based small id allocator.
  *
@@ -2225,7 +2702,7 @@ bcm_ip_cksum(uint8 *buf, uint32 len, uint32 sum)
  * with savings in not having to use an indirect access, had it been dynamically
  * allocated.
  */
-#define BCM_MWBMAP_ITEMS_MAX    (4 * 1024)  /* May increase to 16K */
+#define BCM_MWBMAP_ITEMS_MAX    (64 * 1024)  /* May increase to 64K */
 
 #define BCM_MWBMAP_BITS_WORD    (NBITS(uint32))
 #define BCM_MWBMAP_WORDS_MAX    (BCM_MWBMAP_ITEMS_MAX / BCM_MWBMAP_BITS_WORD)
@@ -2258,7 +2735,7 @@ bcm_ip_cksum(uint8 *buf, uint32 len, uint32 sum)
 typedef struct bcm_mwbmap {     /* Hierarchical multiword bitmap allocator    */
        uint16 wmaps;               /* Total number of words in free wd bitmap    */
        uint16 imaps;               /* Total number of words in free id bitmap    */
-       int16  ifree;               /* Count of free indices. Used only in audits */
+       int32  ifree;               /* Count of free indices. Used only in audits */
        uint16 total;               /* Total indices managed by multiword bitmap  */
 
        void * magic;               /* Audit handle parameter from user           */
@@ -2302,7 +2779,7 @@ bcm_mwbmap_init(osl_t *osh, uint32 items_max)
 
        /* Initialize runtime multiword bitmap state */
        mwbmap_p->imaps = (uint16)words;
-       mwbmap_p->ifree = (int16)items_max;
+       mwbmap_p->ifree = (int32)items_max;
        mwbmap_p->total = (uint16)items_max;
 
        /* Setup magic, for use in audit of handle */
@@ -2655,10 +3132,10 @@ bcm_mwbmap_audit(struct bcm_mwbmap * mwbmap_hdl)
 
 /* Simple 16bit Id allocator using a stack implementation. */
 typedef struct id16_map {
-       uint16  total;     /* total number of ids managed by allocator */
-       uint16  start;     /* start value of 16bit ids to be managed */
        uint32  failures;  /* count of failures */
        void    *dbg;      /* debug placeholder */
+       uint16  total;     /* total number of ids managed by allocator */
+       uint16  start;     /* start value of 16bit ids to be managed */
        int     stack_idx; /* index into stack of available ids */
        uint16  stack[0];  /* stack of 16 bit ids */
 } id16_map_t;
@@ -2689,7 +3166,12 @@ id16_map_init(osl_t *osh, uint16 total_ids, uint16 start_val16)
        id16_map_t * id16_map;
 
        ASSERT(total_ids > 0);
-       ASSERT((start_val16 + total_ids) < ID16_INVALID);
+
+       /* A start_val16 of ID16_UNDEFINED, allows the caller to fill the id16 map
+        * with random values.
+        */
+       ASSERT((start_val16 == ID16_UNDEFINED) ||
+              (start_val16 + total_ids) < ID16_INVALID);
 
        id16_map = (id16_map_t *) MALLOC(osh, ID16_MAP_SZ(total_ids));
        if (id16_map == NULL) {
@@ -2701,24 +3183,32 @@ id16_map_init(osl_t *osh, uint16 total_ids, uint16 start_val16)
        id16_map->failures = 0;
        id16_map->dbg = NULL;
 
-       /* Populate stack with 16bit id values, commencing with start_val16 */
-       id16_map->stack_idx = 0;
-       val16 = start_val16;
+       /*
+        * Populate stack with 16bit id values, commencing with start_val16.
+        * if start_val16 is ID16_UNDEFINED, then do not populate the id16 map.
+        */
+       id16_map->stack_idx = -1;
+
+       if (id16_map->start != ID16_UNDEFINED) {
+               val16 = start_val16;
 
-       for (idx = 0; idx < total_ids; idx++, val16++) {
-               id16_map->stack_idx = idx;
-               id16_map->stack[id16_map->stack_idx] = val16;
+               for (idx = 0; idx < total_ids; idx++, val16++) {
+                       id16_map->stack_idx = idx;
+                       id16_map->stack[id16_map->stack_idx] = val16;
+               }
        }
 
 #if defined(BCM_DBG) && defined(BCM_DBG_ID16)
-       id16_map->dbg = MALLOC(osh, ID16_MAP_DBG_SZ(total_ids));
+       if (id16_map->start != ID16_UNDEFINED) {
+               id16_map->dbg = MALLOC(osh, ID16_MAP_DBG_SZ(total_ids));
 
-       if (id16_map->dbg) {
-               id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+               if (id16_map->dbg) {
+                       id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
 
-               id16_map_dbg->total = total_ids;
-               for (idx = 0; idx < total_ids; idx++) {
-                       id16_map_dbg->avail[idx] = TRUE;
+                       id16_map_dbg->total = total_ids;
+                       for (idx = 0; idx < total_ids; idx++) {
+                               id16_map_dbg->avail[idx] = TRUE;
+                       }
                }
        }
 #endif /* BCM_DBG && BCM_DBG_ID16 */
@@ -2760,7 +3250,11 @@ id16_map_clear(void * id16_map_hndl, uint16 total_ids, uint16 start_val16)
        id16_map_t * id16_map;
 
        ASSERT(total_ids > 0);
-       ASSERT((start_val16 + total_ids) < ID16_INVALID);
+       /* A start_val16 of ID16_UNDEFINED, allows the caller to fill the id16 map
+        * with random values.
+        */
+       ASSERT((start_val16 == ID16_UNDEFINED) ||
+              (start_val16 + total_ids) < ID16_INVALID);
 
        id16_map = (id16_map_t *)id16_map_hndl;
        if (id16_map == NULL) {
@@ -2772,21 +3266,26 @@ id16_map_clear(void * id16_map_hndl, uint16 total_ids, uint16 start_val16)
        id16_map->failures = 0;
 
        /* Populate stack with 16bit id values, commencing with start_val16 */
-       id16_map->stack_idx = 0;
-       val16 = start_val16;
+       id16_map->stack_idx = -1;
 
-       for (idx = 0; idx < total_ids; idx++, val16++) {
-               id16_map->stack_idx = idx;
-               id16_map->stack[id16_map->stack_idx] = val16;
+       if (id16_map->start != ID16_UNDEFINED) {
+               val16 = start_val16;
+
+               for (idx = 0; idx < total_ids; idx++, val16++) {
+                       id16_map->stack_idx = idx;
+                       id16_map->stack[id16_map->stack_idx] = val16;
+               }
        }
 
 #if defined(BCM_DBG) && defined(BCM_DBG_ID16)
-       if (id16_map->dbg) {
-               id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+       if (id16_map->start != ID16_UNDEFINED) {
+               if (id16_map->dbg) {
+                       id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
 
-               id16_map_dbg->total = total_ids;
-               for (idx = 0; idx < total_ids; idx++) {
-                       id16_map_dbg->avail[idx] = TRUE;
+                       id16_map_dbg->total = total_ids;
+                       for (idx = 0; idx < total_ids; idx++) {
+                               id16_map_dbg->avail[idx] = TRUE;
+                       }
                }
        }
 #endif /* BCM_DBG && BCM_DBG_ID16 */
@@ -2813,8 +3312,8 @@ id16_map_alloc(void * id16_map_hndl)
        id16_map->stack_idx--;
 
 #if defined(BCM_DBG) && defined(BCM_DBG_ID16)
-
-       ASSERT(val16 < (id16_map->start + id16_map->total));
+       ASSERT((id16_map->start == ID16_UNDEFINED) ||
+              (val16 < (id16_map->start + id16_map->total)));
 
        if (id16_map->dbg) { /* Validate val16 */
                id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
@@ -2838,8 +3337,8 @@ id16_map_free(void * id16_map_hndl, uint16 val16)
        id16_map = (id16_map_t *)id16_map_hndl;
 
 #if defined(BCM_DBG) && defined(BCM_DBG_ID16)
-
-       ASSERT(val16 < (id16_map->start + id16_map->total));
+       ASSERT((id16_map->start == ID16_UNDEFINED) ||
+              (val16 < (id16_map->start + id16_map->total)));
 
        if (id16_map->dbg) { /* Validate val16 */
                id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
@@ -2871,7 +3370,12 @@ id16_map_audit(void * id16_map_hndl)
 
        id16_map = (id16_map_t *)id16_map_hndl;
 
-       ASSERT((id16_map->stack_idx > 0) && (id16_map->stack_idx < id16_map->total));
+       ASSERT(id16_map->stack_idx >= -1);
+       ASSERT(id16_map->stack_idx < (int)id16_map->total);
+
+       if (id16_map->start == ID16_UNDEFINED)
+               goto done;
+
        for (idx = 0; idx <= id16_map->stack_idx; idx++) {
                ASSERT(id16_map->stack[idx] >= id16_map->start);
                ASSERT(id16_map->stack[idx] < (id16_map->start + id16_map->total));
@@ -2882,7 +3386,7 @@ id16_map_audit(void * id16_map_hndl)
                        if (((id16_map_dbg_t *)(id16_map->dbg))->avail[val16] != TRUE) {
                                insane |= 1;
                                ID16_MAP_MSG(("id16_map<%p>: stack_idx %u invalid val16 %u\n",
-                                             id16_map_hndl, idx, val16));
+                                       id16_map_hndl, idx, val16));
                        }
                }
 #endif /* BCM_DBG && BCM_DBG_ID16 */
@@ -2898,17 +3402,19 @@ id16_map_audit(void * id16_map_hndl)
                if (avail && (avail != (id16_map->stack_idx + 1))) {
                        insane |= 1;
                        ID16_MAP_MSG(("id16_map<%p>: avail %u stack_idx %u\n",
-                                     id16_map_hndl, avail, id16_map->stack_idx));
+                               id16_map_hndl, avail, id16_map->stack_idx));
                }
        }
 #endif /* BCM_DBG && BCM_DBG_ID16 */
 
+done:
+       /* invoke any other system audits */
        return (!!insane);
 }
 /* END: Simple id16 allocator */
 
 
-#endif /* BCMDRIVER */
+#endif 
 
 /* calculate a >> b; and returns only lower 32 bits */
 void
@@ -2987,7 +3493,7 @@ void counter_printlog(counter_tbl_t *ctr_tbl)
 #endif /* OSL_SYSUPTIME_SUPPORT == TRUE */
 #endif /* DEBUG_COUNTER */
 
-#ifdef BCMDRIVER
+#if defined(BCMDRIVER) && !defined(_CFEZ_)
 void
 dll_pool_detach(void * osh, dll_pool_t * pool, uint16 elems_max, uint16 elem_size)
 {
@@ -3007,15 +3513,13 @@ dll_pool_init(void * osh, uint16 elems_max, uint16 elem_size)
 
        mem_size = sizeof(dll_pool_t) + (elems_max * elem_size);
 
-       if ((dll_pool_p = (dll_pool_t *)MALLOC(osh, mem_size)) == NULL) {
+       if ((dll_pool_p = (dll_pool_t *)MALLOCZ(osh, mem_size)) == NULL) {
                printf("dll_pool_init: elems_max<%u> elem_size<%u> malloc failure\n",
                        elems_max, elem_size);
                ASSERT(0);
                return dll_pool_p;
        }
 
-       bzero(dll_pool_p, mem_size);
-
        dll_init(&dll_pool_p->free_list);
        dll_pool_p->elems_max = elems_max;
        dll_pool_p->elem_size = elem_size;
@@ -3066,4 +3570,4 @@ dll_pool_free_tail(dll_pool_t * dll_pool_p, void * elem_p)
        dll_pool_p->free_count += 1;
 }
 
-#endif /* BCMDRIVER */
+#endif