diff --git a/include/linux/bcm_br_fdb.h b/include/linux/bcm_br_fdb.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a86253a753d6196d4507f40daef97aa752ac98c
--- /dev/null
+++ b/include/linux/bcm_br_fdb.h
@@ -0,0 +1,48 @@
+#ifndef _BCM_BR_FDB_H
+#define _BCM_BR_FDB_H
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+int bcm_br_has_fdb_expired(const struct net_bridge *br,
+				  const struct net_bridge_fdb_entry *fdb);
+
+int bcm_br_fdb_notify(struct net_bridge *br,
+		       const struct net_bridge_fdb_entry *fdb, int type,
+		       bool swdev_notify);
+
+int bcm_br_fdb_init(struct net_bridge_fdb_entry *fdb);
+
+int bcm_br_fdb_fill_info(const struct net_bridge_fdb_entry *fdb);
+
+int bcm_br_fdb_update(struct net_bridge_fdb_entry *fdb,
+					struct net_bridge_port *source);
+
+int bcm_br_fdb_cleanup(struct net_bridge_fdb_entry *fdb, 
+                       unsigned long time_now, unsigned long delay);
+#endif
diff --git a/include/linux/bcm_br_mcast.h b/include/linux/bcm_br_mcast.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ef3146d6bb3a0fe9f21a0113fa56cabb52f79dd
--- /dev/null
+++ b/include/linux/bcm_br_mcast.h
@@ -0,0 +1,44 @@
+/*
+*    Copyright (c) 2003-2019 Broadcom
+*    All Rights Reserved
+*
+<:label-BRCM:2019:DUAL/GPL:standard
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+#if (defined(CONFIG_BCM_MCAST) || defined(CONFIG_BCM_MCAST_MODULE))
+
+#ifndef _BCM_BR_MCAST_H
+#define _BCM_BR_MCAST_H
+
+#include <linux/skbuff.h> 
+#include <linux/netdevice.h>
+
+typedef int (*br_bcm_mcast_receive_hook)(int ifindex, struct sk_buff *skb, int is_routed);
+typedef int (*br_bcm_mcast_should_deliver_hook)(int ifindex, struct sk_buff *skb, struct net_device *src_dev, bool dst_mrouter);
+
+int br_bcm_mcast_flood_forward(struct net_device *dev, struct sk_buff *skb);
+int br_bcm_mcast_bind(br_bcm_mcast_receive_hook bcm_rx_hook, br_bcm_mcast_should_deliver_hook bcm_should_deliver_hook);
+
+#endif /* _BCM_BR_MCAST_H */
+#endif
diff --git a/include/linux/bcm_dslcpe_wlan_info.h b/include/linux/bcm_dslcpe_wlan_info.h
new file mode 100755
index 0000000000000000000000000000000000000000..f14fc33aaae8411b854c2864ed1c84a2d73c0df4
--- /dev/null
+++ b/include/linux/bcm_dslcpe_wlan_info.h
@@ -0,0 +1,27 @@
+#ifndef __BCM_DSLCPE_WLAN_INFO_H_
+#define __BCM_DSLCPE_WLAN_INFO_H_
+#if defined(CONFIG_BLOG)
+#include <linux/blog.h>
+#define WLAN_CLIENT_INFO_OK (0)
+#define WLAN_CLIENT_INFO_ERR (-1)
+typedef enum {
+    WLAN_CLIENT_TYPE_CPU,
+    WLAN_CLIENT_TYPE_WFD,
+    WLAN_CLIENT_TYPE_RUNNER,
+    WLAN_CLIENT_TYPE_MAX
+} wlan_client_type_t;
+
+typedef struct  {
+    wlan_client_type_t type;
+    union {
+        uint32_t        wl;
+        BlogWfd_t       wfd;
+        BlogRnr_t       rnr;
+    };
+} wlan_client_info_t;
+
+
+typedef int (* wlan_client_get_info_t)(struct net_device *dev,char *mac_address_p,int priority, wlan_client_info_t *info_p);
+
+#endif /* CONFIG_BLOG */
+#endif /* __BCM_DSLCPE_WLAN_INFO_H_ */
diff --git a/include/linux/bcm_log.h b/include/linux/bcm_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..193376e46c2c0906fcda42dcd3352df918518b52
--- /dev/null
+++ b/include/linux/bcm_log.h
@@ -0,0 +1,313 @@
+/*
+* <:copyright-BRCM:2012:DUAL/GPL:standard
+* 
+*    Copyright (c) 2012 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+:>
+*/
+#ifndef _BCM_LOG_SERVICES_
+#define _BCM_LOG_SERVICES_
+
+#if !defined(__KERNEL__)
+#include <stdint.h>             /**< ISO C99 7.18 Integer Types */
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include <linux/bcm_log_mod.h>
+
+#if !defined(__KERNEL__)
+#define bcm_printk          printf
+#define BUG()               do { } while(0)
+#define EXPORT_SYMBOL(sym)
+#endif
+
+/*********
+ *********
+ * Private:
+ *********
+ *********/
+
+
+#define IN /*Input parameters*/
+#define OUT /*Output parameters*/
+#define INOUT /*Input/Output parameters*/
+
+/*
+ * This block of defines selects supported functionality for everything
+ * that includes bcm_log.h.  Selection of functionality will eventually
+ * be moved to make menuconfig.  CONFIG_BRCM_COLORIZE_PRINTS is already
+ * in make menuconfig, but it is locally disabled here.
+ */
+#ifdef CONFIG_BCM_LOG
+#undef CONFIG_BRCM_COLORIZE_PRINTS
+#define BCM_ASSERT_SUPPORTED
+#define BCM_LOG_SUPPORTED
+#define BCM_DATADUMP_SUPPORTED
+#define BCM_ERROR_SUPPORTED
+#undef BCM_SNAPSHOT_SUPPORTED
+#endif /* CONFIG_BCM_LOG */
+
+#include <linux/bcm_colors.h>
+
+#if defined(BCM_ASSERT_SUPPORTED)
+#define BCM_ASSERTCODE(code)    code
+#else
+#define BCM_ASSERTCODE(code)
+#endif /*defined(BCM_ASSERT_SUPPORTED)*/
+
+#if defined(BCM_LOG_SUPPORTED)
+#define BCM_LOGCODE(code)    code
+#else
+#define BCM_LOGCODE(code)
+#endif /*defined(BCM_LOG_SUPPORTED)*/
+
+#if defined(BCM_ERROR_SUPPORTED)
+#define BCM_ERRORCODE(code)    code
+#else
+#define BCM_ERRORCODE(code)
+#endif /*defined(BCM_ERROR_SUPPORTED)*/
+
+#if defined(BCM_DATADUMP_SUPPORTED)
+#define BCM_DATADUMPCODE(code)    code
+#else
+#define BCM_DATADUMPCODE(code)
+#endif /*defined(BCM_DATADUMP_SUPPORTED)*/
+
+#if defined(BCM_SNAPSHOT_SUPPORTED)
+#define BCM_SNAPSHOTCODE(code)    code
+#else
+#define BCM_SNAPSHOTCODE(code)
+#endif /*defined(BCM_SNAPSHOT_SUPPORTED)*/
+
+typedef enum {
+    BCM_LOG_DD_IMPORTANT=0,
+    BCM_LOG_DD_INFO,
+    BCM_LOG_DD_DETAIL,
+    BCM_LOG_DD_MAX
+} bcmLogDataDumpLevel_t;
+
+typedef void (*bcmLogLevelChangeCallback_t)(bcmLogId_t logId, bcmLogLevel_t level, void *ctx);
+
+typedef struct {
+    bcmLogId_t logId;
+    char *name;
+    bcmLogLevel_t logLevel;
+    bcmLogDataDumpLevel_t ddLevel;
+    bcmLogLevelChangeCallback_t lcCallback;
+    void * lcCallbackCtx;
+} bcmLogModuleInfo_t;
+
+
+/********
+ ********
+ * Public: service API offered by LOGdriver to other drivers
+ ********
+ ********/
+#if defined(__KERNEL__)
+/* This fucntion is same as printk, but is defined always
+ * and should be used in binary only modules to avoid
+ * dependency on CONFIG_PRINTK. It can be used in place of 
+ * regular printk as well.
+ *
+ * All driver should use/define macro based on this function and
+ * should not create new clones. 
+ */
+int bcm_printk(const char *fmt, ...);
+#define bcm_pr_cont(fmt, ...)  bcm_printk(KERN_CONT fmt, ##__VA_ARGS__)
+#define bcm_print(fmt, ...)  bcm_pr_cont(fmt, ##__VA_ARGS__)
+#define bcm_pr_hex_dump_offset(r, g, b, l, a) \
+        print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, r, g, b, l, a)
+#endif
+
+/**
+ * Logging API: Activate by #defining BCM_LOG_SUPPORTED
+ **/
+
+#if defined(BCM_LOG_SUPPORTED)
+bcmLogModuleInfo_t *bcmLog_logIsEnabled(bcmLogId_t logId, bcmLogLevel_t logLevel);
+#endif
+
+#define BCM_LOG_FUNC(logId)                     \
+    BCM_LOG_DEBUG((logId), " ")
+
+#define BCM_LOG_DEBUG(logId, fmt, arg...)                               \
+    BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_DEBUG); \
+                      if (_pModInfo)                                              \
+                          bcm_printk(CLRm "[DBG " "%s" "] %-10s: " fmt CLRnl, \
+                                 _pModInfo->name, __FUNCTION__, ##arg); } while(0) )
+
+#define BCM_LOG_INFO(logId, fmt, arg...)                               \
+    BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_INFO); \
+                      if (_pModInfo)                                              \
+                          bcm_printk(CLRg "[INF " "%s" "] %-10s: " fmt CLRnl, \
+                                 _pModInfo->name, __FUNCTION__, ##arg); } while(0) )
+
+#define BCM_LOG_NOTICE(logId, fmt, arg...)                               \
+    BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_NOTICE); \
+                      if (_pModInfo)                                              \
+                          bcm_printk(CLRb "[NTC " "%s" "] %-10s: " fmt CLRnl, \
+                                 _pModInfo->name, __FUNCTION__, ##arg); } while(0) )
+
+
+/**
+ * Error Reporting API: Activate by #defining BCM_ERROR_SUPPORTED
+ **/
+
+#define BCM_LOG_ERROR(logId, fmt, arg...)                                \
+    BCM_ERRORCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_ERROR); \
+                      if (_pModInfo)                                              \
+                          bcm_printk(CLRerr "[ERROR " "%s" "] %-10s,%d: " fmt CLRnl, \
+                                 _pModInfo->name, __FUNCTION__, __LINE__, ##arg); } while(0) )
+
+
+/**
+ * Assert API: Activate by #defining BCM_ASSERT_SUPPORTED
+ **/
+
+#define BCM_ASSERT(cond)                                         \
+    BCM_ASSERTCODE( if ( !(cond) ) {                                    \
+                        bcm_printk(CLRerr "[ASSERT " "%s" "] %-10s,%d: " #cond CLRnl, \
+                               __FILE__, __FUNCTION__, __LINE__); \
+                        BUG();                                          \
+                     } )
+
+
+/**
+ * Datadump API: Activate by #defining BCM_DATADUMP_SUPPORTED
+ **/
+
+/*
+ * Prototype of datadump print functions.
+ * Note: parse functions must be exported (EXPORT_SYMBOL)
+ */
+typedef int (Bcm_DataDumpPrintFunc)(uint32_t dataDumpId, IN void* dataPtr, uint32_t numDataBytes,
+                                    OUT char* buf, uint32_t bufSize);
+
+#if defined(BCM_DATADUMP_SUPPORTED)
+bcmLogModuleInfo_t *bcmLog_ddIsEnabled(bcmLogId_t logId, bcmLogDataDumpLevel_t ddLevel);
+void bcm_dataDumpRegPrinter(uint32_t qId, uint32_t dataDumpId, Bcm_DataDumpPrintFunc *printFun);
+void bcm_dataDump(uint32_t qID, uint32_t dataDumpID, const char* dataDumpName, void *ptr, uint32_t numBytes);
+uint32_t bcm_dataDumpCreateQ(const char* qName);
+void bcm_dataDumpDeleteQ(uint32_t qid);
+#endif
+
+/*
+ * Create a DataDump queue. Different modules can share a queue.
+ * Returns a queue ID (uint32_t).
+ */
+#define BCM_DATADUMP_CREATE_Q(qName) BCM_DATADUMPCODE(bcm_dataDumpCreateQ(qName))
+
+/*
+ * Delete a DataDump queue.
+ */
+#define BCM_DATADUMP_DELETE_Q(qID) BCM_DATADUMPCODE(bcm_dataDumpDeleteQ(qID))
+
+/*
+ * Dump data
+ */
+#define BCM_DATADUMP_IMPORTANT(logId, qID, dataDumpID, ptr, numBytes) \
+    BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_IMPORTANT); \
+                      if (_pModInfo)                                              \
+                          bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) )
+#define BCM_DATADUMP_INFO(logId, qID, dataDumpID, ptr, numBytes) \
+    BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_INFO); \
+                      if (_pModInfo)                                              \
+                          bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) )
+#define BCM_DATADUMP_DETAIL(logId, qID, dataDumpID, ptr, numBytes) \
+    BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_DETAIL); \
+                      if (_pModInfo)                                              \
+                          bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) )
+#define BCM_DATADUMP_MAX(logId, qID, dataDumpID, ptr, numBytes) \
+    BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_MAX); \
+                      if (_pModInfo)                                              \
+                          bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) )
+
+/*
+ * Register a printer for a certain DataDump ID.
+ * Datadumps for which no printer is registered will use a default printer.
+ * The default printer will print the data as an array of bytes.
+ */
+#define BCM_DATADUMP_REG_PRINTER(qId, dataDumpId, printFun)             \
+    BCM_DATADUMPCODE(bcm_dataDumpRegPrinter(qId, dataDumpId, printFun))
+
+/* A helper macro for datadump printers */
+#define DDPRINTF(buf, len, bufSize, arg...)                             \
+    ({len += snprintf((buf)+(len), max_t(uint32_t, 0, (bufSize)-80-(len)), ##arg); \
+        if ((len) >= (bufSize)-80) snprintf((buf)+(len), 80, "---BUFFER FULL---\n");})
+
+
+/**
+ * Snapshot API: Commit all logs to the Snapshot queue
+ **/
+
+#define BCM_LOG_SNAPSHOT() BCM_SNAPSHOTCODE() /*TBD*/
+
+
+/**
+ * API Function Prototypes
+ **/
+
+#ifdef CONFIG_BCM_LOG
+
+void bcmLog_setGlobalLogLevel(bcmLogLevel_t logLevel);
+bcmLogLevel_t bcmLog_getGlobalLogLevel(void);
+
+void bcmLog_setLogLevel(bcmLogId_t logId, bcmLogLevel_t logLevel);
+bcmLogLevel_t bcmLog_getLogLevel(bcmLogId_t logId);
+
+char *bcmLog_getModName(bcmLogId_t logId);
+
+typedef int (bcmFun_t)(void *);
+
+/*Register a function with the bcmLog driver*/
+void bcmFun_reg(bcmFunId_t funId, bcmFun_t *f);
+
+/*De-Register a function with the bcmLog driver*/
+void bcmFun_dereg(bcmFunId_t funId);
+
+/*Look up a function by FunId. Returns NULL if the function is not
+ *registered.*/
+bcmFun_t* bcmFun_get(bcmFunId_t funId);
+
+void bcmLog_registerLevelChangeCallback(bcmLogId_t logId, bcmLogLevelChangeCallback_t callback, void *ctx);
+
+#else
+
+/* BCM LOG not configured: create empty stubs for all functions */
+static inline bcmLogModuleInfo_t *bcmLog_logIsEnabled(bcmLogId_t logId, bcmLogLevel_t logLevel) { return NULL; }
+static inline void bcmLog_setGlobalLogLevel(bcmLogLevel_t loglevel)              {}
+static inline bcmLogLevel_t bcmLog_getGlobalLogLevel(void)                       { return 0; }
+static inline char *bcmLog_getModName(bcmLogId_t logId)                          { return NULL; }
+static inline void bcmLog_setLogLevel(bcmLogId_t logId, bcmLogLevel_t logLevel)  {}
+static inline bcmLogLevel_t bcmLog_getLogLevel(bcmLogId_t logId)                 { return 0; }
+typedef int (bcmFun_t)(void *);
+static inline void bcmFun_reg(bcmFunId_t funId, bcmFun_t f)                      {}
+static inline void bcmFun_dereg(bcmFunId_t funId)                                {}
+static inline bcmFun_t* bcmFun_get(bcmFunId_t funId)                             { return NULL; }
+static inline void bcmLog_registerLevelChangeCallback(bcmLogId_t logId, bcmLogLevelChangeCallback_t callback, void *ctx) {}
+
+
+#endif /* CONFIG_BCM_LOG */
+#endif /*_BCM_LOG_SERVICES_*/
diff --git a/include/linux/bcm_log_mod.h b/include/linux/bcm_log_mod.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a7ff82d9c45791319e6482a1ae56d791cc95abd
--- /dev/null
+++ b/include/linux/bcm_log_mod.h
@@ -0,0 +1,313 @@
+/*
+* <:copyright-BRCM:2010:DUAL/GPL:standard
+* 
+*    Copyright (c) 2010 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+* :>
+
+*/
+
+#ifndef _BCM_LOG_MODULES_
+#define _BCM_LOG_MODULES_
+
+typedef enum {
+    BCM_LOG_LEVEL_ERROR=0,
+    BCM_LOG_LEVEL_NOTICE,
+    BCM_LOG_LEVEL_INFO,
+    BCM_LOG_LEVEL_DEBUG,
+    BCM_LOG_LEVEL_MAX
+} bcmLogLevel_t;
+
+/* To support a new module, create a new log ID in bcmLogId_t,
+   and a new entry in BCM_LOG_MODULE_INFO */
+
+
+typedef enum {
+    BCM_LOG_ID_LOG=0,
+    BCM_LOG_ID_VLAN,
+    BCM_LOG_ID_GPON,
+    BCM_LOG_ID_PLOAM,
+    BCM_LOG_ID_PLOAM_FSM,
+    BCM_LOG_ID_PLOAM_HAL,
+    BCM_LOG_ID_PLOAM_PORT,
+    BCM_LOG_ID_PLOAM_ALARM,
+    BCM_LOG_ID_OMCI,
+    BCM_LOG_ID_I2C,
+    BCM_LOG_ID_ENET,
+    BCM_LOG_ID_GPON_SERDES,
+    BCM_LOG_ID_AE,
+    BCM_LOG_ID_XTM,
+    BCM_LOG_ID_IQ,
+    BCM_LOG_ID_BPM,
+    BCM_LOG_ID_ARL,
+    BCM_LOG_ID_EPON,
+    BCM_LOG_ID_GMAC,   
+    BCM_LOG_ID_RDPA,
+    BCM_LOG_ID_RDPA_CMD_DRV,
+    BCM_LOG_ID_PKTRUNNER,
+    BCM_LOG_ID_SIM_CARD,
+    BCM_LOG_ID_PMD,
+    BCM_LOG_ID_TM,
+    BCM_LOG_ID_SPDSVC,
+    BCM_LOG_ID_MCAST,
+    BCM_LOG_ID_DPI,
+    BCM_LOG_ID_CMDLIST,
+    BCM_LOG_ID_ARCHER,
+    BCM_LOG_ID_TOD,
+    BCM_LOG_ID_PON_PWM,
+    BCM_LOG_ID_OPTICALDET,
+    BCM_LOG_ID_WANTYPEDET,
+    BCM_LOG_ID_XPORT,
+    BCM_LOG_ID_BCMLIBS_BIT_POOL,
+    BCM_LOG_ID_MPM,
+    BCM_LOG_ID_MAX
+} bcmLogId_t;
+
+#define BCM_LOG_MODULE_INFO                             \
+    {                                                   \
+        {.logId = BCM_LOG_ID_LOG, .name = "bcmlog", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_VLAN, .name = "vlan", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_GPON, .name = "gpon", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PLOAM, .name = "ploam", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PLOAM_FSM, .name = "ploamFsm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PLOAM_HAL, .name = "ploamHal", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PLOAM_PORT, .name = "ploamPort", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PLOAM_ALARM, .name = "ploamAlarm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_OMCI, .name = "omci", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_I2C, .name = "i2c", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_ENET, .name = "enet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_GPON_SERDES, .name = "gponSerdes", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_AE, .name = "ae", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_XTM, .name = "xtm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_IQ, .name = "iq", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_BPM, .name = "bpm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_ARL, .name = "arl", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_EPON, .name = "eponlue", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_GMAC, .name = "gmac", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_RDPA, .name = "rdpa", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_RDPA_CMD_DRV, .name = "rdpadrv", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PKTRUNNER, .name = "pktrunner", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_SIM_CARD, .name = "sim_card", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PMD, .name = "pmd", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_TM, .name = "tm", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_SPDSVC, .name = "spdsvc", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_MCAST, .name = "mcast", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_DPI, .name = "dpi", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_CMDLIST, .name = "cmdlist", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_ARCHER, .name = "archer", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+        {.logId = BCM_LOG_ID_TOD, .name = "tod", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_PON_PWM, .name = "pon_pwm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_OPTICALDET, .name = "opticaldet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_WANTYPEDET, .name = "wantypedet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_XPORT, .name = "xport", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_BCMLIBS_BIT_POOL, .name = "bitpool", .logLevel = BCM_LOG_LEVEL_NOTICE}, \
+        {.logId = BCM_LOG_ID_MPM, .name = "mpm", .logLevel = BCM_LOG_LEVEL_ERROR}, \
+    }
+
+/* To support a new registered function,
+ * create a new BCM_FUN_ID */
+
+typedef enum {
+    BCM_FUN_ID_RESET_SWITCH=0,
+    BCM_FUN_ID_ENET_LINK_CHG,
+    BCM_FUN_ID_ENET_CHECK_SWITCH_LOCKUP,
+    BCM_FUN_ID_ENET_GET_PORT_BUF_USAGE,
+    BCM_FUN_ID_GPON_GET_GEM_PID_QUEUE,
+    BCM_FUN_ID_ENET_HANDLE,
+    BCM_FUN_ID_EPON_HANDLE,
+    BCM_FUN_IN_ENET_CLEAR_ARL_ENTRY,
+    BCM_FUN_ID_ENET_IS_WAN_PORT, /* Take Logical port number as argument */
+    BCM_FUN_ID_ENET_IS_SWSWITCH_PORT,
+    BCM_FUN_ID_ENET_LAG_PORT_GET,
+    BCM_FUN_ID_ENET_PORT_ROLE_NOTIFY,
+    BCM_FUN_ID_ENET_BOND_RX_PORT_MAP,
+    BCM_FUN_ID_ENET_SYSPORT_CONFIG,
+    BCM_FUN_ID_ENET_SYSPORT_QUEUE_MAP,
+    BCM_FUN_ID_ENET_REMAP_TX_QUEUE,
+    BCM_FUN_ID_ENET_PHY_SPEED_SET,
+    BCM_FUN_ID_ENET_TM_EN_SET,
+    /* The arguments of the BCM TM functions are defined by bcmTmDrv_arg_t */
+    BCM_FUN_ID_TM_REGISTER,
+    BCM_FUN_ID_TM_PORT_CONFIG,
+    BCM_FUN_ID_TM_PORT_ENABLE,
+    BCM_FUN_ID_TM_ARBITER_CONFIG,
+    BCM_FUN_ID_TM_QUEUE_CONFIG,
+    BCM_FUN_ID_TM_APPLY,
+    BCM_FUN_ID_TM_ENQUEUE,
+    /* The arguments of the Speed Service functions are defined in spdsvc_defs.h */
+    BCM_FUN_ID_SPDSVC_TRANSMIT,
+    BCM_FUN_ID_SPDSVC_RECEIVE,
+    /* Kernel Bonding Driver related function */
+    BCM_FUN_ID_BOND_CLR_SLAVE_STAT,
+    BCM_FUN_ID_ENET_IS_BONDED_LAN_WAN_PORT, /* Expects Logical port number as argument */
+    BCM_FUN_ID_ENET_IS_DEV_IN_SLAVE_PATH, 
+    BCM_FUN_ID_BOND_RX_HANDLER, 
+    /* DSL Runner Hooks */
+    BCM_FUN_ID_RUNNER_PREPEND,
+    BCM_FUN_ID_TCPSPDTEST_CONNECT,
+    /* Archer Hooks */
+    BCM_FUN_ID_ARCHER_HOST_BIND,
+    BCM_FUN_ID_ARCHER_XTMRT_BIND,
+    BCM_FUN_ID_ARCHER_WFD_BIND,
+    BCM_FUN_ID_ARCHER_WFD_CONFIG,
+    BCM_FUN_ID_VLAN_LOOKUP_DP,
+    /* WLAN Hooks */
+    BCM_FUN_ID_WLAN_QUERY_BRIDGEFDB,
+    BCM_FUN_ID_WLAN_UPDATE_BRIDGEFDB,
+    BCM_FUN_ID_SPDT_RNR_TRANSMIT,
+    BCM_FUN_ID_MAX
+} bcmFunId_t;
+
+/* Structures passed in above function calls */
+typedef struct {
+    struct net_device *slave_dev;   /* Input */
+    struct net_device **bond_dev;    /* Input/Output */
+}BCM_BondDevInfo;
+
+/* Structures passed in above function calls */
+typedef struct {
+    uint16_t gemPortIndex; /* Input */
+    uint16_t gemPortId;    /* Output */
+    uint8_t  usQueueIdx;   /* Output */
+}BCM_GponGemPidQueueInfo;
+
+typedef enum {
+    BCM_ENET_FUN_TYPE_LEARN_CTRL = 0,
+    BCM_ENET_FUN_TYPE_ARL_WRITE,
+    BCM_ENET_FUN_TYPE_AGE_PORT,
+    BCM_ENET_FUN_TYPE_UNI_UNI_CTRL,
+    BCM_ENET_FUN_TYPE_PORT_RX_CTRL,
+    BCM_ENET_FUN_TYPE_GET_VPORT_CNT,
+    BCM_ENET_FUN_TYPE_GET_IF_NAME_OF_VPORT,
+    BCM_ENET_FUN_TYPE_GET_UNIPORT_MASK,
+    BCM_ENET_FUN_TYPE_MAX
+} bcmFun_Type_t;
+
+typedef struct {
+    uint16_t vid;
+    uint16_t val;
+    uint8_t mac[6];
+} arlEntry_t;
+
+typedef struct {
+    bcmFun_Type_t type; /* Action Needed in Enet Driver */
+    union {
+        uint8_t port;
+        uint8_t uniport_cnt;
+        uint16_t portMask;
+        arlEntry_t arl_entry;
+    };
+    char name[16];
+    uint8_t enable;
+}BCM_EnetHandle_t;
+
+typedef enum {
+    BCM_EPON_FUN_TYPE_UNI_UNI_CTRL = 0,
+    BCM_EPON_FUN_TYPE_MAX
+} bcmEponFun_Type_t;
+
+typedef struct {
+    bcmEponFun_Type_t type; /* Action Needed in Epon Driver */
+    uint8_t enable;
+}BCM_EponHandle_t;
+
+typedef struct {
+    uint8_t port; /* switch port */
+    uint8_t enable; /* enable/disable the clock */
+}BCM_CmfFfeClk_t;
+
+#define BCM_RUNNER_PREPEND_SIZE_MAX  32 /* Increasing the size of the prepend data buffer will require
+                                           recompiling the pktrunner driver files released as binary */
+
+typedef struct {
+    void *blog_p;      /* INPUT: Pointer to the Blog_t structure that triggered the Runner flow creation */
+    uint8_t data[BCM_RUNNER_PREPEND_SIZE_MAX]; /* INPUT: The data that will be be prepended to all packets
+                                                  forwarded by Runner that match the given Blog/Flow.
+                                                  The data must be stored in NETWWORK BYTE ORDER */
+    unsigned int size; /* OUTPUT: Size of the prepend data, up to 32 bytes long.
+                          When no data is to be prepended, specify size = 0 */
+} BCM_runnerPrepend_t;
+
+typedef struct {
+    unsigned int sysport;
+    unsigned int switch_id;
+    unsigned int port;
+    unsigned int is_wan;
+} BCM_EnetPortRole_t;
+
+#define BCM_ENET_SYSPORT_INTF_MAX       2
+#define BCM_ENET_SYSPORT_BLOG_CHNL_MAX  8
+
+typedef enum {
+    BCM_ENET_SYSPORT_MODE_INVALID = 0,
+    BCM_ENET_SYSPORT_MODE_PORT,
+    BCM_ENET_SYSPORT_MODE_INTERNAL_BRCM_SW,
+    BCM_ENET_SYSPORT_MODE_EXTERNAL_BRCM_SW,
+    BCM_ENET_SYSPORT_MODE_MAX
+} bcmSysport_Mode_t;
+
+typedef struct {
+    bcmSysport_Mode_t mode;
+} bcmSysport_Sysport_t;
+
+typedef struct {
+    struct net_device *dev;
+    int sysport;
+    int switch_id;
+    int port;
+    int nbr_of_queues;
+} bcmSysport_BlogChnl_t;
+
+typedef struct {
+    int nbr_of_sysports;
+    bcmSysport_Sysport_t sysport[BCM_ENET_SYSPORT_INTF_MAX];
+    int nbr_of_blog_channels;
+    bcmSysport_BlogChnl_t blog_chnl[BCM_ENET_SYSPORT_BLOG_CHNL_MAX];
+} bcmSysport_Config_t;
+
+#define BCM_ENET_SYSPORT_QUEUE_MAP_PRIORITY_MAX  8
+
+typedef struct {
+    int blog_chnl;
+    uint8_t priority_to_switch_queue[BCM_ENET_SYSPORT_QUEUE_MAP_PRIORITY_MAX];
+} bcmSysport_QueueMap_t;
+
+typedef struct {
+    int blog_chnl;
+    int blog_chnl_rx;
+} bcmEnet_BondRxPortMap_t;
+
+/* Structure used with BCM_FUN_ID_ENET_REMAP_TX_QUEUE */
+typedef struct {
+    uint8_t tx_queue;
+    void *dev;
+} bcmEnet_QueueReMap_t;
+
+typedef struct {
+    struct net_device *dev;
+    int kbps;
+} bcmSysport_PhySpeed_t;
+
+#endif /* _BCM_LOG_MODULES_ */
+
diff --git a/include/linux/bcm_netdev_path.h b/include/linux/bcm_netdev_path.h
new file mode 100644
index 0000000000000000000000000000000000000000..e35b551906cbc14dcc888872fad659ea86eccdb5
--- /dev/null
+++ b/include/linux/bcm_netdev_path.h
@@ -0,0 +1,109 @@
+#ifndef __BCM_NETDEV_PATH_H_INCLUDED__
+#define __BCM_NETDEV_PATH_H_INCLUDED__
+
+
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+/* Forward declaration */
+struct net_device;
+
+#define NETDEV_PATH_HW_SUBPORTS_MAX  CONFIG_BCM_MAX_GEM_PORTS
+struct netdev_path
+{
+        /* this reference counter indicates the number of interfaces
+           referencing this interface */
+        int refcount;
+        /* indicates the RX hardware port number associated to the
+           interface */
+        unsigned int hw_port;
+        /* indicates the TX hardware port number associated to the
+           interface */
+        unsigned int hw_tx_port;
+        /* hardware port type, must be set to one of the types defined in
+           BlogPhy_t  */
+        unsigned int hw_port_type;
+        /* some device drivers support virtual subports within a hardware
+		   port. hw_subport_mcast is used to map a multicast hw subport
+		   to a hw port. */
+        unsigned int hw_subport_mcast_idx;
+};
+
+/* Returns TRUE when _dev is a member of a path, otherwise FALSE */
+#define netdev_path_is_linked(_dev) ( netdev_path_next_dev(_dev) != NULL )
+
+/* Returns TRUE when _dev is the leaf in a path, otherwise FALSE */
+#define netdev_path_is_leaf(_dev) ( (_dev)->bcm_nd_ext.path.refcount == 0 )
+
+/* Returns TRUE when _dev is the root of a path, otherwise FALSE. The root
+   device is the physical device */
+#define netdev_path_is_root(_dev) ( netdev_path_next_dev(_dev) == NULL )
+
+#define netdev_path_set_hw_port(_dev, _hw_port, _hw_port_type)  \
+    do {                                                        \
+        (_dev)->bcm_nd_ext.path.hw_port = (_hw_port);                      \
+        (_dev)->bcm_nd_ext.path.hw_tx_port = (_hw_port);                   \
+        (_dev)->bcm_nd_ext.path.hw_port_type = (_hw_port_type);            \
+    } while(0)
+
+#define netdev_path_set_hw_port_only(_dev, _hw_port)            \
+    do {                                                        \
+        (_dev)->bcm_nd_ext.path.hw_port = (_hw_port);                      \
+    } while(0)
+
+#define netdev_path_set_hw_tx_port_only(_dev, _hw_port)         \
+    do {                                                        \
+        (_dev)->bcm_nd_ext.path.hw_tx_port = (_hw_port);                   \
+    } while(0)
+
+#define netdev_path_get_hw_port(_dev) ( (_dev)->bcm_nd_ext.path.hw_port )
+
+#define netdev_path_get_hw_tx_port(_dev) ( (_dev)->bcm_nd_ext.path.hw_tx_port )
+
+#define netdev_path_get_hw_port_type(_dev) ( (_dev)->bcm_nd_ext.path.hw_port_type )
+#define netdev_path_set_hw_port_type(_dev, _hwt) do { (_dev)->bcm_nd_ext.path.hw_port_type = _hwt; } while (0)
+
+#define netdev_path_get_hw_subport_mcast_idx(_dev) ( (_dev)->bcm_nd_ext.path.hw_subport_mcast_idx )
+
+/* Returns a pointer to the next device in a path, towards the root
+   (physical) device */
+struct net_device *netdev_path_next_dev(struct net_device *dev);
+
+struct net_device *netdev_path_get_root(struct net_device *dev);
+
+int netdev_path_set_hw_subport_mcast_idx(struct net_device *dev, unsigned int subport_idx);
+
+int netdev_path_add(struct net_device *new_dev, struct net_device *next_dev);
+
+int netdev_path_remove(struct net_device *dev);
+
+void netdev_path_dump(struct net_device *dev);
+
+
+#endif /* __BCM_NETDEV_PATH_H_INCLUDED__ */
diff --git a/include/linux/bcm_netdevice.h b/include/linux/bcm_netdevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..a86d0098d198294d52d04d11587729fa7c72aeee
--- /dev/null
+++ b/include/linux/bcm_netdevice.h
@@ -0,0 +1,152 @@
+#ifndef __BCM_NETDEVICE_H_INCLUDED__
+#define __BCM_NETDEVICE_H_INCLUDED__
+
+
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+#if defined(CONFIG_BLOG)
+#include <linux/blog.h>
+#if defined(CONFIG_BCM_WLAN_MODULE)
+#include <linux/bcm_dslcpe_wlan_info.h>
+#endif
+#endif
+#include <linux/bcm_netdev_path.h>
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+#include <linux/br_fp.h>
+#endif
+#include <uapi/linux/bcm_maclimit.h>
+
+#define BCM_IFF_WANDEV      (1 << 0)
+#define BCM_IFF_VLAN        (1 << 1)
+#define BCM_IFF_PPP         (1 << 2)
+#define BCM_IFF_HW_FDB      (1 << 3)  // this dev is enabled for hw MAC learning
+#define BCM_IFF_HW_SWITCH   (1 << 4)
+#define BCM_IFF_WLANDEV     (1 << 5)
+#define BCM_IFF_BCM_DEV     (1 << 6)
+#define BCM_IFF_WLANDEV_NIC (1 << 7)
+#define BCM_IFF_WLANDEV_DHD (1 << 8)
+
+#define BLOG_DEV_STAT_FLAG_INCLUDE_SW_UC    (1<<0) /* Include SW accelerated Unicast stats */
+#define BLOG_DEV_STAT_FLAG_INCLUDE_HW_UC    (1<<1) /* Include HW accelerated Unicast stats */
+#define BLOG_DEV_STAT_FLAG_INCLUDE_SW_MC    (1<<2) /* Include SW accelerated Multicast stats */
+#define BLOG_DEV_STAT_FLAG_INCLUDE_HW_MC    (1<<3) /* Include HW accelerated Multicast stats */
+#define BLOG_DEV_STAT_FLAG_INCLUDE_SW       (BLOG_DEV_STAT_FLAG_INCLUDE_SW_UC|BLOG_DEV_STAT_FLAG_INCLUDE_SW_MC)
+#define BLOG_DEV_STAT_FLAG_INCLUDE_HW       (BLOG_DEV_STAT_FLAG_INCLUDE_HW_UC|BLOG_DEV_STAT_FLAG_INCLUDE_HW_MC)
+#define BLOG_DEV_STAT_FLAG_INCLUDE_ALL      (BLOG_DEV_STAT_FLAG_INCLUDE_SW|BLOG_DEV_STAT_FLAG_INCLUDE_HW)
+
+/* Info types to ask from different drivers */
+typedef enum {
+    BCM_NETDEV_TO_RDPA_IF,
+} bcm_netdev_priv_info_type_t;
+/* Output from driver corresponding to the info type */
+typedef union {
+    struct {
+        int rdpa_if;
+    } bcm_netdev_to_rdpa_if;
+} bcm_netdev_priv_info_out_t;
+
+typedef	int (*bcm_netdev_priv_info_get_cb_fn_t)(struct net_device *dev, 
+                                                bcm_netdev_priv_info_type_t info_type, 
+                                                bcm_netdev_priv_info_out_t *info_out);
+
+struct bcm_netdev_ext {
+    unsigned int iff_flags;
+    struct netdev_path path;
+#if defined(CONFIG_BLOG)
+	BlogStats_t blog_stats; /* Cummulative stats of accelerated flows */
+	unsigned int blog_stats_flags; /* Blog stats collection property for the device */
+#if defined(CONFIG_BCM_WLAN_MODULE)
+	/* runner multicast acceleration hook */
+	wlan_client_get_info_t wlan_client_get_info;
+#endif
+#endif /* CONFIG_BLOG */
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+    struct bcm_br_ext bcm_br_ext;
+#endif
+    struct mac_limit mac_limit;
+    /* return 0-success, -1:failure (not supported or other error) */
+    bcm_netdev_priv_info_get_cb_fn_t bcm_netdev_cb_fn;
+};
+
+#if defined(CONFIG_BLOG) && defined(CONFIG_BCM_WLAN_MODULE)
+#define netdev_wlan_client_get_info(dev) ((dev)->bcm_nd_ext.wlan_client_get_info)
+#else
+#define netdev_wlan_client_get_info(dev) NULL
+#endif
+
+#define bcm_netdev_ext_field_get(dev, f) ((dev)->bcm_nd_ext.f)
+#define bcm_netdev_ext_field_get_ptr(dev, f) (&(dev)->bcm_nd_ext.f)
+#define bcm_netdev_ext_field_set(dev, f, val) ((dev)->bcm_nd_ext.f = val)
+
+#define netdev_bcm_dev_set(_dev)    (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_BCM_DEV
+#define netdev_bcm_dev_unset(_dev)  (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_BCM_DEV
+#define is_netdev_bcm_dev(_dev)     ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_BCM_DEV)
+
+#define netdev_wan_set(_dev)        (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WANDEV
+#define netdev_wan_unset(_dev)      (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WANDEV
+#define is_netdev_wan(_dev)         ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WANDEV)
+
+#define netdev_vlan_set(_dev)        (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_VLAN
+#define is_netdev_vlan(_dev)         ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_VLAN)
+
+#define netdev_ppp_set(_dev)        (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_PPP
+#define is_netdev_ppp(_dev)         ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_PPP)
+
+#define netdev_hw_fdb_set(_dev)     (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_HW_FDB
+#define netdev_hw_fdb_unset(_dev)   (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_HW_FDB
+#define is_netdev_hw_fdb(_dev)      ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_HW_FDB)
+
+#define netdev_hw_switch_set(_dev)    (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_HW_SWITCH
+#define netdev_hw_switch_unset(_dev)  (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_HW_SWITCH
+#define is_netdev_hw_switch(_dev)     ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_HW_SWITCH)
+
+#define netdev_wlan_set(_dev)       (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV
+#define netdev_wlan_unset(_dev)     (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV
+#define is_netdev_wlan(_dev)        ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV)
+
+#define netdev_wlan_nic_set(_dev)       (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV_NIC
+#define netdev_wlan_nic_unset(_dev)     (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV_NIC
+#define is_netdev_wlan_nic(_dev)        ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV_NIC)
+
+#define netdev_wlan_dhd_set(_dev)       (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV_DHD
+#define netdev_wlan_dhd_unset(_dev)     (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV_DHD
+#define is_netdev_wlan_dhd(_dev)        ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV_DHD)
+
+// for NETDEV_CHANGEUPPER
+#define is_netdev_br_port_add(_dev, _ptr)   (netif_is_bridge_port(_dev) && ((struct netdev_notifier_changeupper_info *)(ptr))->linking)
+#define is_netdev_br_port_del(_dev, _ptr)   (netif_is_bridge_port(_dev) && !((struct netdev_notifier_changeupper_info *)(ptr))->linking)
+#define netdev_get_bridge_master(_dev, _ptr) (((struct netdev_notifier_changeupper_info *)(ptr))->upper_dev)
+
+void bcm_netdev_ext_inherit(struct net_device *parent, struct net_device * child);
+
+int bcm_attach_vlan_hook(struct net_device *dev);
+void bcm_detach_vlan_hook(struct net_device *dev);
+
+#endif /* __BCM_NETDEVICE_H_INCLUDED__ */
\ No newline at end of file
diff --git a/include/linux/bcm_nf_conntrack.h b/include/linux/bcm_nf_conntrack.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe6f7ce1e3b4eecedaafc6371fd9e14247f697e0
--- /dev/null
+++ b/include/linux/bcm_nf_conntrack.h
@@ -0,0 +1,293 @@
+/*
+* <:copyright-BRCM:2012:DUAL/GPL:standard
+* 
+*    Copyright (c) 2012 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+*
+:>
+*/
+
+#ifndef _BCM_NF_CONNTRACK_H
+#define _BCM_NF_CONNTRACK_H
+
+#include <linux/types.h>
+#include <linux/netfilter/nf_conntrack_common.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+
+#include <linux/blog.h>
+#include <linux/dpi.h>
+#include <linux/iqos.h>
+
+
+#if defined(CONFIG_BLOG)
+static inline void bcm_nf_blog_ct_init(struct nf_conn *ct)
+{
+	/* no blog lock needed here */
+	set_bit(IPS_BLOG_BIT, &ct->status);  /* Enable conntrack blogging */
+	ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] = BLOG_KEY_FC_INVALID;
+	ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]    = BLOG_KEY_FC_INVALID;
+} 
+
+static inline int bcm_nf_blog_destroy_conntrack(struct nf_conn *ct)
+{
+	blog_lock();
+	pr_debug("%s(%px) blog keys[0x%08x,0x%08x]\n", __func__,
+		ct, ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL],
+		ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]);
+
+
+	/* Conntrack going away, notify blog client */
+	if ((ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) ||
+			(ct->bcm_ext.blog_key[IP_CT_DIR_REPLY] != BLOG_KEY_FC_INVALID)) {
+
+		blog_notify(DESTROY_FLOWTRACK, (void*)ct,
+					(uint32_t)ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL],
+					(uint32_t)ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]);
+	}
+
+	clear_bit(IPS_BLOG_BIT, &ct->status);	/* Disable further blogging */
+	blog_unlock();
+
+	return 0;
+}
+
+static inline int bcm_nf_blog_link_ct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
+			 struct sk_buff *skb, u_int16_t l3num, u_int8_t protonum)
+{
+
+	/* here we dont need blog lock as this blog is owned by this skb */
+
+	struct nf_conn_help * help = nfct_help(ct);
+
+
+	if ((help != (struct nf_conn_help *)NULL) &&
+			(help->helper != (struct nf_conntrack_helper *)NULL) &&
+			(help->helper->name && strcmp(help->helper->name, "BCM-NAT"))) {
+		pr_debug("nf_conntrack_in: skb<%px> ct<%px> helper<%s> found\n",
+				skb, ct, help->helper->name);
+		clear_bit(IPS_BLOG_BIT, &ct->status);
+	}
+
+	if (test_bit(IPS_BLOG_BIT, &ct->status)) {	/* OK to blog ? */
+		uint32_t ct_type=(l3num==PF_INET)?BLOG_PARAM2_IPV4:BLOG_PARAM2_IPV6;
+		pr_debug("nf_conntrack_in: skb<%px> blog<%px> ct<%px>\n",
+				skb, blog_ptr(skb), ct);
+
+		if (protonum == IPPROTO_GRE)
+			ct_type = BLOG_PARAM2_GRE_IPV4;
+
+		if(ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port) == BLOG_L2TP_PORT)				
+			ct_type = BLOG_PARAM2_L2TP_IPV4;
+
+		blog_link(FLOWTRACK, blog_ptr(skb),
+				(void*)ct, CTINFO2DIR(ctinfo), ct_type);
+	} else {
+		pr_debug("nf_conntrack_in: skb<%px> ct<%px> NOT BLOGible<%px>\n",
+				skb, ct, blog_ptr(skb));
+		blog_skip(skb, blog_skip_reason_ct_status_donot_blog); /* No blogging */
+	}
+
+	return 0;
+}
+
+static inline int bcm_nf_blog_update_timeout(struct nf_conn *ct, unsigned long extra_jiffies)
+{
+	blog_lock();
+	
+	if ((ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) ||
+			(ct->bcm_ext.blog_key[IP_CT_DIR_REPLY] != BLOG_KEY_FC_INVALID)) {
+
+		unsigned int blog_key = (ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) ? 
+						ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] : ct->bcm_ext.blog_key[IP_CT_DIR_REPLY];
+
+		blog_notify(UPDATE_FLOWTRACK_IDLE_TIMEOUT, (void*)ct,
+					blog_key, (uint32_t)(extra_jiffies/HZ));
+	}
+	blog_unlock();
+
+	return 0;
+}
+
+#endif /*CONFIG_BLOG */
+
+static inline int nf_conntrack_ipv6_is_multicast(const __be32 ip6[4])
+{
+	return ((ip6[0] & htonl(0xFF000000)) == htonl(0xFF000000));
+}
+
+static inline void bcm_nf_conn_set_iq_prio(struct nf_conn *ct, struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+#if defined(CONFIG_BLOG)
+	if (skb != NULL && skb->blog_p != NULL ) 
+		ct->bcm_ext.iq_prio = (blog_iq(skb) == BLOG_IQ_PRIO_HIGH) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW;
+	else
+#endif
+	{
+
+		switch (nf_ct_l3num(ct)) {
+			case AF_INET:
+				ct->bcm_ext.iq_prio = ipv4_is_multicast(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW;
+				break;
+			case AF_INET6:
+				ct->bcm_ext.iq_prio = nf_conntrack_ipv6_is_multicast(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW;
+				break;
+			default:
+				ct->bcm_ext.iq_prio = IQOS_PRIO_LOW;
+		}
+	}	
+#endif
+}
+
+static inline void bcm_nf_iqos_destroy_conntrack(struct nf_conn *ct)
+{
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+	if (test_bit(IPS_IQOS_BIT,&ct->status)) {
+		clear_bit(IPS_IQOS_BIT, &ct->status);	
+		iqos_rem_L4port(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
+				ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.all), IQOS_ENT_DYN);
+		iqos_rem_L4port(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum,
+				ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all), IQOS_ENT_DYN);
+	}
+#endif
+}
+
+#if defined(CONFIG_BCM_NF_DERIVED_CONN)
+static inline void bcm_nf_ct_derived_list_add(struct nf_conn *ct)
+{
+ 	BCM_DERIVED_CONN_LOCK_BH();
+
+	 /* master ref count incremneted before calling this fcuntion */
+	/* via exp->master safe, refcnt bumped in nf_ct_find_expectation */
+	if(ct->master){
+
+		list_add(&ct->bcm_ext.derived_list,
+			 &ct->master->bcm_ext.derived_connections);
+	}
+	
+ 	BCM_DERIVED_CONN_UNLOCK_BH();
+}
+
+static inline void bcm_nf_ct_derived_list_del(struct nf_conn *ct)
+{
+ 	BCM_DERIVED_CONN_LOCK_BH();
+	if(ct->master){
+		list_del(&ct->bcm_ext.derived_list);
+	}
+	
+ 	BCM_DERIVED_CONN_UNLOCK_BH();
+}
+static inline void bcm_nf_ct_derived_conn_init(struct nf_conn *ct)
+{
+	INIT_LIST_HEAD(&ct->bcm_ext.derived_connections);
+	INIT_LIST_HEAD(&ct->bcm_ext.derived_list);
+	ct->bcm_ext.derived_timeout = 0;
+}
+#else
+
+static inline void bcm_nf_ct_derived_list_add(struct nf_conn *ct){};
+static inline void bcm_nf_ct_derived_list_del(struct nf_conn *ct){};
+static inline void bcm_nf_ct_derived_conn_init(struct nf_conn *ct){};
+#endif
+
+
+static inline unsigned long bcm_nf_ct_refresh(struct nf_conn *ct,
+			  unsigned long extra_jiffies)
+{
+#if defined(CONFIG_BCM_NF_DERIVED_CONN)
+	/* when derived time out is set always use it */
+	if(ct->bcm_ext.derived_timeout)
+		extra_jiffies = ct->bcm_ext.derived_timeout;
+#endif
+
+#if defined(CONFIG_BLOG)
+	if( nf_ct_is_confirmed(ct) && (ct->bcm_ext.extra_jiffies != extra_jiffies)) {
+		ct->bcm_ext.extra_jiffies = extra_jiffies;
+		/*notify accelerator */
+		bcm_nf_blog_update_timeout(ct, extra_jiffies);
+	}
+#endif
+
+	return extra_jiffies;
+}
+
+static void bcm_conntrack_init_end(void)
+{
+#if IS_ENABLED(CONFIG_BCM_DPI)
+	dpi_conntrack_init();
+#endif
+}
+
+static void bcm_conntrack_cleanup_end(void)
+{
+#if IS_ENABLED(CONFIG_BCM_DPI)
+	dpi_conntrack_cleanup();
+#endif
+}
+
+static void bcm_nf_ct_alloc(struct nf_conn *ct, struct sk_buff *skb)
+{
+#if defined(CONFIG_BLOG)
+	bcm_nf_blog_ct_init(ct);
+#endif
+	/* REGARDLESS_DROP */
+	INIT_LIST_HEAD(&ct->bcm_ext.safe_list);
+
+	bcm_nf_ct_derived_conn_init(ct);
+	bcm_nf_conn_set_iq_prio(ct, skb);
+
+#if IS_ENABLED(CONFIG_BCM_DPI)
+	memset(&ct->bcm_ext.dpi, 0, sizeof(ct->bcm_ext.dpi));
+	if (skb && skb->dev && is_netdev_wan(skb->dev))
+		set_bit(DPI_CT_INIT_FROM_WAN_BIT, &ct->bcm_ext.dpi.flags);
+#endif
+#if IS_ENABLED(CONFIG_NF_DYNDSCP)
+	/* initialize dynamic dscp inheritance fields */
+	ct->bcm_ext.dyndscp.status = 0;
+	ct->bcm_ext.dyndscp.dscp[0] = 0;
+	ct->bcm_ext.dyndscp.dscp[1] = 0;
+#endif
+}
+
+static void bcm_nf_ct_init(struct nf_conn *ct)
+{
+	bcm_nf_ct_derived_list_add(ct);
+}
+
+static void bcm_nf_ct_delete(struct nf_conn *ct)
+{
+#if IS_ENABLED(CONFIG_BCM_DPI)
+	dpi_nf_ct_delete(ct);
+#endif
+}
+
+static void bcm_nf_ct_destroy(struct nf_conn *ct)
+{
+#if defined(CONFIG_BLOG)
+	bcm_nf_blog_destroy_conntrack(ct);
+#endif
+	bcm_nf_iqos_destroy_conntrack(ct);
+	bcm_nf_ct_derived_list_del(ct);
+}
+#endif /* _BCM_NF_CONNTRACK_H */
diff --git a/include/linux/bcm_nf_regardlessdrop.h b/include/linux/bcm_nf_regardlessdrop.h
new file mode 100644
index 0000000000000000000000000000000000000000..957e11d4577101d89eb59e90266de917f0605761
--- /dev/null
+++ b/include/linux/bcm_nf_regardlessdrop.h
@@ -0,0 +1,283 @@
+/*
+* <:copyright-BRCM:2012:DUAL/GPL:standard
+* 
+*    Copyright (c) 2012 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+:>
+*/
+
+#ifndef _BCM_NF_REGARDLESSDROP_
+#define _BCM_NF_REGARDLESSDROP_
+
+#define NF_CT_SAFE_LISTS_MAX 6
+/* regardless drop of connection when conntrack table is full */
+struct safe_list {
+	spinlock_t lock;
+	struct list_head low;          /* low priority linux only */
+	struct list_head low_sw_accel; /* low priority sw acceleartor */
+	struct list_head low_hw_accel; /* low priority hw accelerator */
+	struct list_head hi;           /* high priority linux only */
+	struct list_head hi_sw_accel;  /* high priority sw acceleartor */
+	struct list_head hi_hw_accel;  /* high priority hw accelerator */
+    struct list_head *drop_list_order[NF_CT_SAFE_LISTS_MAX]; /*order in which lists are checked to drop a connection */
+};
+
+struct safe_list ct_safe_lists = {
+	.lock 		     = __SPIN_LOCK_UNLOCKED(ct_safe_lists.lock),
+	.low		     = LIST_HEAD_INIT(ct_safe_lists.low),
+	.low_sw_accel    = LIST_HEAD_INIT(ct_safe_lists.low_sw_accel),
+	.low_hw_accel    = LIST_HEAD_INIT(ct_safe_lists.low_hw_accel),
+	.hi			     = LIST_HEAD_INIT(ct_safe_lists.hi),
+	.hi_sw_accel     = LIST_HEAD_INIT(ct_safe_lists.hi_sw_accel),
+	.hi_hw_accel     = LIST_HEAD_INIT(ct_safe_lists.hi_hw_accel),
+#if CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 1
+    /* when trying to find a drop candidate search safe_list's in the order of
+     * non-accelerated-->sw_accelerated-->hw_accelerated
+     * this is the default policy
+     */
+    .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.hi,
+                        &ct_safe_lists.low_sw_accel,&ct_safe_lists.hi_sw_accel,
+                        &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi_hw_accel}
+#elif CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 2
+    .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.low_sw_accel,
+                        &ct_safe_lists.hi, &ct_safe_lists.hi_sw_accel,
+                        &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi_hw_accel}
+#elif CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 3
+    .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.low_sw_accel,
+                        &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi,
+                        &ct_safe_lists.hi_sw_accel, &ct_safe_lists.hi_hw_accel}
+#else
+#error "Netfilter Regardless Drop Order is not set"
+#endif
+};
+
+
+static inline void ct_set_curr_safe_list(struct nf_conn *ct)
+{
+	/*first try to move to HW list */
+	if(ct->bcm_ext.hw_accel_flows) {
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+		if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH)
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi_hw_accel;
+		else
+#endif
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.low_hw_accel;
+	}else if(ct->bcm_ext.sw_accel_flows) {
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+		if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH)
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi_sw_accel;
+		else
+#endif
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.low_sw_accel;
+	}else{
+		/*move to SW only list */
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+		if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH)
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi;
+		else
+#endif
+			ct->bcm_ext.curr_safe_list = &ct_safe_lists.low;
+	}
+}
+
+static inline void ct_safe_list_add_tail(struct nf_conn *ct)
+{
+	spin_lock_bh(&ct_safe_lists.lock);
+
+	ct->bcm_ext.hw_accel_flows = 0;
+	ct->bcm_ext.sw_accel_flows = 0;
+
+	ct_set_curr_safe_list(ct);
+
+	list_add_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list);
+
+	spin_unlock_bh(&ct_safe_lists.lock);
+}
+
+static inline void ct_safe_list_move_tail(struct nf_conn *ct)
+{
+	spin_lock_bh(&ct_safe_lists.lock);
+
+	list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list);
+
+	spin_unlock_bh(&ct_safe_lists.lock);
+}
+
+static inline void ct_safe_list_del(struct nf_conn *ct)
+{
+	spin_lock_bh(&ct_safe_lists.lock);
+	list_del(&ct->bcm_ext.safe_list);
+	spin_unlock_bh(&ct_safe_lists.lock);
+}
+
+#if defined(CONFIG_BLOG)
+
+static inline void __ct_blog_flow_accel_activate_event(struct nf_conn *ct,
+		BlogFlowEventInfo_t *info)
+{
+	spin_lock_bh(&ct_safe_lists.lock);
+	/* ensure ct is not being deleted */
+	if(likely(atomic_read(&ct->ct_general.use) >= 1))
+	{
+		if(info->flow_event_type == FLOW_EVENT_TYPE_HW)
+			ct->bcm_ext.hw_accel_flows++;
+		else
+			ct->bcm_ext.sw_accel_flows++;
+
+		ct_set_curr_safe_list(ct);
+		
+		list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list);
+	}
+	spin_unlock_bh(&ct_safe_lists.lock);
+}
+
+static inline void ct_blog_flow_activate_event(BlogFlowEventInfo_t *info)
+{
+
+    if ((info->flow_event_type == FLOW_EVENT_TYPE_FC) || 
+			(info->flow_event_type == FLOW_EVENT_TYPE_HW)){
+
+		__ct_blog_flow_accel_activate_event(info->ct_pld_p, info);
+
+        if(info->ct_del_p) 
+            __ct_blog_flow_accel_activate_event(info->ct_del_p, info);
+    }
+}
+
+static inline void __ct_blog_flow_accel_deactivate_event(struct nf_conn *ct,
+		BlogFlowEventInfo_t *info)
+{
+	spin_lock_bh(&ct_safe_lists.lock);
+	/* ensure ct is not being deleted */
+	if(likely(atomic_read(&ct->ct_general.use) >= 1)){
+
+		if(info->flow_event_type == FLOW_EVENT_TYPE_HW)
+			ct->bcm_ext.hw_accel_flows--;
+		else
+			ct->bcm_ext.sw_accel_flows--;
+
+		ct_set_curr_safe_list(ct);
+
+		list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list);
+	}
+	spin_unlock_bh(&ct_safe_lists.lock);
+}
+
+static inline void ct_blog_flow_deactivate_event( BlogFlowEventInfo_t *info)
+{
+    if ((info->flow_event_type == FLOW_EVENT_TYPE_FC) || 
+			(info->flow_event_type == FLOW_EVENT_TYPE_HW)){
+
+        __ct_blog_flow_accel_deactivate_event(info->ct_pld_p, info);
+
+        if(info->ct_del_p) 
+            __ct_blog_flow_accel_deactivate_event(info->ct_del_p, info);
+    }
+}
+
+static int ct_blog_flowevent_notify(struct notifier_block * nb,
+                 unsigned long  event, void *info)
+{
+    switch(event){
+
+        case FLOW_EVENT_ACTIVATE:
+            ct_blog_flow_activate_event(info);
+            break;
+
+        case FLOW_EVENT_DEACTIVATE:
+            ct_blog_flow_deactivate_event(info);
+            break;
+
+        default:
+            break;
+
+    }
+    return NOTIFY_OK;
+}
+
+#endif /*CONFIG_BLOG */
+
+
+/*caller must have safe_list lock acquired */
+static inline struct nf_conn* __ct_find_drop_candidate(struct net *net, struct list_head *list )
+{
+	struct list_head *tmp;
+	struct nf_conn *ct, *ct_candidate=NULL;
+
+	if (!list_empty(list)) {
+		list_for_each(tmp, list) {
+			ct = container_of(tmp, struct nf_conn, bcm_ext.safe_list);
+
+			/*TODO  IPS_OFFLOAD_BIT, should we check all lists or only sw only lists*/
+
+
+			if (likely(!test_bit(IPS_OFFLOAD_BIT, &ct->status) && nf_ct_is_confirmed(ct) 
+				&& !nf_ct_is_dying(ct) && net_eq(nf_ct_net(ct), net) 
+				&& atomic_inc_not_zero(&ct->ct_general.use))) {
+
+			/* we dont need to check if connection is expired or not to drop it,
+			 * or trrigger gc, as we are already using LRU
+			 */ 
+				ct_candidate = ct;
+				/* move to the tail of the list while it's being deleted*/
+				list_move_tail(&ct_candidate->bcm_ext.safe_list, list);
+				break;
+			}
+		}
+	}
+	/* refcount of ct_candidate is incremented in this fucntion,
+     * it's callers responsibility to decrement it
+     */
+	return ct_candidate;
+}
+
+/* Choose a LRU connection based on the configured drop order policy */
+static int bcm_regardless_drop(struct net *net)
+{
+	struct nf_conn *ct_candidate = NULL;
+	int i,dropped = 0;
+
+	spin_lock_bh(&ct_safe_lists.lock);
+
+	for( i=0; i < NF_CT_SAFE_LISTS_MAX; i++ ) {
+		ct_candidate = __ct_find_drop_candidate(net, ct_safe_lists.drop_list_order[i]);
+		if(ct_candidate)
+			break;
+	}
+
+	spin_unlock_bh(&ct_safe_lists.lock);
+
+	if (unlikely(ct_candidate == NULL))
+		return dropped;
+
+	if(nf_ct_delete(ct_candidate, 0, 0) == true){
+		dropped = 1;
+		NF_CT_STAT_INC_ATOMIC(net, early_drop);
+	}
+
+	nf_ct_put(ct_candidate);
+	return dropped;
+}
+
+#endif /* _BCM_NF_REGARDLESSDROP_ */
diff --git a/include/linux/bcm_nfconn_ext.h b/include/linux/bcm_nfconn_ext.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a79fd4a9d8e92b6f7df4c178bec8ed524922287
--- /dev/null
+++ b/include/linux/bcm_nfconn_ext.h
@@ -0,0 +1,85 @@
+#ifndef _BCM_NFCONN_EXT_H
+#define _BCM_NFCONN_EXT_H
+
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+#include <linux/dpi.h>
+
+struct bcm_nf_conn_ext {
+#if defined(CONFIG_BLOG)
+	unsigned int blog_key[2];	/* Associating 2=IP_CT_DIR_MAX blogged flows */
+	unsigned long extra_jiffies;	/* connection timeout value */
+#endif
+
+#if defined(CONFIG_BCM_KF_NF_REGARDLESS_DROP)
+	uint32_t hw_accel_flows;	/* Number of HW accelerated flows, need 32 bit for tunnel connection */
+	uint32_t sw_accel_flows;	/* Number of SW accelerated flows, need 32 bit for tunnel connection */
+	struct list_head safe_list;	/* regardless drop of connections */
+	struct list_head *curr_safe_list; /* current safe_list for this connection*/
+#endif
+
+#if defined(CONFIG_BCM_NF_DERIVED_CONN)
+	struct list_head derived_connections;	/* Used by master connection */
+	struct list_head derived_list;		/* Used by child connection */
+	unsigned int derived_timeout;		/* if non-zero override linux timeout */
+#endif
+
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+	uint8_t iq_prio;			/* Ingress QoS Prio */
+	uint8_t unused0;
+	uint16_t unused1;
+#endif
+
+#if IS_ENABLED(CONFIG_NF_DYNDSCP)
+	struct nf_tos_inheritance {
+		u_int16_t status;
+		u_int8_t dscp[2];		/* IP_CT_DIR_MAX */
+	} dyndscp;
+#endif
+#if IS_ENABLED(CONFIG_BCM_DPI)
+	struct dpi_info dpi;
+#endif
+};
+
+#define bcm_nfconn_ext_field_get(ct, f)		(ct->bcm_ext.f)
+#define bcm_nfconn_ext_field_get_ptr(ct, f)	(&ct->bcm_ext.f)
+#define bcm_nfconn_ext_field_set(ct, f, val)	(ct->bcm_ext.f = val)
+
+#if defined(CONFIG_BCM_NF_DERIVED_CONN)
+extern spinlock_t bcm_derived_conn_lock;
+#define BCM_DERIVED_CONN_LOCK_BH()	spin_lock_bh(&bcm_derived_conn_lock)
+#define BCM_DERIVED_CONN_UNLOCK_BH()	spin_unlock_bh(&bcm_derived_conn_lock)
+#endif
+
+
+int ct_show_bcm_ext(struct seq_file *s, const struct nf_conn *ct);
+
+
+#endif /*_BCM_NFCONN_EXT_H */
diff --git a/include/linux/bcm_skb_defines.h b/include/linux/bcm_skb_defines.h
new file mode 100644
index 0000000000000000000000000000000000000000..4acb80265551ba45564bb12f674bcc5aaabb0316
--- /dev/null
+++ b/include/linux/bcm_skb_defines.h
@@ -0,0 +1,149 @@
+/*
+* <:copyright-BRCM:2014:DUAL/GPL:standard
+* 
+*    Copyright (c) 2014 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+* :>
+*/
+
+#ifndef _BCM_SKB_DEFINES_
+#define _BCM_SKB_DEFINES_
+
+/* queue = mark[4:0] */
+#define SKBMARK_Q_S             0
+#define SKBMARK_Q_M             (0x1F << SKBMARK_Q_S)
+#define SKBMARK_GET_Q(MARK)     ((MARK & SKBMARK_Q_M) >> SKBMARK_Q_S)
+#define SKBMARK_SET_Q(MARK, Q)  ((MARK & ~SKBMARK_Q_M) | (Q << SKBMARK_Q_S))
+/* traffic_class_id = mark[10:5] */
+#define SKBMARK_TC_ID_S         5
+#define SKBMARK_TC_ID_M         (0x3F << SKBMARK_TC_ID_S)
+#define SKBMARK_GET_TC_ID(MARK) ((MARK & SKBMARK_TC_ID_M) >> SKBMARK_TC_ID_S)
+#define SKBMARK_SET_TC_ID(MARK, TC) \
+    ((MARK & ~SKBMARK_TC_ID_M) | (TC << SKBMARK_TC_ID_S))
+/* flow_id = mark[18:11] */
+#define SKBMARK_FLOW_ID_S       11
+#define SKBMARK_FLOW_ID_M       (0xFF << SKBMARK_FLOW_ID_S)
+#define SKBMARK_GET_FLOW_ID(MARK) \
+    ((MARK & SKBMARK_FLOW_ID_M) >> SKBMARK_FLOW_ID_S)
+#define SKBMARK_SET_FLOW_ID(MARK, FLOW) \
+    ((MARK & ~SKBMARK_FLOW_ID_M) | (FLOW << SKBMARK_FLOW_ID_S))
+/* iq_prio = mark[19]; for Ingress QoS used when TX is WLAN */
+#define SKBMARK_IQPRIO_MARK_S    19
+#define SKBMARK_IQPRIO_MARK_M    (0x01 << SKBMARK_IQPRIO_MARK_S)
+#define SKBMARK_GET_IQPRIO_MARK(MARK) \
+    ((MARK & SKBMARK_IQPRIO_MARK_M) >> SKBMARK_IQPRIO_MARK_S)
+#define SKBMARK_SET_IQPRIO_MARK(MARK, IQPRIO_MARK) \
+    ((MARK & ~SKBMARK_IQPRIO_MARK_M) | (IQPRIO_MARK << SKBMARK_IQPRIO_MARK_S))
+/* port = mark[26:20]; for enet driver of gpon port, this is gem_id */
+#define SKBMARK_PORT_S          20
+#define SKBMARK_PORT_M          (0x7F << SKBMARK_PORT_S)
+#define SKBMARK_GET_PORT(MARK) \
+    ((MARK & SKBMARK_PORT_M) >> SKBMARK_PORT_S)
+#define SKBMARK_SET_PORT(MARK, PORT) \
+    ((MARK & ~SKBMARK_PORT_M) | (PORT << SKBMARK_PORT_S))
+
+/* iffwan_mark = mark[27] --  BRCM defined-- */
+#define SKBMARK_IFFWAN_MARK_S    27
+#define SKBMARK_IFFWAN_MARK_M    (0x01 << SKBMARK_IFFWAN_MARK_S)
+#define SKBMARK_GET_IFFWAN_MARK(MARK) \
+    ((MARK & SKBMARK_IFFWAN_MARK_M) >> SKBMARK_IFFWAN_MARK_S)
+#define SKBMARK_SET_IFFWAN_MARK(MARK, IFFWAN_MARK) \
+    ((MARK & ~SKBMARK_IFFWAN_MARK_M) | (IFFWAN_MARK << SKBMARK_IFFWAN_MARK_S))
+
+/* ipsec_mark = mark[28] */
+#define SKBMARK_IPSEC_MARK_S    28
+#define SKBMARK_IPSEC_MARK_M    (0x01 << SKBMARK_IPSEC_MARK_S)
+#define SKBMARK_GET_IPSEC_MARK(MARK) \
+    ((MARK & SKBMARK_IPSEC_MARK_M) >> SKBMARK_IPSEC_MARK_S)
+#define SKBMARK_SET_IPSEC_MARK(MARK, IPSEC_MARK) \
+    ((MARK & ~SKBMARK_IPSEC_MARK_M) | (IPSEC_MARK << SKBMARK_IPSEC_MARK_S))
+/* policy_routing = mark[31:29] */
+#define SKBMARK_POLICY_RTNG_S   29
+#define SKBMARK_POLICY_RTNG_M   (0x07 << SKBMARK_POLICY_RTNG_S)
+#define SKBMARK_GET_POLICY_RTNG(MARK)  \
+    ((MARK & SKBMARK_POLICY_RTNG_M) >> SKBMARK_POLICY_RTNG_S)
+#define SKBMARK_SET_POLICY_RTNG(MARK, POLICY) \
+    ((MARK & ~SKBMARK_POLICY_RTNG_M) | (POLICY << SKBMARK_POLICY_RTNG_S))
+
+/* dpi_queue = mark[31:27] */
+/* Overlaps with SKBMARK_IFFWAN, SKBMARK_IPSEC, and SKBMARK_POLICY_RTNG  */
+#define SKBMARK_DPIQ_MARK_S    27
+#define SKBMARK_DPIQ_MARK_M    (0x1F << SKBMARK_DPIQ_MARK_S)
+#define SKBMARK_GET_DPIQ_MARK(MARK) \
+    ((MARK & SKBMARK_DPIQ_MARK_M) >> SKBMARK_DPIQ_MARK_S)
+#define SKBMARK_SET_DPIQ_MARK(MARK, DPIQ_MARK) \
+    ((MARK & ~SKBMARK_DPIQ_MARK_M) | (DPIQ_MARK << SKBMARK_DPIQ_MARK_S))
+
+/* The enet driver subdivides queue field (mark[4:0]) in the skb->mark into
+   priority and channel */
+/* priority = queue[2:0] (=>mark[2:0]) */
+#define SKBMARK_Q_PRIO_S        (SKBMARK_Q_S)
+#define SKBMARK_Q_PRIO_M        (0x07 << SKBMARK_Q_PRIO_S)
+#define SKBMARK_GET_Q_PRIO(MARK) \
+    ((MARK & SKBMARK_Q_PRIO_M) >> SKBMARK_Q_PRIO_S)
+#define SKBMARK_SET_Q_PRIO(MARK, Q) \
+    ((MARK & ~SKBMARK_Q_PRIO_M) | (Q << SKBMARK_Q_PRIO_S))
+/* channel = queue[4:3] (=>mark[4:3]) */
+#define SKBMARK_Q_CH_S          (SKBMARK_Q_S + 3)
+#define SKBMARK_Q_CH_M          (0x03 << SKBMARK_Q_CH_S)
+#define SKBMARK_GET_Q_CHANNEL(MARK) ((MARK & SKBMARK_Q_CH_M) >> SKBMARK_Q_CH_S)
+#define SKBMARK_SET_Q_CHANNEL(MARK, CH) \
+    ((MARK & ~SKBMARK_Q_CH_M) | (CH << SKBMARK_Q_CH_S))
+/* service_queue_enable_mark = mark[4] --  DS BRCM defined-- */
+#define SKBMARK_SQ_MARK_S    4
+#define SKBMARK_SQ_MARK_M    (0x01 << SKBMARK_SQ_MARK_S)
+#define SKBMARK_GET_SQ_MARK(MARK) \
+    ((MARK & SKBMARK_SQ_MARK_M) >> SKBMARK_SQ_MARK_S)
+#define SKBMARK_SET_SQ_MARK(MARK, SQ_MARK) \
+    ((MARK & ~SKBMARK_SQ_MARK_M) | (SQ_MARK << SKBMARK_SQ_MARK_S))
+
+#define SKBMARK_ALL_GEM_PORT  (0xFF) 
+
+#define WLAN_PRIORITY_BIT_POS  (1)
+#define WLAN_PRIORITY_MASK     (0x7 << WLAN_PRIORITY_BIT_POS)
+#define GET_WLAN_PRIORITY(VAL) ((VAL & WLAN_PRIORITY_MASK) >> WLAN_PRIORITY_BIT_POS)
+#define SET_WLAN_PRIORITY(ENCODEVAL, PRIO) ((ENCODEVAL & (~WLAN_PRIORITY_MASK)) | (PRIO << WLAN_PRIORITY_BIT_POS))
+
+#define WLAN_IQPRIO_BIT_POS    (0)
+#define WLAN_IQPRIO_MASK       (0x1 << WLAN_IQPRIO_BIT_POS)
+#define GET_WLAN_IQPRIO(VAL)   ((VAL & WLAN_IQPRIO_MASK) >> WLAN_IQPRIO_BIT_POS)
+#define SET_WLAN_IQPRIO(ENCODEVAL, IQPRIO) ((ENCODEVAL & (~WLAN_IQPRIO_MASK)) | (IQPRIO << WLAN_IQPRIO_BIT_POS))
+
+// LINUX_PRIORITY_BIT_POS_IN_MARK macro must be in sync with PRIO_LOC_NFMARK (=>mark[2:0])
+#define PRIO_LOC_NFMARK                  SKBMARK_Q_PRIO_S
+#define LINUX_PRIORITY_BIT_POS_IN_MARK   SKBMARK_Q_PRIO_S
+#define LINUX_PRIORITY_BIT_MASK          SKBMARK_Q_PRIO_M
+#define LINUX_GET_PRIO_MARK(MARK)        ((MARK & LINUX_PRIORITY_BIT_MASK) >> LINUX_PRIORITY_BIT_POS_IN_MARK)
+#define LINUX_SET_PRIO_MARK(MARK, PRIO)  ((MARK & (~LINUX_PRIORITY_BIT_MASK)) | (PRIO << LINUX_PRIORITY_BIT_POS_IN_MARK)) 
+
+//Encode 3 bits of priority and 1 bit of IQPRIO into 4 bits as follows (3bitPrio:1bitIQPrio)
+#define ENCODE_WLAN_PRIORITY_MARK(u8EncodeVal, u32Mark) \
+    (u8EncodeVal = SET_WLAN_PRIORITY(u8EncodeVal, LINUX_GET_PRIO_MARK(u32Mark)) | SET_WLAN_IQPRIO(u8EncodeVal, SKBMARK_GET_IQPRIO_MARK(u32Mark)))
+#define DECODE_WLAN_PRIORITY_MARK(encodedVal, u32Mark) \
+    do { (u32Mark) = LINUX_SET_PRIO_MARK(u32Mark, GET_WLAN_PRIORITY(encodedVal)); \
+        (u32Mark) = SKBMARK_SET_IQPRIO_MARK(u32Mark, GET_WLAN_IQPRIO(encodedVal)); \
+    } while(0)
+
+
+#endif /* _BCM_SKB_DEFINES_ */
diff --git a/include/linux/bcm_skbuff.h b/include/linux/bcm_skbuff.h
new file mode 100644
index 0000000000000000000000000000000000000000..94b9ad73f98e79b101b948f44f2a386ad9fb79e1
--- /dev/null
+++ b/include/linux/bcm_skbuff.h
@@ -0,0 +1,525 @@
+#ifndef _BCM_SKBUFF_H
+#define _BCM_SKBUFF_H
+
+#include <linux/net.h>
+
+#define CONFIG_SKBSHINFO_HAS_DIRTYP	1
+
+struct blog_t; /* defined(CONFIG_BLOG) */
+struct net_device;
+
+#ifndef NULL_STMT
+#define NULL_STMT		do { /* NULL BODY */ } while (0)
+#endif
+
+typedef void (*RecycleFuncP)(void *nbuff_p, unsigned long context, uint32_t flags);
+
+#define SKB_DATA_RECYCLE	(1 << 0)
+#define SKB_DATA_NO_RECYCLE	(~SKB_DATA_RECYCLE)
+#define SKB_RECYCLE		(1 << 1)
+#define SKB_NO_RECYCLE		(~SKB_RECYCLE)
+#define SKB_RECYCLE_NOFREE	(1 << 2) /* DO NOT USE */
+#define SKB_RECYCLE_FPM_DATA	(1 << 3) /* Data buffer from Runner FPM pool */
+#define SKB_RNR_FLOOD		(1 << 4) /* Data buffer flooded by Runner to flooding-capable ports */
+/* Indicates whether a sk_buf or a data buffer is in BPM pristine state */
+#define SKB_BPM_PRISTINE	(1 << 5)
+/* UDP Speed Test flags */
+#define SKB_RNR_UDPSPDT_BASIC	(1 << 6)
+#define SKB_RNR_UDPSPDT_IPERF3	(1 << 7)
+
+#define SKB_RNR_FLAGS		(SKB_RNR_FLOOD | SKB_RNR_UDPSPDT_BASIC | SKB_RNR_UDPSPDT_IPERF3)
+#define SKB_RNR_UDPSPDT_FLAGS	(SKB_RNR_UDPSPDT_BASIC | SKB_RNR_UDPSPDT_IPERF3)
+
+#define SKB_BPM_TAINTED(skb)						\
+({									\
+	((struct sk_buff *)skb)->recycle_flags &= ~SKB_BPM_PRISTINE;	\
+	(skb_shinfo(skb))->dirty_p = NULL;				\
+})
+
+
+#define SKB_DATA_PRISTINE(skb)						\
+({									\
+	(skb_shinfo(skb))->dirty_p = ((struct sk_buff *)skb)->head;	\
+})
+
+struct fkbuff;
+
+extern void skb_frag_xmit4(struct sk_buff *origskb, struct net_device *txdev,
+			   uint32_t is_pppoe, uint32_t minMtu, void *ip_p);
+extern void skb_frag_xmit6(struct sk_buff *origskb, struct net_device *txdev,
+			   uint32_t is_pppoe, uint32_t minMtu, void *ip_p);
+extern struct sk_buff *skb_xlate(struct fkbuff *fkb_p);
+extern struct sk_buff *skb_xlate_dp(struct fkbuff *fkb_p, uint8_t *dirty_p);
+extern int skb_avail_headroom(const struct sk_buff *skb);
+extern void skb_bpm_tainted(struct sk_buff *skb);
+
+extern int skb_avail_headroom(const struct sk_buff *skb);
+
+extern void skb_cb_zero(struct sk_buff *skb);
+
+extern size_t skb_size(void);
+extern size_t skb_aligned_size(void);
+extern int skb_layout_test(int head_offset, int tail_offset, int end_offset);
+
+/**
+ *	skb_headerinit	-	initialize a socket buffer header
+ *	@headroom: reserved headroom size
+ *	@datalen: data buffer size, data buffer is allocated by caller
+ *	@skb: skb allocated by caller
+ *	@data: data buffer allocated by caller
+ *	@recycle_hook: callback function to free data buffer and skb
+ *	@recycle_context: context value passed to recycle_hook, param1
+ *  @blog_p: pass a blog to a skb for logging
+ *
+ *	Initializes the socket buffer and assigns the data buffer to it.
+ *	Both the sk_buff and the pointed data buffer are pre-allocated.
+ *
+ */
+void skb_headerinit(unsigned int headroom, unsigned int datalen,
+		    struct sk_buff *skb, unsigned char *data,
+		    RecycleFuncP recycle_hook, unsigned long recycle_context,
+		    struct blog_t *blog_p);
+
+
+/* TODO avoid this detail here, nbuff/skbuff should just define this as
+ * uint32_t and wl driver should cast this to appropriate structure
+ */
+typedef union wlFlowInf {
+	uint32_t u32;
+	union {
+		union {
+			struct {
+				/* Start - Shared fields between ucast and mcast */
+				uint32_t is_ucast:1;
+				/* wl_prio is 4 bits for nic and 3 bits for dhd. Plan is
+				 * to make NIC as 3 bits after more analysis */
+				uint32_t wl_prio:4;
+				/* End - Shared fields between ucast and mcast */
+				uint32_t nic_reserved1:11;
+				uint32_t wl_chainidx:16;
+			};
+			struct {
+				uint32_t overlayed_field:16;
+				uint32_t ssid_dst:16; /* For bridged traffic we don't have chainidx (0xFE) */
+			};
+		} nic;
+
+		struct {
+			/* Start - Shared fields between ucast and mcast */
+			uint32_t is_ucast:1;
+			uint32_t wl_prio:4;
+			/* End - Shared fields between ucast and mcast */
+			/* Start - Shared fields between dhd ucast and dhd mcast */
+			uint32_t flowring_idx:10;
+			/* End - Shared fields between dhd ucast and dhd mcast */
+			uint32_t dhd_reserved:13;
+			uint32_t ssid:4;
+		} dhd;
+	} ucast;
+	struct {
+		/* Start - Shared fields between ucast and mcast */
+		/* for multicast, WFD does not need to populate this flowring_idx, it is used internally by dhd driver */
+		uint32_t is_ucast:1;
+		uint32_t wl_prio:4;
+		/* End - Shared fields between ucast and mcast */
+		/* Start - Shared fields between dhd ucast and dhd mcast */
+		uint32_t flowring_idx:10;
+		/* End - Shared fields between dhd ucast and dhd mcast */
+		uint32_t mcast_reserved:1;
+		uint32_t ssid_vector:16;
+	} mcast;
+
+	struct {
+		/* Start - Shared fields b/w ucast, mcast & pktfwd */
+		uint32_t is_ucast           : 1;    /* Start - Shared fields b/w ucast, mcast */
+		uint32_t wl_prio            : 4;    /* packet priority */
+		/* End - Shared fields between ucast, mcast & pktfwd */
+		uint32_t pktfwd_reserved    : 7;
+		uint32_t ssid               : 4;
+		uint32_t pktfwd_key         : 16;   /* pktfwd_key_t : 2b domain, 2b incarn, 12b index */
+	} pktfwd;
+} wlFlowInf_t;
+
+struct wlan_ext {
+
+	union {
+		__u32 wl_cb[6];
+		struct {
+			/* pktc_cb should hold space for void* and unsigned int */
+			unsigned char	pktc_cb[16];
+			__u16		pktc_flags; /* wl_flags */
+			__u16		dma_index; /* used by HND router for NIC Bulk Tx */
+			__u8		wl_flag1;  /* used for blog handle, only need one bit for now */
+			__u8		wl_rsvd;
+			__u16		wl_flowid; /* cfp flowid */
+		};
+	} __aligned(8);
+};
+
+#define SKB_VLAN_MAX_TAGS	4
+
+struct vlan_ext {
+	union {
+		struct {
+			__u32	reserved:31;
+			__u32	restore_rx_vlan:1; /* Restore Rx VLAN at xmit. Used in ONT mode */
+		};
+		__u32		bcm_flags_word;
+	} bcm_flags;
+	__u16			vlan_count;
+	__u16			vlan_tpid;
+	__u32			cfi_save;
+	__u32			vlan_header[SKB_VLAN_MAX_TAGS];
+	struct net_device	*rxdev;
+};
+
+#define MAP_FORWARD_NONE	0
+#define MAP_FORWARD_MODE1	1
+#define MAP_FORWARD_MODE2	2
+#define MAP_FORWARD_MODE3	3 /* MAP-E Pre-Fragmentation */
+
+struct map_ext {
+	__u8			map_forward:2;
+	__u8			map_mf:1;
+	__u32			map_offset;
+	__u32			map_id;
+};
+
+struct bcm_skb_ext {
+	struct wlan_ext wlan;
+	struct vlan_ext vlan;
+	struct map_ext map;
+
+	void *tunl; /* used to store tunl pointer */
+
+	unsigned char		*clone_wr_head; /* indicates drivers(ex:enet)about writable headroom in aggregated skb */
+	unsigned char		*clone_fc_head; /* indicates fcache about writable headroom in aggregated skb */
+
+	struct net_device	*in_dev; /* Physical device where this pkt is received */
+};
+
+/* accessor macro */
+#define skbuff_bcm_ext_wlan_get(_skb, _field)	((_skb)->bcm_ext.wlan._field)
+#define skbuff_bcm_ext_vlan_get(_skb, _field)	((_skb)->bcm_ext.vlan._field)
+#define skbuff_bcm_ext_map_get(_skb, _field)	((_skb)->bcm_ext.map._field)
+#define skbuff_bcm_ext_indev_get(_skb)			((_skb)->bcm_ext.in_dev)
+#define skbuff_bcm_ext_indev_set(_skb, _dev)	((_skb)->bcm_ext.in_dev = _dev)
+
+void bcm_skbuff_copy_skb_header(struct sk_buff *new, const struct sk_buff *old);
+void bcm_skbuff_skb_clone(struct sk_buff *n, struct sk_buff *skb);
+void bcm_skbuff_handle_netif_rx_internal(struct sk_buff *skb);
+void bcm_skbuff_handle_netif_receive_skb_core(struct sk_buff *skb);
+
+#if (defined(CONFIG_BCM_WLAN) || defined(CONFIG_BCM_WLAN_MODULE))
+int bcm_hook_br_handle_frame_finish(struct sk_buff *skb, int state);
+int bcm_hook_br_should_deliver(struct sk_buff *skb, int state);
+#else /* !CONFIG_BCM_WLAN */
+#define bcm_hook_br_handle_frame_finish(skb, state)	0
+#define bcm_hook_br_should_deliver(skb, state)		0
+#endif /* !CONFIG_BCM_WLAN */
+
+#if defined(CONFIG_BCM_USBNET_ACCELERATION)
+void skb_clone_headers_set(struct sk_buff *skb, unsigned int len);
+unsigned int skb_writable_headroom(const struct sk_buff *skb);
+#endif
+void skb_header_free(struct sk_buff *skb);
+struct sk_buff *skb_header_alloc(void);
+
+void skb_shinforeset(struct skb_shared_info *skb_shinfo);
+
+/* 
+ * sk_buff structure is copied directly from skbuff.h and removing any #ifdef except CONFIG_BCM_KF_NBUFF.
+ * This is on-purpose to solve binary incompatibility issue.
+ */
+
+#if defined(CONFIG_BCM_KF_MPTCP)
+#define BCM_SKB_CB_SIZE		80
+#else
+#define BCM_SKB_CB_SIZE		48
+#endif
+
+struct sk_buff {
+	union {
+		struct {
+			/* These two members must be first. */
+			struct sk_buff		*next;
+			struct sk_buff		*prev;
+
+			union {
+				struct net_device	*dev;
+				/* Some protocols might use this space to store information,
+				 * while device pointer would be NULL.
+				 * UDP receive path is one user.
+				 */
+				unsigned long		dev_scratch;
+			};
+		};
+		struct rb_node		rbnode; /* used in netem, ip4 defrag, and tcp stack */
+		struct list_head	list;
+	};
+
+	union {
+		struct sock		*sk;
+		int			ip_defrag_offset;
+	};
+
+	union {
+		ktime_t		tstamp;
+		u64		skb_mstamp;
+	};
+#if defined(CONFIG_BCM_KF_NBUFF)
+	__u32 unused;
+	union {
+		/* 3 bytes unused */
+		unsigned int recycle_and_rnr_flags;
+		unsigned int recycle_flags;
+	};
+	/*
+	 * Several skb fields have been regrouped together for better data locality
+	 * cache performance, 16byte cache line proximity.
+	 * In 32 bit architecture, we have 32 bytes of data before this comment.
+	 * In 64 bit architecture, we have 52 bytes of data at this point.
+	 */
+
+	/*--- members common to fkbuff: begin here ---*/
+	struct {
+		union {
+			/* see fkb_in_skb_test() */
+			void 			*fkbInSkb;
+			void			*word0;
+		};
+
+		/* defined(CONFIG_BLOG), use blog_ptr() */
+		struct blog_t		*blog_p;
+		unsigned char		*data;
+
+		/* The len in fkb is only 24 bits other 8 bits are used as internal flags
+		 * when fkbInSkb is used the max len can be only 24 bits, the bits 31-24
+		 * are cleared
+		 * currently we don't have a case where len can be >24 bits.
+		 */
+		union {
+			unsigned int	len;
+			/* used for fkb_in_skb test */
+			__u32		len_word;
+		};
+
+		union {
+			__u32		mark;
+			__u32		dropcount;
+			void		*queue;
+			/* have to declare the following variation of fkb_mark
+			 * for the ease of handling 64 bit vs 32 bit in fcache
+			 */
+			unsigned long	fkb_mark;
+			__u32       fc_ctxt; /* hybrid flow cache context */
+		};
+
+		union {
+			__u32		priority;
+			wlFlowInf_t	wl;
+		};
+
+		/* Recycle preallocated skb or data */
+		RecycleFuncP		recycle_hook;
+
+		union {
+			unsigned long	recycle_context;
+			struct sk_buff	*next_free;
+			__u32       fpm_num;
+		};
+#ifdef CONFIG_64BIT
+	}  ____cacheline_aligned;
+	/*
+	 * purposedly making the above fkbuff data structure cacheline aligned
+	 * in 64 bit architecture.
+	 * This can ensure the offset to the content is fixed into same cacheline.
+	 * Main reason we only declare as cacheline_aligned for 64 bit is that
+	 * we have manually calculated to ensure that this structure is 32 byte
+	 * aligned in 32 bit architecture.  If we add ____cacheline_aligned
+	 * also for 32 bit architecture, it will waste 64 byte memory if that
+	 * architecture is with 64 byte cache line size (i.e., 63148).
+	 */
+#else
+	};
+#endif
+	/*--- members common to fkbuff: end here ---*/
+
+
+#endif
+
+	struct bcm_skb_ext bcm_ext;
+
+	union {
+		struct {
+			unsigned long	_skb_refdst;
+			void		(*destructor)(struct sk_buff *skb);
+		};
+		struct list_head	tcp_tsorted_anchor;
+	};
+
+	struct	sec_path	*sp;
+	unsigned long		 _nfct;
+	struct nf_bridge_info	*nf_bridge;
+#if defined(CONFIG_BCM_KF_NBUFF)
+	unsigned int		data_len;
+#else
+	unsigned int		len,
+				data_len;
+#endif
+	__u16		mac_len,
+				hdr_len;
+
+	/* Following fields are _not_ copied in __copy_skb_header()
+	 * Note that queue_mapping is here mostly to fill a hole.
+	 */
+	__u16			queue_mapping;
+
+/* if you move cloned around you also must adapt those constants */
+#ifdef __BIG_ENDIAN_BITFIELD
+#define CLONED_MASK	(1 << 7)
+#else
+#define CLONED_MASK	1
+#endif
+#define CLONED_OFFSET()		offsetof(struct sk_buff, __cloned_offset)
+
+	__u8		__cloned_offset[0];
+	__u8		cloned:1,
+				nohdr:1,
+				fclone:2,
+				peeked:1,
+				head_frag:1,
+				xmit_more:1,
+				pfmemalloc:1;
+
+	/* fields enclosed in headers_start/headers_end are copied
+	 * using a single memcpy() in __copy_skb_header()
+	 */
+	/* private: */
+	__u32			headers_start[0];
+	/* public: */
+
+/* if you move pkt_type around you also must adapt those constants */
+#ifdef __BIG_ENDIAN_BITFIELD
+#define PKT_TYPE_MAX	(7 << 5)
+#else
+#define PKT_TYPE_MAX	7
+#endif
+#define PKT_TYPE_OFFSET()	offsetof(struct sk_buff, __pkt_type_offset)
+
+	__u8			__pkt_type_offset[0];
+	__u8			pkt_type:3;
+	__u8			ignore_df:1;
+	__u8			nf_trace:1;
+	__u8			ip_summed:2;
+	__u8			ooo_okay:1;
+
+	__u8			l4_hash:1;
+	__u8			sw_hash:1;
+	__u8			wifi_acked_valid:1;
+	__u8			wifi_acked:1;
+	__u8			no_fcs:1;
+	/* Indicates the inner headers are valid in the skbuff. */
+	__u8			encapsulation:1;
+	__u8			encap_hdr_csum:1;
+	__u8			csum_valid:1;
+
+	__u8			csum_complete_sw:1;
+	__u8			csum_level:2;
+	__u8			csum_not_inet:1;
+	__u8			dst_pending_confirm:1;
+	__u8			ndisc_nodetype:2;
+	__u8			ipvs_property:1;
+
+	__u8			inner_protocol_type:1;
+	__u8			remcsum_offload:1;
+	__u8			offload_fwd_mark:1;
+	__u8			offload_mr_fwd_mark:1;
+	__u8			tc_skip_classify:1;
+	__u8			tc_at_ingress:1;
+	__u8			tc_redirected:1;
+	__u8			tc_from_ingress:1;
+	__u8			decrypted:1;
+	__u16			tc_index;	/* traffic control index */
+
+	union {
+		__wsum		csum;
+		struct {
+			__u16	csum_start;
+			__u16	csum_offset;
+		};
+	};
+#ifdef CONFIG_BCM_KF_NBUFF
+#else
+	__u32			priority;
+#endif
+	int			skb_iif;
+	__u32			hash;
+	__be16			vlan_proto;
+	__u16			vlan_tci;
+	union {
+		unsigned int	napi_id;
+		unsigned int	sender_cpu;
+	};
+	__u32		secmark;
+
+#if defined(CONFIG_BCM_KF_NBUFF)
+	__u32		reserved_tailroom;
+#else
+	union {
+		__u32		mark;
+		__u32		reserved_tailroom;
+	};
+#endif
+
+	union {
+		__be16		inner_protocol;
+		__u8		inner_ipproto;
+	};
+
+	__u16			inner_transport_header;
+	__u16			inner_network_header;
+	__u16			inner_mac_header;
+
+	__be16			protocol;
+	__u16			transport_header;
+	__u16			network_header;
+	__u16			mac_header;
+
+	/* private: */
+	__u32			headers_end[0];
+
+	/*
+	 * This is the control buffer. It is free to use for every
+	 * layer. Please put your private variables there. If you
+	 * want to keep them across layers you have to do a skb_clone()
+	 * first. This is owned by whoever has the skb queued ATM.
+	 */
+	char			cb[BCM_SKB_CB_SIZE] __aligned(8);
+
+/*
+ * ------------------------------- CAUTION!!! ---------------------------------
+ * Do NOT add a new field or modify any existing field(except cb) before this 
+ * line to the beginning of the struct sk_buff. Doing so will cause 
+ * struct sk_buff to be incompatible with the compiled binaries and may cause 
+ * the binary only modules to crash.
+ * ---------------------------------------------------------------------------
+ */
+
+	/* public: */
+
+	/* These elements must be at the end, see alloc_skb() for details.  */
+	sk_buff_data_t		tail;
+	sk_buff_data_t		end;
+#if defined(CONFIG_BCM_KF_NBUFF)
+	unsigned char		*head;
+#else
+	unsigned char		*head,
+				*data;
+#endif
+	unsigned int		truesize;
+	refcount_t		users;
+};
+
+
+#endif	/* _BCM_SKBUFF_H */
diff --git a/include/linux/blog.h b/include/linux/blog.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7097ae129ae26e4fd7b24ed7d32085555cb281e
--- /dev/null
+++ b/include/linux/blog.h
@@ -0,0 +1,3116 @@
+#if defined(CONFIG_BLOG)
+
+#ifndef __BLOG_H_INCLUDED__
+#define __BLOG_H_INCLUDED__
+
+/*--------------------------------*/
+/* Blog.h and Blog.c for Linux OS */
+/*--------------------------------*/
+
+/* 
+* <:copyright-BRCM:2003:DUAL/GPL:standard
+* 
+*    Copyright (c) 2003 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+:>
+*/
+
+/*
+ *******************************************************************************
+ *
+ * File Name  : blog.h
+ *
+ * Description:
+ *
+ * A Blog is an extension of the native OS network stack's packet context.
+ * In Linux a Blog would be an extension of the Linux socket buffer (aka skbuff)
+ * or a network device driver level packet context FkBuff. The nbuff layer
+ * provides a transparent access SHIM to the underlying packet context, may it
+ * be a skbuff or a fkbuff. In a BSD network stack, a packet context is the
+ * BSD memory buffer (aka mbuff).
+ *
+ * Blog layer provides Blog clients a SHIM to the native OS network stack:
+ * Blog clients may be implemented to:
+ *  - debug trace a packet as it passes through the network stack,
+ *  - develop traffic generators (loop) at the network device driver level.
+ *  - develop network driver level promiscuous mode bound applications and use
+ *    the Blog SHIM to isolate themselves from the native OS network constructs
+ *    or proprietery network constructs such as Ethernet bridges, VLAN network
+ *    interfaces, IGMP, firewall and connection tracking systems.
+ *
+ * As such, Blog provides an extension of the packet context and contains the
+ * received and transmitted packets data and parsed information. Parsing results
+ * are saved to describe, the type of layer 1, 2, 3 and 4 headers seen, whether
+ * the packet was a unicast, broadcast or multicast, a tunnel 4in6 or 6in4 etc.
+ *
+ * Blog views a receive or transmit end-point to be any construct that can be
+ * described by a end point context and a handler op. An end-point could hence
+ * be a:
+ *  - a network device (Linux net_device with hard start transmit handler),
+ *  - a link or queue in the network stack (e.g. a Linux Traffic Control queue
+ *    or a netlink or raw socket queue),
+ *  - a file system logging interface and its logging handler,
+ *  - a virtual interface to some hardware block that provides some hardware
+ *    assisted functionality (e.g. IPSEC acceleration or checksum offloading
+ *    or GSO block),
+ *  - a raw interface to an external hardware test traffic generator using say
+ *    a DMA mapped packet reception or transmission.
+ *
+ * Blog clients are hence applications that provide value added capability by
+ * binding at such end-points.
+ *
+ * A simple Blog client application is a loop traffic generator that simply
+ * acts as a sink of packets belonging to a specific "l3 flow" and mirrors
+ * them to another interface or loops them back into the stack by serving as a
+ * source to a receive network device, while measuring the packet processing
+ * datapath performance in the native OS network stack/proprietary constructs.
+ * Such a loop traffic generator could be used to inject N cells/packets
+ * that cycle through the system endlessly, serving as background traffic while
+ * a few flows are studied from say a QOS perspective.
+ *
+ * Another example of a Blog client is a proxy accelerator (hardware / software)
+ * that is capable of snooping on specific flows and accelerating them while
+ * bypassing the native OS network stack and/or proprietery constructs. It is
+ * however required that the native OS constructs can co-exist. E.g. it may be
+ * necessary to refresh a network bridge's ARL table, or a connection/session
+ * tracker, or update statistics, when individual packets bypass such network
+ * constructs. A proxy accelerator may also reside between a Rx network device
+ * a hardware IPSEC accelerator block and a Tx network device.
+ *
+ * Blog layer provides a logical composite SHIM to the network constructs
+ * Linux or proprietery, allowing 3rd party network constructs to be seemlesly
+ * supported in the native OS.  E.g a network stack that uses a proprietery
+ * session tracker with firewalling capability would need to be transparently
+ * accessed, so that a Blog client may refresh the session tracking object when
+ * packets bypass the network stack.
+ *
+ * For each OS (eCOS, Linux, BSD) a blog.c implementation file is provided that
+ * implements the OS specific SHIM. Support for 3rd-party network constructs
+ * would need to be defined in the blog.c . E.g. for Linux, if a proprietery
+ * session tracker replaces the Linux netfilter connection tracking framework,
+ * then the void * ct_p and the corresponding query/set operations would need to
+ * be implemented. The Blog clients SHOULD NOT rely on any function other than
+ * those specifically defined allowing a coexistence of the Blog client and the
+ * native construct. In the example of a ct_p, for all practice and purposes,
+ * the void *, could have been a key or a handle to a connection tracking object
+ *
+ * Likewise, the Blog client may save need to save a client key with the
+ * network constuct. Again a client key may be a pointer to a client object or
+ * simply a hash key or some handle semantics.
+ *
+ * The logical SHIM is defined as follows:
+ *
+ * __doc_include_if_linux__
+ *
+ * 1. Extension of a packet context with a logging context:
+ * ========================================================
+ *   Explicit APIs to allocate/Free a Blog structure, and bind to the packet
+ *   context, may it be a skbuff or a fkbuff. Support for transferring a
+ *   Blog_t structure from one packet context to another during the course of
+ *   a packet in the network stack involving a packet context clone/copy is
+ *   also included. The release and recycling of Blog_t structures when a 
+ *   packet context is freed are also providied.
+ *   Binding is bi-directional: packet context <-- --> Blog_t
+ * 
+ *
+ * 2. Associating native OS or 3rd-party network constructs: blog_link()
+ * ==========================================================================
+ *   Examples of network constructs
+ *      "dev"   - Network device 
+ *      "ct"    - Connection or session tracker
+ *      "fdb"   - Network bridge forwarding database entity
+ *
+ *   Association is pseudo bi-directional, using "void *" binding in a Blog_t to
+ *   a network construct. In the reverse, a network construct will link to a
+ *   Blog client entity using a Key concept. Two types of keys are currently
+ *   employed, a BlogFlowKey and a BlogGroupKey. 
+ *
+ *   A BlogFlowKey would typically refer to a single unidirectional packet
+ *   stream defined by say all packets belonging to a unidirectional IPv4 flow,
+ *   whereas a BlogGroupKey could be used to represent a single downstream
+ *   multicast stream (IP multicast group) that results in replicated streams
+ *   pertaining to multiple clients joining a the IPv4 multicast group.
+ *
+ *   Likewise, one may represent a single unidirectional IPv4 UDP flow using
+ *   BlogFlowKey, and the reverse direction IPv4 UDP reply flow
+ *   using another BlogFlowKey, and represent the mated pair using a
+ *   BlogGroupKey.
+ *
+ *   In a Blog traffic generator client, where in several IPv4 UDP flows, each
+ *   represented independently using a BlogFlowKey, allows for a set of them
+ *   (background downstream stress traffic) to be managed as a group using a
+ *   BlogGroupKey.
+ *
+ *   Designer Note:
+ *   A network construct may be required to save a BlogFlowKey and/or
+ *   BlogGroupKey to complete the reverse binding between a network construct
+ *   and the Blog client application. An alternate approach would be to save
+ *   a pointer to the Blog_t in the network construct with an additional
+ *   dereference through the keys saved within the Blog_t object.
+ *
+ *   A BlogFlowKey and a BlogGroupKey is a 32bt sized unit and can serve either
+ *   as a pointer (32bit processor) or a index or a hash key or ...
+ *
+ *
+ * 3. Network construct and Blog client co-existence call backs:
+ * =============================================================
+ *
+ * blog_notify():
+ * ==============
+ * A network construct may notify a Blog client of a change of status and may
+ * be viewed as a "downcall" from specialized network construct to a Blog client
+ * E.g. if a connection/session tracking system deems that a flow needs to be
+ * deleted or say it itself is being destroyed, then it needs to notify the Blog
+ * client. This would allow the Blog client to cleanup any association with the
+ * network construct.
+ * Ability for a Blog client to receive general system wide notifications of
+ * changes, to include, network interfaces or link state changes, protocol stack
+ * service access point changes, etc.
+ * Designer Note: Linux notification list?
+ *
+ * blog_request():
+ * ===============
+ * A Blog client may request a change in state in the network construct and may
+ * be viewed as a "upcall" from the Blog client into the network construct. A
+ * timer refresh of the bridge fdb or connection tracking object, or a query
+ * whether the session tracker has successfully established (e.g. a TCP 3-way
+ * handshake has completed, or a IGMP client was permitted to join a group, or a
+ * RTSP session was successful) a uni-driectional or bi-directional flow.
+ *
+ *
+ * 4. Network end-point binding of Blog client
+ * ===========================================
+ *
+ * blog_init(), blog_sinit(), blog_finit():
+ * ========================================
+ * __comment_if_linux__ : This function is invoked by a Linux network device on
+ * packet reception to pass the packet to a Blog client application.
+ *
+ * Pass a packet context to a Blog client at a "RX" network device either using
+ * a skbuff or a fkbuff packet context. Blog client MAY ONLY ACCESS fkbuff
+ * fields. As per the nbuff specification, a FkBuff may be considered as a
+ * base class and a skbuff is a derived class, inheriting the base class members
+ * of the base class, fkbuff. The basic fields of a packet context are a pointer
+ * to the received packet's data, data length, a set of reserved fields to carry
+ * layer 1 information, queue priority, etc, and packet context and or packet
+ * recycling. The layer 1 information is described in terms of channels and
+ * and link layer phy preambles. A channel could be an ATM VCI, a DSL queue, a
+ * PON Gem Port. A Phy could describe the LINK layer type and or a preamble for
+ * instance a RFC2684 header in the DSL world.
+ *
+ * blog_[s|f]init() will setup the L1 coarse key<channel,phy> and invokes a Blog
+ * client's receive hook. A Blog client may consume the packet bypassing the
+ * native OS network stack, may suggest that the packet context be extended by
+ * a Blog_t structure or may deem that the packet is of not interest. As such
+ * the Blog client will return PKT_DONE, PKT_BLOG or PKT_NORM, respectively. In
+ * case no Blog client has been registered for receiving packets (promiscuous)
+ * driectly from RX network devices, then the packet will follow a normal data
+ * path within the network stack (PKT_NORM).
+ *
+ * Designer Note: Blog clients MAY NOT use fields not defined in FkBuff.
+ * 
+ *
+ * blog_emit():
+ * ============
+ * __comment_if_linux__ : This function is invoked by a Linux network device
+ * prior to packet transmission to pass the packet to a Blog client application.
+ *
+ * Pass a packet context to a Blog client at a "TX" network device either using
+ * a skbuff or a fkbuff packet context. The same restrictions on a Blog client
+ * pertaining to packet field context access as defined in the blog_init()
+ * variant of APIs is applicable to blog_emit(). A Blog client may also return
+ * PKT_NORM or PKT_DONE, to indicate normal processing, or packet consumption.
+ *
+ * Designer Note: blog_emit() will ONLY pass those packets to Blog clients that
+ * have a packet context extended with a Blog_t structure. Hence skbuffs or
+ * fkbuffs that do not have a Blog_t extension will not be handed to the Blog
+ * client. Do we need blog_semit/blog_femit variants.
+ *
+ *
+ * 5. Binding Blog client applications: blog_bind()
+ * ================================================
+ * blog_bind() enables a "single" client to bind into the network stack by
+ * specifying a network device packet reception handler, a network device packet
+ * transmission handler, network stack to blog client notify hook.
+ *
+ *
+ * 6. Miscellanous
+ * ===============
+ * - Blog_t management.
+ * - Data-filling a Blog_t.
+ * - Protocol Header specifications independent of OS.
+ * - Debug printing.
+ *
+ *
+ * __end_include_if_linux__
+ *
+ *  Version 1.0 SKB based blogging
+ *  Version 2.0 NBuff/FKB based blogging (mbuf)
+ *  Version 2.1 IPv6 Support
+ *  Version 3.0 Restructuring Blog SHIM to support eCOS, Linux and proprietery
+ *              network constructs
+ *
+ *******************************************************************************
+ */
+
+#define BLOG_VERSION            "v3.0"
+
+#if defined(__KERNEL__)                 /* Kernel space compilation           */
+#include <linux/types.h>                /* LINUX ISO C99 7.18 Integer types   */
+#else                                   /* User space compilation             */
+#include <stdint.h>                     /* C-Lib ISO C99 7.18 Integer types   */
+#endif
+#include <linux/blog_net.h>             /* IEEE and RFC standard definitions  */
+#include <linux/nbuff_types.h>          /* for IS_SKBUFF_PTR                  */
+#include <linux/brcm_dll.h>
+
+#ifndef NULL_STMT
+#define NULL_STMT                   do { /* NULL BODY */ } while (0)
+#endif
+
+#undef  BLOG_DECL
+#define BLOG_DECL(x)                x,
+
+#ifndef BLOG_OFFSETOF
+#define BLOG_OFFSETOF(stype, member)     ((size_t) &((struct stype *)0)->member)
+#endif
+
+/* Forward declarations */
+struct blog_t;
+typedef struct blog_t Blog_t;
+#define BLOG_NULL                   ((Blog_t*)NULL)
+#define BLOG_KEY_NONE               0
+
+/* __bgn_include_if_linux__ */
+
+struct sk_buff;                         /* linux/skbuff.h                     */
+struct fkbuff;                          /* linux/nbuff.h                      */
+
+/* See RFC 4008 */
+
+
+typedef struct blogCtTimeFlags {
+    uint32_t        unused: 31;
+    uint32_t        valid: 1;   /* BlogCtTime has valid values */
+} BlogCtTimeFlags_t;
+
+/* used to pass timer info between the stack and blog layer */
+typedef struct blogCtTime {
+    BlogCtTimeFlags_t flags;        /* Flags */
+    uint8_t         unknown;        /* unknown proto */
+    uint8_t         proto;          /* known proto TCP, UDP */
+    uint8_t         intv;           /* intv in sec */
+    uint8_t         idle;           /* idle time in sec */
+} BlogCtTime_t;
+
+/* used to exchange info between fcache and drivers */
+typedef struct {
+    uint32_t h_proto;    /* protocol */
+    uint32_t key_match;  /* key */
+    void     *txdev_p;
+    uint8_t tx_l3_offset;
+    uint8_t tx_l4_offset;
+    uint8_t mcast_fwd_exception; /* Runner mcast forwarding exception */
+    uint8_t esp_ivsize;
+    uint8_t esp_icvsize;
+} BlogFcArgs_t;
+
+typedef struct {
+    uint64_t rx_packets;
+    uint64_t rx_bytes;
+    int32_t  rx_rtp_packets_lost; /*TODO chekc why this is defined as signed int */
+    uint32_t pollTS_ms; // Poll timestamp in ms
+}BlogFcStats_t;
+
+typedef struct {
+    u64 packet_count;
+    u64 byte_count;
+} blog_fast_stats_t;
+
+/*
+ * Linux Netfilter Conntrack registers it's conntrack refresh function which
+ * will be invoked to refresh a conntrack when packets belonging to a flow
+ * managed by Linux conntrack are bypassed by a Blog client.
+ */
+typedef void (*blog_cttime_upd_t)(void * ct_p, BlogCtTime_t *ct_time_p);
+extern blog_cttime_upd_t blog_cttime_update_fn;
+
+
+extern int blog_ct_get_stats(const void *ct, uint32_t blog_key, uint32_t dir,
+        BlogFcStats_t *stats);
+extern int blog_ct_push_stats(void);
+
+#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE)
+typedef int (*blog_gre_rcv_check_t)(void *dev, BlogIpv4Hdr_t *iph, uint16_t len, 
+              void **tunl_pp, uint32_t *pkt_seqno_p);
+extern blog_gre_rcv_check_t blog_gre_rcv_check_fn;
+
+typedef int (*blog_gre_xmit_upd_t)(void * tunl_p, BlogIpv4Hdr_t *iph, uint16_t len);
+extern blog_gre_xmit_upd_t blog_gre_xmit_update_fn;
+typedef int (*blog_gre6_rcv_check_t)(void *dev, BlogIpv6Hdr_t *ipv6h, uint16_t len, 
+              void **tunl_pp, uint32_t *pkt_seqno_p);
+extern blog_gre6_rcv_check_t blog_gre6_rcv_check_fn;
+
+typedef int (*blog_gre6_xmit_upd_t)(void * tunl_p, BlogIpv6Hdr_t *ipv6h, uint16_t len);
+extern blog_gre6_xmit_upd_t blog_gre6_xmit_update_fn;
+#endif
+
+
+#define PPTP_NOT_ACK 0
+#define PPTP_WITH_ACK 1
+#define PPTP_GRE_VER_0 0
+#define PPTP_GRE_VER_1 1
+#define PPTP_GRE_NONE 2
+
+typedef int (*blog_pptp_xmit_upd_t)(uint16_t call_id, uint32_t seqNum, 
+                                    uint32_t ackNum, uint32_t daddr);
+extern blog_pptp_xmit_upd_t blog_pptp_xmit_update_fn;
+
+typedef int (*blog_pptp_xmit_get_t)(uint16_t call_id, uint32_t* seqNum, 
+                                    uint32_t* ackNum, uint32_t daddr);
+extern blog_pptp_xmit_get_t blog_pptp_xmit_get_fn;
+
+typedef int (*blog_pptp_rcv_check_t)(uint16_t call_id, uint32_t *rcv_pktSeq, 
+                                     uint32_t rcv_pktAck, uint32_t saddr);
+extern blog_pptp_rcv_check_t blog_pptp_rcv_check_fn;
+ 
+typedef int (*blog_l2tp_rcv_check_t)(void *dev, uint16_t tunnel_id, 
+                                     uint16_t session_id);
+extern blog_l2tp_rcv_check_t blog_l2tp_rcv_check_fn;
+
+#if defined(CONFIG_BCM_OVS)
+typedef int (* blog_is_ovs_internal_dev_t)(void *dev);
+typedef unsigned long (* blog_mega_get_key_t)(void *mega);
+typedef void (* blog_mega_set_key_t)(void *mega, unsigned long blog_key);
+typedef void (* blog_mega_put_fast_stats_t)(void *net_p, 
+        const blog_fast_stats_t *stats);
+
+typedef struct {
+    blog_is_ovs_internal_dev_t is_ovs_internal_dev;
+    blog_mega_get_key_t        mega_get_key;
+    blog_mega_set_key_t        mega_set_key;
+    blog_mega_put_fast_stats_t mega_put_fast_stats;
+} blog_ovs_hooks_t;
+void blog_bind_ovs(blog_ovs_hooks_t *blog_ovs_hooks_p);
+#endif
+
+/* __end_include_if_linux__ */
+
+
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes a Blog client,
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+        BLOG_DECL(BlogClient_fcache)
+        BLOG_DECL(BlogClient_mcast)
+        BLOG_DECL(BlogClient_MAX)
+} BlogClient_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes whether a packet is consumed and freed by a Blog client application,
+ * whether a packet needs to be processed normally within the network stack or
+ * whether a packet context is extended with a Blog_t object.
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+        BLOG_DECL(PKT_DONE)             /* Packet consumed and freed          */
+        BLOG_DECL(PKT_NORM)             /* Continue normal stack processing   */
+        BLOG_DECL(PKT_BLOG)             /* Continue stack with blogging       */
+        BLOG_DECL(PKT_DROP)             /* Drop Packet                        */
+        BLOG_DECL(PKT_TCP4_LOCAL)       /* ipv4 tcp packet terminating locally*/
+        BLOG_DECL(BLOG_ACTION_MAX)
+} BlogAction_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes the direction in the network stack when a packet is processed by a
+ * virtual network interface/network device.
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+        BLOG_DECL(DIR_RX)               /* Receive path in network stack      */
+        BLOG_DECL(DIR_TX)               /* Transmit path in network stack     */
+        BLOG_DECL(BLOG_DIR_MAX)
+} BlogDir_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes the type of Network entity associated with a Blog_t.
+ *
+ * BlogNetEntity_t may be linked to a blog using blog_link to make the Blog_t
+ * point to the BlogNetEntity_t. A reverse linking from the BlogNetEntity_t to
+ * Blog_t is only possible via a key (if necessary when a one to one association
+ * between the BlogNetEntity_t and a Blog exists. For instance, there is a
+ * one to one association between a Flow Connection Tracker and a Blog. In fact
+ * a Linux Netfilter Connection Tracking object manages a bi-directional flow
+ * and thus may have 2 keys to reference the corresponding Blog_t. However, a
+ * network device (physical end device or a virtual device) may have multiple
+ * Flows passing through it and hence no one-to-one association exists. In this
+ * can a Blog may have a link to a network device, but the reverse link (via a
+ * key) is not saved in the network device.
+ *
+ * Linking a BlogNetEntity_t to a blog is done via blog_link() whereas saving
+ * a reference key into a BlogNetEntity_t is done via blog_request() by the
+ * Blog client application, if needed.
+ *
+ *------------------------------------------------------------------------------
+ */
+
+#define BLOG_CT_PLD             0U
+#define BLOG_CT_DEL             1U
+#define BLOG_CT_MAX             2U
+
+/* FLOWTRACK: param1 is ORIG=0 or REPLY=1 direction */
+#define BLOG_PARAM1_DIR_ORIG    0U
+#define BLOG_PARAM1_DIR_REPLY   1U
+#define BLOG_PARAM1_DIR_MAX     2U
+
+/* FLOWTRACK: param2 is IPv4=0, IPv6=1, GRE=2, L2TP=3 */
+#define BLOG_PARAM2_IPV4        0U
+#define BLOG_PARAM2_IPV6        1U
+#define BLOG_PARAM2_GRE_IPV4    2U
+#define BLOG_PARAM2_L2TP_IPV4   3U
+#define BLOG_PARAM2_MAX         4U
+#define BLOG_CT_VER_MAX         2U
+
+/* MAP_TUPLE: param1 is US=0 or DS=1 direction */
+#define BLOG_PARAM1_MAP_DIR_US  BLOG_PARAM1_DIR_ORIG
+#define BLOG_PARAM1_MAP_DIR_DS  BLOG_PARAM1_DIR_REPLY
+
+/* BRIDGEFDB: param1 is src|dst */
+#define BLOG_PARAM1_SRCFDB      0U
+#define BLOG_PARAM1_DSTFDB      1U
+
+/* LLID/GEM index for the mcast data received at WAN side. 0xFE means any value is acceptable */
+#define BLOG_CHAN_XPON_MCAST_ANY 0xFE
+
+/* IF_DEVICE: param1 is direction RX or TX, param 2 is minMtu */
+
+typedef enum {
+        BLOG_DECL(FLOWTRACK)            /* Flow (connection|session) tracker  */
+        BLOG_DECL(BRIDGEFDB)            /* Bridge Forwarding Database entity  */
+        BLOG_DECL(MCAST_FDB)            /* Multicast Client FDB entity        */
+        BLOG_DECL(IF_DEVICE)            /* Virtual Interface (network device) */
+        BLOG_DECL(IF_DEVICE_MCAST)      /* Virtual Interface (network device) */
+        BLOG_DECL(GRE_TUNL)             /* GRE Tunnel                         */
+        BLOG_DECL(TOS_MODE)             /* TOS_MODE                           */
+        BLOG_DECL(MAP_TUPLE)            /* Flow (MAP-T connection) tracker    */
+        BLOG_DECL(MEGA)                 /* Megaflow tracker                   */
+        BLOG_DECL(BLOG_NET_ENTITY_MAX)
+} BlogNetEntity_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes a type of notification sent from the network stack to the Blog client
+ * See blog_notify(BlogNotify_t, void *, unsigned long param1, uint32_t param2);
+ *------------------------------------------------------------------------------
+ */
+
+/* MCAST_CONTROL_EVT: param1 is add|del, and param2 is IPv4|IPv6 */ 
+#define BLOG_PARAM1_MCAST_ADD       0U
+#define BLOG_PARAM1_MCAST_DEL       1U
+#define BLOG_PARAM2_MCAST_IPV4      0U
+#define BLOG_PARAM2_MCAST_IPV6      1U
+
+/* LINK_STATE_CHANGE: param1 */
+#define BLOG_PARAM1_LINK_STATE_UP   0U
+#define BLOG_PARAM1_LINK_STATE_DOWN 1U
+
+typedef enum {
+        BLOG_DECL(DESTROY_FLOWTRACK)    /* Session/connection is deleted      */
+        BLOG_DECL(DESTROY_BRIDGEFDB)    /* Bridge FDB has aged                */
+        BLOG_DECL(MCAST_CONTROL_EVT)    /* Mcast client joins a group event   */
+        BLOG_DECL(MCAST_SYNC_EVT)       /* Topology change for mcast event    */
+        BLOG_DECL(DESTROY_NETDEVICE)    /* Network device going down          */
+        BLOG_DECL(FETCH_NETIF_STATS)    /* Fetch accumulated stats            */
+        BLOG_DECL(CLEAR_NETIF_STATS)    /* Clear accumulated stats            */
+        BLOG_DECL(DYNAMIC_DSCP_EVENT)   /* Dynamic DSCP change event          */
+        BLOG_DECL(UPDATE_NETDEVICE)     /* Netdevice has been modified (MTU, etc) */
+        BLOG_DECL(ARP_BIND_CHG)         /* ARP IP/MAC binding change event    */
+        BLOG_DECL(CONFIG_CHANGE)        /* Certain configuration change event */
+        BLOG_DECL(UP_NETDEVICE)         /* network device up                  */
+        BLOG_DECL(DN_NETDEVICE)         /* network device down                */
+        BLOG_DECL(CHANGE_ADDR)          /* network device change MAC addr     */
+        BLOG_DECL(SET_DPI_PARAM)        /* Set the DPI parameters             */
+        BLOG_DECL(DESTROY_MAP_TUPLE)    /* MAPT Session/connection is deleted */
+        BLOG_DECL(FLUSH)                /* Flush flows based on parameters    */
+        BLOG_DECL(DESTROY_MEGA)         /* Megaflow connection is deleted     */
+        BLOG_DECL(FETCH_MEGA_STATS)     /* Fetch megaflow fast stats          */
+        BLOG_DECL(CLEAR_MEGA_STATS)     /* Clear megaflow fast stats          */
+        BLOG_DECL(UPDATE_FLOWTRACK_IDLE_TIMEOUT)/* update idle timeout		  */
+        BLOG_DECL(BLOG_NOTIFY_MAX)
+} BlogNotify_t;
+
+typedef enum {
+        BLOG_DECL(QUERY_FLOWTRACK)      /* Session/connection time is queried */
+        BLOG_DECL(QUERY_BRIDGEFDB)      /* Bridge FDB time is queried         */
+        BLOG_DECL(QUERY_MAP_TUPLE)      /* MAP-T connection time is queried   */
+        BLOG_DECL(QUERY_FLOWTRACK_STATS)/* get stats of flows associated with NPE */
+        BLOG_DECL(QUERY_GET_HW_ACCEL)
+        BLOG_DECL(BLOG_QUERY_MAX)
+} BlogQuery_t;
+
+typedef struct{
+    int orig_queue;                     /* Originating queue index */
+    int reply_queue;                    /* Reply queue index */
+    int priority;                       /* Traffic priority */
+}BlogDpiParams_t;
+
+
+/* Blog Notify FLUSH strucutre */
+typedef int (* BlogFlushMetadataFunc_t)(void *metadata_p, const Blog_t *const blog_p);
+
+typedef struct {
+    uint32_t flush_all      :1;
+    uint32_t flush_flow     :1;
+    uint32_t flush_dev      :1;
+    uint32_t flush_dstmac   :1;
+    uint32_t flush_srcmac   :1;
+    uint32_t flush_meta     :1;         /* Not available through Userspace/CLI */
+    uint32_t flush_hw       :1;         /* Flush all flows from HW */
+    uint32_t flush_unused   :25;
+    uint8_t mac[6];
+    int devid;
+    int flowid;
+    void *metadata_p;                   /* flush_meta = 1 ; Must set metadata_p, devid & flush_dev */
+    BlogFlushMetadataFunc_t func_p;     /* flush_meta = 1 ; Must provide callback func */
+}BlogFlushParams_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes a type of request from a Blog client to a network stack entity.
+ *------------------------------------------------------------------------------
+ */
+
+typedef enum {
+        BLOG_DECL(FLOWTRACK_KEY_SET)    /* Set Client key into Flowtracker    */
+        BLOG_DECL(FLOWTRACK_KEY_GET)    /* Get Client key into Flowtracker    */
+        BLOG_DECL(FLOWTRACK_DSCP_GET)   /* Get DSCP from Flow tracker:DYNDSCP */
+        BLOG_DECL(FLOWTRACK_CONFIRMED)  /* Test whether session is confirmed  */
+        BLOG_DECL(FLOWTRACK_ALG_HELPER) /* Test whether flow has an ALG       */
+        BLOG_DECL(FLOWTRACK_EXCLUDE)    /* Clear flow candidacy by Client     */
+        BLOG_DECL(FLOWTRACK_TIME_SET)   /* Set time in a flow tracker         */
+        BLOG_DECL(FLOWTRACK_IDLE_TIMEOUT_GET)  /* get idle timeout in a flow tracker  */
+        BLOG_DECL(FLOWTRACK_PUT_STATS)  /* Push accumulated stats to conntrack*/
+        BLOG_DECL(NETIF_PUT_STATS)      /* Push accumulated stats to devices  */
+        BLOG_DECL(LINK_XMIT_FN)         /* Fetch device link transmit function*/
+        BLOG_DECL(LINK_NOCARRIER)       /* Fetch device link carrier          */
+        BLOG_DECL(NETDEV_NAME)          /* Network device name                */
+        BLOG_DECL(MCAST_DFLT_MIPS)      /* Delete action in blogRule chain    */
+        BLOG_DECL(IQPRIO_SKBMARK_SET)   /* Set IQOS Prio in skb->mark         */
+        BLOG_DECL(DPIQ_SKBMARK_SET)     /* Set DPIQ in skb->mark              */
+        BLOG_DECL(BRIDGEFDB_KEY_SET)    /* Set Client key into bridge FDB     */
+        BLOG_DECL(BRIDGEFDB_KEY_GET)    /* Get Client key into bridge FDB     */
+        BLOG_DECL(BRIDGEFDB_TIME_SET)   /* Refresh bridge FDB time            */
+        BLOG_DECL(SYS_TIME_GET)         /* Get the system time in jiffies     */
+        BLOG_DECL(GRE_TUNL_XMIT)        /* GRE Tunnel tx                      */
+        BLOG_DECL(GRE6_TUNL_XMIT)       /* GRE6 Tunnel tx                      */
+        BLOG_DECL(SKB_DST_ENTRY_SET)    /* get dst_entry from skb             */
+        BLOG_DECL(SKB_DST_ENTRY_RELEASE)/* release dst_entry from blog        */
+        BLOG_DECL(NETDEV_ADDR)          /* Device MAC addr                    */
+        BLOG_DECL(FLOW_EVENT_ACTIVATE)  /* Flow Activation event              */
+        BLOG_DECL(FLOW_EVENT_DEACTIVATE)/* Flow Deactivation event            */
+        BLOG_DECL(CHK_HOST_DEV_MAC)     /* Check Dev HostMAC for addition     */
+        BLOG_DECL(MAP_TUPLE_KEY_SET)    /* Set Client key into MAPT Tuple     */
+        BLOG_DECL(MAP_TUPLE_KEY_GET)    /* Get Client key into MAPT Tuple     */
+        BLOG_DECL(MEGA_KEY_SET)         /* Set Client key into megaflow       */
+        BLOG_DECL(MEGA_KEY_GET)         /* Get Client key into megaflow       */
+        BLOG_DECL(MEGA_PUT_STATS)       /* Put the stats in a megaflow        */
+        BLOG_DECL(BLOG_REQUEST_MAX)
+} BlogRequest_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Denotes a type of update to an existing Blog flow.
+ *------------------------------------------------------------------------------
+ */
+
+typedef enum {
+        BLOG_DECL(BLOG_UPDATE_DPI_QUEUE)     /* DPI Queue assignment has changed */
+        BLOG_DECL(BLOG_UPDATE_DPI_PRIORITY)  /* DPI Priority assignment has changed */
+        BLOG_DECL(BLOG_UPDATE_BITMAP)        /* Multicast client bitmap has changed */
+        BLOG_DECL(BLOG_UPDATE_FWD_AND_TRAP)  /* fwd_and_trap bit has changed */
+        BLOG_DECL(BLOG_UPDATE_BITMAP_FWD_AND_TRAP)  /* Mcast client bitmap and 
+                                                fwd_and_trap bit have changed */
+        BLOG_DECL(BLOG_UPDATE_MAX)
+} BlogUpdate_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Flow event parameters
+ *------------------------------------------------------------------------------
+ */
+
+typedef enum {
+        BLOG_DECL(FLOW_EVENT_TYPE_FC)        /* FCache Flow */
+        BLOG_DECL(FLOW_EVENT_TYPE_HW)        /* Hardware Flow */
+        BLOG_DECL(FLOW_EVENT_TYPE_MAX)
+} BlogFlowEventType_t;
+
+
+typedef struct {
+    void *ct_pld_p;
+    void *ct_del_p;
+    union {
+        struct {
+            uint32_t is_downstream      :1;
+            uint32_t flow_event_type    :2;
+            uint32_t reserved           :21;
+            uint32_t skb_mark_flow_id   :8;
+        };
+        uint32_t u32;
+    };
+} BlogFlowEventInfo_t;
+
+
+/*
+ *------------------------------------------------------------------------------
+ * Clean this up.
+ *------------------------------------------------------------------------------
+ */
+
+#define BLOG_ENCAP_MAX          6       /* Maximum number of L2 encaps        */
+#define BLOG_HDRSZ_MAX          38      /* Maximum size of L2 encaps          */
+
+typedef enum {
+        BLOG_DECL(GRE_ETH)             /* e.g. BLOG_XTMPHY, BLOG_GPONPHY     */
+        BLOG_DECL(BCM_XPHY)             /* e.g. BLOG_XTMPHY, BLOG_GPONPHY     */
+        BLOG_DECL(BCM_SWC)              /* BRCM LAN Switch Tag/Header         */
+        BLOG_DECL(ETH_802x)             /* Ethernet                           */
+        BLOG_DECL(VLAN_8021Q)           /* Vlan 8021Q (incld stacked)         */
+        BLOG_DECL(PPPoE_2516)           /* PPPoE RFC 2516                     */
+        BLOG_DECL(PPP_1661)             /* PPP RFC 1661                       */
+        BLOG_DECL(PLD_IPv4)             /* Payload IPv4                       */
+        BLOG_DECL(PLD_IPv6)             /* Payload IPv6                       */
+        BLOG_DECL(PPTP)                 /* PPTP Header                        */
+        BLOG_DECL(L2TP)                 /* L2TP Header                        */
+        BLOG_DECL(GRE)                  /* GRE Header                         */
+        BLOG_DECL(ESP)                  /* ESP Header                         */
+        BLOG_DECL(DEL_IPv4)             /* Outer IPv4                         */
+        BLOG_DECL(DEL_IPv6)             /* Outer IPv6                         */
+        BLOG_DECL(DEL_L2)               /* L2 DEL                             */
+        BLOG_DECL(PLD_L2)               /* L2 PLD                             */
+        BLOG_DECL(HDR0_IPv4)            /* IPv4 Inner Header 0                */
+        BLOG_DECL(HDR0_IPv6)            /* IPv6 Inner Header 0                */
+        BLOG_DECL(HDR0_L2)              /* L2 Inner Header 0                  */
+        BLOG_DECL(GREoESP_type)         /* GRE over ESP type                  */
+        BLOG_DECL(GREoESP_type_resvd)   /* GRE over ESP type                  */
+        BLOG_DECL(GREoESP)              /* GRE over ESP                       */
+        BLOG_DECL(NPT6)                 /* NPT6                               */
+        BLOG_DECL(PASS_THRU)            /* pass-through                       */
+        BLOG_DECL(DEL_DST_OPTS)         /* Delivery IPv6 Dest options         */
+        BLOG_DECL(PLD_DST_OPTS)         /* Payload IPv6 Dest options          */
+        BLOG_DECL(LLC_SNAP)             /* LLC_SNAP                           */
+        BLOG_DECL(VXLAN)                /* VXLAN Header                       */
+        BLOG_DECL(unused)               /* unused                             */
+        BLOG_DECL(PROTO_MAX)
+} BlogEncap_t;
+
+
+
+
+
+
+/* CAUTION: Following macros have binary dependencies. Please do not change these
+   macros without consulting with Broadcom or the subsystem owners
+   Macro definition START */
+#define BLOG_IS_HWACC_DISABLED_WLAN_EXTRAPHY(rxphy,txphy) ((rxphy == BLOG_EXTRA1PHY) || \
+                                                           (txphy == BLOG_EXTRA1PHY))
+#define BLOG_IS_TX_HWACC_ENABLED_WLAN_PHY(txphy) (txphy == BLOG_WLANPHY)
+/* Macro definition END */
+
+/*
+ *------------------------------------------------------------------------------
+ * Logging of a maximum 4 "virtual" network devices that a flow can traverse.
+ * Virtual devices are interfaces that do not perform the actual DMA transfer.
+ * E.g. an ATM interface would be referred to as a physical interface whereas
+ * a ppp interface would be referred to as a Virtual interface.
+ *------------------------------------------------------------------------------
+ */
+#define MAX_VIRT_DEV           7
+
+#define DEV_DIR_MASK           0x3ul
+#define DEV_PTR_MASK           (~DEV_DIR_MASK)
+#define DEV_DIR(ptr)           ((uintptr_t)(ptr) & DEV_DIR_MASK)
+
+#define IS_RX_DIR(ptr)         ( DEV_DIR(ptr) == DIR_RX )
+#define IS_TX_DIR(ptr)         ( DEV_DIR(ptr) == DIR_TX )
+
+/*
+ *------------------------------------------------------------------------------
+ * Device pointer conversion between with and without embeded direction info
+ *------------------------------------------------------------------------------
+ */
+#define DEVP_APPEND_DIR(ptr,dir) ((void *)((uintptr_t)(ptr) | (uintptr_t)(dir)))
+#define DEVP_DETACH_DIR(ptr)     ((void *)((uintptr_t)(ptr) & (uintptr_t) \
+                                                              DEV_PTR_MASK))
+/*
+ *------------------------------------------------------------------------------
+ * Denotes the tos mode.
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+    BLOG_DECL(BLOG_TOS_FIXED)
+    BLOG_DECL(BLOG_TOS_INHERIT)
+    BLOG_DECL(BLOG_TOS_MAX)
+} BlogTos_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Blog statistics structure
+ *------------------------------------------------------------------------------
+ */
+typedef struct{
+    /* NOTE : All these structure variables should be of same type/size */
+
+    uint64_t  rx_packets;             /* total blog packets received    */
+    uint64_t  tx_packets;             /* total blog packets transmitted */
+    uint64_t  rx_bytes;               /* total blog bytes received      */
+    uint64_t  tx_bytes;               /* total blog bytes transmitted   */
+    uint64_t  multicast;              /* total blog multicast packets   */
+    uint64_t  tx_multicast_packets;   /* multicast packets transmitted */
+    uint64_t  rx_multicast_bytes;     /* multicast bytes recieved */ 
+    uint64_t  tx_multicast_bytes;     /* multicast bytes transmitted */
+} BlogStats_t;
+
+typedef enum {
+    BLOG_DECL(blog_skip_reason_unknown = 0) /* unknown or customer defined */
+    BLOG_DECL(blog_skip_reason_br_flood)
+    BLOG_DECL(blog_skip_reason_ct_tcp_state_not_est)
+    BLOG_DECL(blog_skip_reason_ct_tcp_state_ignore)
+    BLOG_DECL(blog_skip_reason_ct_status_donot_blog)
+    BLOG_DECL(blog_skip_reason_nf_xt_skiplog)
+    BLOG_DECL(blog_skip_reason_nf_ebt_skiplog)
+    BLOG_DECL(blog_skip_reason_scrub_pkt)
+    BLOG_DECL(blog_skip_reason_sch_htb)
+    BLOG_DECL(blog_skip_reason_sch_dsmark)
+    BLOG_DECL(blog_skip_reason_unknown_proto)
+    BLOG_DECL(blog_skip_reason_unknown_proto_ah4)
+    BLOG_DECL(blog_skip_reason_unknown_proto_ah6)
+    BLOG_DECL(blog_skip_reason_unknown_proto_esp6)
+    BLOG_DECL(blog_skip_reason_esp4_crypto_algo)
+    BLOG_DECL(blog_skip_reason_esp4_spu_disabled)
+    BLOG_DECL(blog_skip_reason_spudd_check_failure)
+    BLOG_DECL(blog_skip_reason_dpi)
+    BLOG_DECL(blog_skip_reason_bond)
+    BLOG_DECL(blog_skip_reason_map_tcp)
+    BLOG_DECL(blog_skip_reason_blog)
+    BLOG_DECL(blog_skip_reason_l2_local_termination)
+    BLOG_DECL(blog_skip_reason_mega_multi_output_ports)
+    BLOG_DECL(blog_skip_reason_mega_attr_mismatch)
+    BLOG_DECL(blog_skip_reason_mega_field_mismatch)
+    BLOG_DECL(blog_skip_reason_max)
+} blog_skip_reason_t;
+
+typedef enum {
+    BLOG_DECL(blog_free_reason_unknown = 0) /* unknown or customer defined */
+    BLOG_DECL(blog_free_reason_blog_emit)
+    BLOG_DECL(blog_free_reason_blog_iq_prio)
+    BLOG_DECL(blog_free_reason_kfree)
+    BLOG_DECL(blog_free_reason_ipmr_local)
+    BLOG_DECL(blog_free_reason_max)
+} blog_free_reason_t;
+
+typedef struct {
+    uint32_t blog_get;
+    uint32_t blog_put;
+    uint32_t blog_skip;
+    uint32_t blog_free;
+    uint32_t blog_xfer;
+    uint32_t blog_clone;
+    uint32_t blog_copy;
+    uint32_t blog_min_avail;
+} blog_info_stats_t;
+
+#define BLOG_DUMP_DISABLE   0
+#define BLOG_DUMP_RXBLOG    1
+#define BLOG_DUMP_TXBLOG    2
+#define BLOG_DUMP_RXTXBLOG  3
+
+/*
+ * -----------------------------------------------------------------------------
+ * Support accleration of L2, L3 packets.
+ *
+ * When acceleration support is enabled system wide, the default to be used may
+ * be set in CC_BLOG_SUPPORT_ACCEL_MODE which gets saved in blog_support_accel_mode_g.
+ * One may change the default (at runtime) by invoking blog_support_accel_mode().
+ * -----------------------------------------------------------------------------
+ */
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Acceleration support:
+ * All the platforms support L3 tuple based acceleatiion.
+ * When the acceleation mode is configured as L23, the accelerators decides
+ * on per packet basis whether to use L2 or L3 tuple based acceleration.
+ * -----------------------------------------------------------------------------
+ */
+#define BLOG_ACCEL_MODE_L3             0    /* Legacy. All platforms support*/
+#define BLOG_ACCEL_MODE_L23            1    /* Platforms supporting both */
+
+#define CC_BLOG_SUPPORT_ACCEL_MODE     (BLOG_ACCEL_MODE_L3)
+
+extern int blog_support_accel_mode_g;
+
+typedef int (*blog_accel_mode_set_t)(uint32_t accel_mode);
+extern blog_accel_mode_set_t blog_accel_mode_set_fn;
+
+extern void blog_support_accel_mode(int accel_mode);
+extern int blog_support_get_accel_mode(void);
+
+extern int blog_support_tcp_ack_mflows_g;
+
+typedef int (*blog_tcp_ack_mflows_set_t)(int enable);
+extern blog_tcp_ack_mflows_set_t blog_tcp_ack_mflows_set_fn;
+
+extern void blog_support_set_tcp_ack_mflows(int enable);
+extern int blog_support_get_tcp_ack_mflows(void);
+
+/*
+ * -----------------------------------------------------------------------------
+ * Support blogging of multicast packets.
+ *
+ * When Multicast support is enabled system wide, the default to be used may
+ * be set in CC_BLOG_SUPPORT_MCAST which gets saved in blog_support_mcast_g.
+ * One may change the default (at runtime) by invoking blog_support_mcast().
+ * -----------------------------------------------------------------------------
+ */
+
+/* Multicast Support for IPv4 and IPv6 Control */
+#define BLOG_MCAST_DISABLE          0
+#define BLOG_MCAST_IPV4             1
+#define BLOG_MCAST_IPV6             2
+
+#ifdef CONFIG_BLOG_MCAST
+#define CC_BLOG_SUPPORT_MCAST        BLOG_MCAST_IPV4 + BLOG_MCAST_IPV6
+#else
+#define CC_BLOG_SUPPORT_MCAST        BLOG_MCAST_DISABLE
+#endif
+
+extern int blog_support_mcast_g;
+extern void blog_support_mcast(int enable);
+
+#define BCM_WLAN_PER_CLIENT_FLOW_LEARNING 1
+
+/*
+ * -----------------------------------------------------------------------------
+ * Support blogging of IPv6 traffic
+ *
+ * When IPv6 support is enabled system wide, the default to be used may
+ * be set in CC_BLOG_SUPPORT_IPV6 which gets saved in blog_support_ipv6_g.
+ * One may change the default (at runtime) by invoking blog_support_ipv6().
+ * -----------------------------------------------------------------------------
+ */
+
+/* IPv6 Support Control: see blog_support_ipv6_g and blog_support_ipv6() */
+#define BLOG_IPV6_DISABLE           0
+#define BLOG_IPV6_ENABLE            1
+
+#ifdef CONFIG_BLOG_IPV6
+#define CC_BLOG_SUPPORT_IPV6        BLOG_IPV6_ENABLE
+#else
+#define CC_BLOG_SUPPORT_IPV6        BLOG_IPV6_DISABLE
+#endif
+
+extern int blog_support_ipv6_g;
+extern void blog_support_ipv6(int enable);
+
+/*
+ * -----------------------------------------------------------------------------
+ * Support blogging of 6rd tos
+ *
+ * When 6rd is configured, the default to be used may be set in
+ * CC_BLOG_DEFAULT_TUNL_TOS which gets saved in blog_tunl_tos_g.
+ * One may change the default (at runtime) by invoking blog_tunl_tos().
+ * -----------------------------------------------------------------------------
+ */
+
+/* GRE Support: enable/disable */
+#define BLOG_GRE_DISABLE          0
+#define BLOG_GRE_ENABLE           1
+
+#ifdef CONFIG_BLOG_GRE
+#define CC_BLOG_SUPPORT_GRE        BLOG_GRE_ENABLE
+#else
+#define CC_BLOG_SUPPORT_GRE        BLOG_GRE_DISABLE
+#endif
+
+extern int blog_gre_tunnel_accelerated_g;
+extern int blog_support_gre_g;
+extern void blog_support_gre(int enable);
+
+/* L2TP Support */
+#define BLOG_L2TP_DISABLE             0
+#define BLOG_L2TP_ENABLE              1
+
+#ifdef CONFIG_BLOG_L2TP
+#define CC_BLOG_SUPPORT_L2TP       BLOG_L2TP_ENABLE
+#else
+#define CC_BLOG_SUPPORT_L2TP       BLOG_L2TP_DISABLE
+#endif
+
+extern int blog_l2tp_tunnel_accelerated_g;
+extern int blog_support_l2tp_g;
+extern void blog_support_l2tp(int enable);
+
+/* ESP Support: tunnel and pass-thru modes */
+#define BLOG_ESP_DISABLE          0
+#define BLOG_ESP_TUNNEL           1
+#define BLOG_ESP_PASS_THRU        2
+
+#ifdef CONFIG_BLOG_ESP
+#define CC_BLOG_SUPPORT_ESP        BLOG_ESP_TUNNEL
+#else
+#define CC_BLOG_SUPPORT_ESP        BLOG_ESP_DISABLE
+#endif
+
+/*
+ * -----------------------------------------------------------------------------
+ * Support 4o6 fragmentation enable/disable
+ * -----------------------------------------------------------------------------
+ */
+#define BLOG_4O6_FRAG_DISABLE           0
+#define BLOG_4O6_FRAG_ENABLE            1
+
+extern int blog_support_4o6_frag_g;
+extern void blog_support_4o6_frag(int enable);
+
+/* blog notify processing mode */
+typedef enum {
+        BLOG_DECL(BLOG_NOTIFY_PROC_MODE_NOW) /* processing mode: now/sync */
+        BLOG_DECL(BLOG_NOTIFY_PROC_MODE_HYBRID)/* mode: now+deferred      */
+        BLOG_DECL(BLOG_NOTIFY_PROC_MODE_DFRD)/* processing mode: deferred */
+        BLOG_DECL(BLOG_NOTIFY_PROC_MODE_MAX)
+} blog_notify_proc_mode_t;
+
+extern int blog_notify_proc_mode_g;
+extern void blog_set_notify_proc_mode(int mode);
+
+typedef enum {
+        BLOG_DECL(BLOG_NOTIFY_API_SYNC) /* blog_notify() */
+        BLOG_DECL(BLOG_NOTIFY_API_ASYNC)/* blog_notify_async() */
+        BLOG_DECL(BLOG_NOTIFY_API_MAX)
+} blog_notify_api_t;
+
+typedef enum
+{
+    BLOG_DECL(BLOG_NOTIFY_EVT_NONE)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_FDB)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_NPE)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_ARP)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_HW)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_DEV)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_PARAMS)
+    BLOG_DECL(BLOG_NOTIFY_EVT_FETCH_NETIF_STATS)
+    BLOG_DECL(BLOG_NOTIFY_EVT_CLEAR_NETIF_STATS)
+    BLOG_DECL(BLOG_NOTIFY_EVT_MAX)
+} blog_notify_evt_type_t;
+
+/* Traffic type */
+typedef enum {
+    BLOG_DECL(BlogTraffic_IPV4_UCAST)
+    BLOG_DECL(BlogTraffic_IPV6_UCAST)
+    BLOG_DECL(BlogTraffic_IPV4_MCAST)
+    BLOG_DECL(BlogTraffic_IPV6_MCAST)
+    BLOG_DECL(BlogTraffic_Layer2_Flow)
+    BLOG_DECL(BlogTraffic_MAX)
+} BlogTraffic_t;
+
+typedef union {
+    uint32_t word;
+    struct {
+        BE_DECL(
+            uint32_t incarn  :  3; /* Allocation instance identification */
+            uint32_t self    : 29; /* Index into static allocation table */
+        )
+        LE_DECL(
+            uint32_t self    : 29; /* Index into static allocation table */
+            uint32_t incarn  :  3; /* Allocation instance identification */
+        )
+    };
+} BlogKeyFc_t;
+
+typedef union {
+    uint32_t word;
+    struct {
+        BE_DECL(
+
+            uint32_t resvd  : 23;
+            uint32_t client_type:  1;
+            uint32_t client :  8;
+        )
+        LE_DECL(
+            uint32_t client :  8;
+            uint32_t client_type:  1;
+            uint32_t resvd  : 23;
+        )
+    };
+} BlogKeyMc_t;
+
+#define BLOG_FDB_KEY_INVALID        BLOG_KEY_NONE
+#define BLOG_KEY_FC_INVALID         BLOG_KEY_NONE
+#define BLOG_KEY_FC_TUNNEL_IPV4     0xFFFFFFFE
+#define BLOG_KEY_FC_TUNNEL_IPV6     0xFFFFFFFF
+
+#define BLOG_KEY_INVALID            BLOG_KEY_NONE
+#define BLOG_KEY_MCAST_INVALID      BLOG_KEY_INVALID
+
+/* mcast client type: TX device only, TX device & MAC address */
+#define BLOG_MCAST_CLIENT_TYPE_TXDEV         0
+#define BLOG_MCAST_CLIENT_TYPE_TXDEV_MACDA   1
+
+typedef struct {
+    BE_DECL(
+        BlogKeyFc_t fc;
+        BlogKeyMc_t mc;
+    )
+    LE_DECL(
+        BlogKeyMc_t mc;
+        BlogKeyFc_t fc;
+    )
+} BlogActivateKey_t;
+
+typedef enum
+{
+    BLOG_DECL(BLOG_L2_KEYMAP_MACSA)
+    BLOG_DECL(BLOG_L2_KEYMAP_MACDA)
+    BLOG_DECL(BLOG_L2_KEYMAP_ETHTYPE)
+    BLOG_DECL(BLOG_L2_KEYMAP_VLAN0)
+    BLOG_DECL(BLOG_L2_KEYMAP_VLAN1)
+    BLOG_DECL(BLOG_L2_KEYMAP_TOS)
+    BLOG_DECL(BLOG_L2_KEYMAP_TCPACK)
+} blog_l2_keymap_field_t;
+
+typedef enum
+{
+    BLOG_DECL(BLOG_L3_KEYMAP_IPV4SA)
+    BLOG_DECL(BLOG_L3_KEYMAP_IPV4DA)
+    BLOG_DECL(BLOG_L3_KEYMAP_IPV6SA)
+    BLOG_DECL(BLOG_L3_KEYMAP_IPV6DA)
+    BLOG_DECL(BLOG_L3_KEYMAP_PROTO)
+    BLOG_DECL(BLOG_L3_KEYMAP_SPORT)
+    BLOG_DECL(BLOG_L3_KEYMAP_DPORT)
+    BLOG_DECL(BLOG_L3_KEYMAP_TOS)
+    BLOG_DECL(BLOG_L3_KEYMAP_TCPACK)
+} blog_l3_keymap_field_t;
+
+
+#define BLOG_SET_L2KEYMAP(b, v0, v1, t)     \
+    b->l2_keymap = (1<<BLOG_L2_KEYMAP_MACSA \
+               | 1<<BLOG_L2_KEYMAP_MACDA \
+               | 1<<BLOG_L2_KEYMAP_ETHTYPE \
+               | v0<<BLOG_L2_KEYMAP_VLAN0 \
+               | v1<<BLOG_L2_KEYMAP_VLAN1 \
+               | t<<BLOG_L2_KEYMAP_TOS)
+
+#define BLOG_SET_IPV4_PT_L3KEYMAP(b)     \
+    b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV4SA \
+               | 1<<BLOG_L3_KEYMAP_IPV4DA \
+               | 1<<BLOG_L3_KEYMAP_PROTO \
+               | 1<<BLOG_L3_KEYMAP_TOS)
+
+#define BLOG_SET_IPV4_L3KEYMAP(b)     \
+    b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV4SA \
+               | 1<<BLOG_L3_KEYMAP_IPV4DA \
+               | 1<<BLOG_L3_KEYMAP_PROTO \
+               | 1<<BLOG_L3_KEYMAP_SPORT \
+               | 1<<BLOG_L3_KEYMAP_DPORT \
+               | 1<<BLOG_L3_KEYMAP_TOS)
+
+#define BLOG_SET_IPV6_PT_L3KEYMAP(b)     \
+    b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV6SA \
+               | 1<<BLOG_L3_KEYMAP_IPV6DA \
+               | 1<<BLOG_L3_KEYMAP_PROTO \
+               | 1<<BLOG_L3_KEYMAP_TOS)
+
+#define BLOG_SET_IPV6_L3KEYMAP(b)     \
+    b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV6SA \
+               | 1<<BLOG_L3_KEYMAP_IPV6DA \
+               | 1<<BLOG_L3_KEYMAP_PROTO \
+               | 1<<BLOG_L3_KEYMAP_SPORT \
+               | 1<<BLOG_L3_KEYMAP_DPORT \
+               | 1<<BLOG_L3_KEYMAP_TOS)
+
+
+/* Is the megaflow valid ? */
+#define IS_BLOG_MEGA(b)   (((b)->mega_p != (void *)NULL))
+
+/* Is the map tuple valid ? */
+#define IS_BLOG_MAP(b)   ( MAPT(b) && ((b)->map_p != (void *)NULL) )
+
+/* Before the flow is learnt, use CT macros */
+#define IS_BLOG_CT_PLD(b)   ( (b)->ct_p[BLOG_CT_PLD] != (void *)NULL )
+#define IS_BLOG_CT_DEL(b)   ( (b)->ct_p[BLOG_CT_DEL] != (void *)NULL )
+#define IS_BLOG_CT(b)       ( IS_BLOG_CT_PLD((b)) || IS_BLOG_CT_DEL((b)) )
+#define IS_BLOG_NOT_CT(b)   ( !IS_BLOG_CT_PLD((b)) && !IS_BLOG_CT_DEL((b)) )
+
+#define IS_BLOG_CT4_PLD(b)                                              \
+    ( IS_BLOG_CT_PLD((b)) &&                                            \
+     ((b)->ct_ver[BLOG_CT_PLD] == BLOG_PARAM2_IPV4))
+
+#define IS_BLOG_CT4_DEL(b)                                              \
+    ( IS_BLOG_CT_DEL((b)) &&                                            \
+     ((b)->ct_ver[BLOG_CT_DEL] == BLOG_PARAM2_IPV4))
+
+#define IS_BLOG_CT6_PLD(b)                                              \
+    ( IS_BLOG_CT_PLD((b)) &&                                            \
+     ((b)->ct_ver[BLOG_CT_PLD] == BLOG_PARAM2_IPV6))
+
+#define IS_BLOG_CT6_DEL(b)                                              \
+    ( IS_BLOG_CT_DEL((b)) &&                                            \
+     ((b)->ct_ver[BLOG_CT_DEL] == BLOG_PARAM2_IPV6))
+
+#define IS_BLOG_CT4(b)      ( IS_BLOG_CT4_PLD(b) || IS_BLOG_CT4_DEL(b) )
+#define IS_BLOG_CT6(b)      ( IS_BLOG_CT6_PLD(b) || IS_BLOG_CT6_DEL(b) )
+
+
+#define BLOG_NPE_PLD            0U
+#define BLOG_NPE_DEL            1U
+#define BLOG_NPE_MAP            2U
+#define BLOG_NPE_MEGA           3U
+#define BLOG_NPE_MAX            4U
+
+#define BLOG_FDB_NPE_SRCFDB     0U
+#define BLOG_FDB_NPE_DSTFDB     1U
+#define BLOG_FDB_NPE_MAX        2U
+
+/* Is the map tuple valid ? */
+#define IS_BLOG_NPE_MAP(b)   ( MAPT(b) && ((b)->npe_p[BLOG_NPE_MAP] != (void *)NULL) )
+#define IS_BLOG_NPE_MEGA(b)  ( ((b)->npe_p[BLOG_NPE_MEGA] != (void *)NULL) )
+
+/* After the flow is learnt, use NPE macros instead of CT macros */
+#define IS_BLOG_NPE_PLD(b)   ( (b)->npe_p[BLOG_NPE_PLD] != (void *)NULL )
+#define IS_BLOG_NPE_DEL(b)   ( (b)->npe_p[BLOG_NPE_DEL] != (void *)NULL )
+#define IS_BLOG_NPE_CT(b)    ( IS_BLOG_NPE_PLD((b)) || IS_BLOG_NPE_DEL((b)) )
+#define IS_BLOG_NOT_NPE_CT(b) ( !IS_BLOG_NPE_PLD((b)) && !IS_BLOG_NPE_DEL((b)) )
+
+#define IS_BLOG_NPE4_PLD(b)                                              \
+    ( IS_BLOG_NPE_PLD((b)) &&                                            \
+     ((b)->ct_ver[BLOG_NPE_PLD] == BLOG_PARAM2_IPV4))
+
+#define IS_BLOG_NPE4_DEL(b)                                              \
+    ( IS_BLOG_NPE_DEL((b)) &&                                            \
+     ((b)->ct_ver[BLOG_NPE_DEL] == BLOG_PARAM2_IPV4))
+
+#define IS_BLOG_NPE6_PLD(b)                                              \
+    ( IS_BLOG_NPE_PLD((b)) &&                                            \
+     ((b)->ct_ver[BLOG_NPE_PLD] == BLOG_PARAM2_IPV6))
+
+#define IS_BLOG_NPE6_DEL(b)                                              \
+    ( IS_BLOG_NPE_DEL((b)) &&                                            \
+     ((b)->ct_ver[BLOG_NPE_DEL] == BLOG_PARAM2_IPV6))
+
+#define IS_BLOG_NPE4(b)      ( IS_BLOG_NPE4_PLD(b) || IS_BLOG_NPE4_DEL(b) )
+#define IS_BLOG_NPE6(b)      ( IS_BLOG_NPE6_PLD(b) || IS_BLOG_NPE6_DEL(b) )
+
+#define BLOG_NPE_NULL        ((blog_npe_t*)NULL)
+
+/*
+ *------------------------------------------------------------------------------
+ * Flow Cache network proxiy entity (npe) Entry:
+ *------------------------------------------------------------------------------
+ */
+struct blog_npe {
+    struct dll_t    node;           /* npe Entity list                        */
+    BlogKeyFc_t     key;            /* linking Linux nwe and npe entity       */
+    struct blog_npe *chain_p;       /* npe Entity Hash list node              */
+    uint32_t        hashix;         /* npe Entity hash index                  */
+
+    int             type;           /* npe Entity type                        */
+    void            *nwe_p;
+    Dll_t           flow_list[BLOG_PARAM1_DIR_MAX];   /* flow lists       */
+    uint32_t        flow_count[BLOG_PARAM1_DIR_MAX];  /* # of flows       */
+} ____cacheline_aligned;
+typedef struct blog_npe blog_npe_t;
+
+
+/*
+ * =============================================================================
+ * CAUTION: OS and network stack may be built without CONFIG_BLOG defined.
+ * =============================================================================
+ */
+
+#if defined(CONFIG_BLOG)
+
+/*
+ *------------------------------------------------------------------------------
+ *
+ *              Section: Blog Conditional Compiles CC_BLOG_SUPPORT_...
+ *
+ * These conditional compiles are not controlled by a system wide build process.
+ * E.g. CONFIG_BLOG_MCAST is a system wide build configuration
+ *      CC_BLOG_SUPPORT_MCAST is a blog defined build configuration
+ *
+ * Do not use any CONFIG_ or CC_BLOG_SUPPORT_ in Blog_t structure definitions.
+ *
+ *------------------------------------------------------------------------------
+ */
+
+/* LAB ONLY: Design development, uncomment to enable */
+/* #define CC_BLOG_SUPPORT_COLOR */
+/* #define CC_BLOG_SUPPORT_DEBUG */
+
+
+
+
+/* To enable user filtering, see blog_filter(), invoked in blog_finit() */
+/* #define CC_BLOG_SUPPORT_USER_FILTER */
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ *                      Section: Definition of a Blog_t
+ * -----------------------------------------------------------------------------
+ */
+
+#define HDR_BMAP_IPV4           1
+#define HDR_BMAP_IPV6           2
+#define HDR_BMAP_L2             3
+
+/* GREoESP flag indicates whether it is GRE over ESP, or ESP over GRE */
+#define BLOG_ESPoGRE            0
+#define BLOG_GREoESP            1
+
+#define BLOG_GREoESP_44         0
+#define BLOG_GREoESP_64         1
+#define BLOG_GREoESP_46         2
+#define BLOG_GREoESP_66         3
+
+#define BLOG_ESPoGRE_44         0
+#define BLOG_ESPoGRE_64         1
+#define BLOG_ESPoGRE_46         2
+#define BLOG_ESPoGRE_66         3
+
+typedef struct {
+
+    uint8_t         channel;        /* e.g. port number, txchannel, ... */
+
+    union {
+        struct {
+            uint8_t         phyHdrLen   : 4;
+            uint8_t         phyHdrType  : 4;
+        };
+        uint8_t         phyHdr;
+    };
+
+    uint16_t unused;
+
+    union {
+        struct {
+            BE_DECL(
+                uint32_t         unused      : 3;
+                uint32_t         VXLAN       : 1;
+                uint32_t         LLC_SNAP    : 1;
+                uint32_t         PLD_DST_OPTS: 1; /* Payload IPv6 Ext Hdr Dest Options */
+                uint32_t         DEL_DST_OPTS: 1; /* Delivery IPv6 Ext Hdr Dest Options */
+                uint32_t         PASS_THRU   : 1;
+
+                uint32_t         NPT6        : 1;
+                uint32_t         GREoESP     : 1; 
+                uint32_t         GREoESP_type: 2;
+                uint32_t         HDR0_L2     : 1;
+                uint32_t         HDR0_IPv6   : 1;
+                uint32_t         HDR0_IPv4   : 1;
+                uint32_t         PLD_L2      : 1;
+
+                uint32_t         DEL_L2      : 1;
+                uint32_t         DEL_IPv6    : 1;
+                uint32_t         DEL_IPv4    : 1;
+                uint32_t         ESP         : 1;
+                uint32_t         GRE         : 1;
+                uint32_t         L2TP        : 1; 
+                uint32_t         PPTP        : 1;
+                uint32_t         PLD_IPv6    : 1;
+
+                uint32_t         PLD_IPv4    : 1;
+                uint32_t         PPP_1661    : 1;
+                uint32_t         PPPoE_2516  : 1;
+                uint32_t         VLAN_8021Q  : 1;
+                uint32_t         ETH_802x    : 1;
+                uint32_t         BCM_SWC     : 1;
+                uint32_t         BCM_XPHY    : 1;    /* e.g. BCM_XTM */
+                uint32_t         GRE_ETH     : 1;    /* Ethernet over GRE */
+            )
+            LE_DECL(
+                uint32_t         GRE_ETH     : 1;    /* Ethernet over GRE */
+                uint32_t         BCM_XPHY    : 1;    /* e.g. BCM_XTM */
+                uint32_t         BCM_SWC     : 1;
+                uint32_t         ETH_802x    : 1;
+                uint32_t         VLAN_8021Q  : 1;
+                uint32_t         PPPoE_2516  : 1;
+                uint32_t         PPP_1661    : 1;
+                uint32_t         PLD_IPv4    : 1;
+
+                uint32_t         PLD_IPv6    : 1;
+                uint32_t         PPTP        : 1;
+                uint32_t         L2TP        : 1;
+                uint32_t         GRE         : 1;
+                uint32_t         ESP         : 1;
+                uint32_t         DEL_IPv4    : 1;
+                uint32_t         DEL_IPv6    : 1;
+                uint32_t         DEL_L2      : 1;
+
+                uint32_t         PLD_L2      : 1;
+                uint32_t         HDR0_IPv4   : 1;
+                uint32_t         HDR0_IPv6   : 1;
+                uint32_t         HDR0_L2     : 1;
+                uint32_t         GREoESP_type: 2;
+                uint32_t         GREoESP     : 1;
+                uint32_t         NPT6        : 1;
+
+                uint32_t         PASS_THRU   : 1;
+                uint32_t         DEL_DST_OPTS: 1; /* Delivery IPv6 Ext Hdr Dest Options */
+                uint32_t         PLD_DST_OPTS: 1; /* Payload IPv6 Ext Hdr Dest Options */
+                uint32_t         LLC_SNAP    : 1;
+                uint32_t         VXLAN       : 1;
+                uint32_t         unused      : 3;
+            )
+        }               bmap;/* as per order of BlogEncap_t enums declaration */
+        uint32_t        hdrs;
+    }; 
+} BlogInfo_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Buffer to log IP Tuple.
+ * Packed: 1 16byte cacheline.
+ *------------------------------------------------------------------------------
+ */
+struct blogTuple_t {
+    uint32_t        saddr;          /* IP header saddr */
+    uint32_t        daddr;          /* IP header daddr */
+
+    union {
+        struct {
+            uint16_t    source;     /* L4 source port */
+            uint16_t    dest;       /* L4 dest port */
+        }           port;
+        struct {
+            uint16_t    unused;
+            uint16_t    gre_callid;
+        };
+        uint32_t    ports;
+        uint32_t    esp_spi;
+    };
+
+    uint8_t         ttl;            /* IP header ttl */
+    uint8_t         tos;            /* IP header tos */
+    uint16_t        check;          /* checksum: rx tuple=l3, tx tuple=l4 */
+
+}; 
+typedef struct blogTuple_t BlogTuple_t;
+
+#define NEXTHDR_IPV4 IPPROTO_IPIP
+#define GRE_MAX_HDR_LEN  (sizeof(struct ipv6hdr) + sizeof(BLOG_HDRSZ_MAX) + BLOG_GRE_HDR_LEN)
+
+#define HDRS_IPinIP     ((1<<GREoESP) | (3<<GREoESP_type) | (1<<GRE) | (1<<ESP) | \
+                         (1<<PLD_IPv4) | (1<<PLD_IPv6) | (1<<PLD_L2) | \
+                         (1<<HDR0_IPv4) | (1<<HDR0_IPv6) | (1<<HDR0_L2) |  \
+                         (1<<DEL_IPv4) | (1<<DEL_IPv6) | (1<<DEL_L2) | (1<<VXLAN))
+#define HDRS_IP4in4     ((1<<PLD_IPv4) | (1<<DEL_IPv4))
+#define HDRS_IP6in4     ((1<<PLD_IPv6) | (1<<DEL_IPv4))
+#define HDRS_IP4in6     ((1<<PLD_IPv4) | (1<<DEL_IPv6))
+#define HDRS_IP6in6     ((1<<PLD_IPv6) | (1<<DEL_IPv6))
+#define HDRS_GIP4       ((1<<PLD_IPv4) | (1<<GRE))
+#define HDRS_GIP6       ((1<<PLD_IPv6) | (1<<GRE))
+#define HDRS_GL2        ((1<<PLD_L2) | (1<<GRE))
+#define HDRS_EIP4       ((1<<PLD_IPv4) | (1<<ESP))
+#define HDRS_IP2in4     ((1<<PLD_L2) | (1<<DEL_IPv4))
+#define HDRS_IP2in6     ((1<<PLD_L2) | (1<<DEL_IPv6))
+#define HDRS_EIP4in6    ((1<<PLD_IPv4) | (1<<DEL_IPv6) | (1<<ESP))
+
+#define RX_IP4in6(b)    (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_IP4in6)
+#define RX_IP6in4(b)    (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_IP6in4)
+#define TX_IP4in6(b)    (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_IP4in6)
+#define TX_IP6in4(b)    (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_IP6in4)
+
+#define RX_IPV4(b)      ((b)->rx.info.bmap.PLD_IPv4)
+#define TX_IPV4(b)      ((b)->tx.info.bmap.PLD_IPv4)
+#define RX_IPV6(b)      ((b)->rx.info.bmap.PLD_IPv6)
+#define TX_IPV6(b)      ((b)->tx.info.bmap.PLD_IPv6)
+#define RX_IPV4_DEL(b)  ((b)->rx.info.bmap.DEL_IPv4)
+#define TX_IPV4_DEL(b)  ((b)->tx.info.bmap.DEL_IPv4)
+#define RX_IPV6_DEL(b)  ((b)->rx.info.bmap.DEL_IPv6)
+#define TX_IPV6_DEL(b)  ((b)->tx.info.bmap.DEL_IPv6)
+#define PT(b)           ((b)->tx.info.bmap.PASS_THRU)
+
+#define RX_GRE(b)       ((b)->rx.info.bmap.GRE)
+#define TX_GRE(b)       ((b)->tx.info.bmap.GRE)
+#define RX_ESP(b)       ((b)->rx.info.bmap.ESP)
+#define TX_ESP(b)       ((b)->tx.info.bmap.ESP)
+#define RX_GRE_ETH(b)   ((b)->rx.info.bmap.GRE_ETH)
+#define TX_GRE_ETH(b)   ((b)->tx.info.bmap.GRE_ETH)
+#define TX_VXLAN(b)     ((b)->tx.info.bmap.VXLAN)
+#define RX_VXLAN(b)     ((b)->rx.info.bmap.VXLAN)
+#define VXLAN(b)        (TX_VXLAN(b) || RX_VXLAN(b))
+
+#define RX_IPV4ONLY(b)  (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv4))
+#define TX_IPV4ONLY(b)  (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv4))
+#define RX_IPV6ONLY(b)  (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv6))
+#define TX_IPV6ONLY(b)  (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv6))
+#define RX_L2ONLY(b)    (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_L2))
+#define TX_L2ONLY(b)    (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_L2))
+
+#define CHK_RX_GIPV4(b)    (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && RX_GRE(b))
+#define CHK_RX_GIPV6(b)    (((b)->rx.info.hdrs & ((1 << DEL_IPv6) | (1 << PLD_IPv6))) && RX_GRE(b))
+
+
+#define RX_IPV4_OUTER(b) (RX_IPV4ONLY(b) || RX_IPV4_DEL(b))
+#define TX_IPV4_OUTER(b) (TX_IPV4ONLY(b) || TX_IPV4_DEL(b))
+#define PT4(b)          (RX_IPV4ONLY(b) && TX_IPV4ONLY(b) && PT(b))
+
+#define RX_IPV6_OUTER(b) (RX_IPV6ONLY(b) || RX_IPV6_DEL(b))
+#define TX_IPV6_OUTER(b) (TX_IPV6ONLY(b) || TX_IPV6_DEL(b))
+#define PT6(b)          (RX_IPV6ONLY(b) && TX_IPV6ONLY(b) && PT(b))
+
+#define HDRS_IPV4       ((1 << PLD_IPv4) | (1 << DEL_IPv4))
+#define HDRS_IPV6       ((1 << PLD_IPv6) | (1 << DEL_IPv6))
+
+#define MAPT_UP(b)      (RX_IPV4ONLY(b) && TX_IPV6ONLY(b))
+#define MAPT_DN(b)      (RX_IPV6ONLY(b) && TX_IPV4ONLY(b))
+#define MAPT(b)         (MAPT_DN(b) || MAPT_UP(b))
+
+#define T4in6UP(b)      (RX_IPV4ONLY(b) && TX_IP4in6(b))
+#define T4in6DN(b)      (RX_IP4in6(b) && TX_IPV4ONLY(b))
+
+#define T6in4UP(b)      (RX_IPV6ONLY(b) && TX_IP6in4(b))
+#define T6in4DN(b)      (RX_IP6in4(b) && TX_IPV6ONLY(b))
+
+#define CHK4in6(b)      (T4in6UP(b) || T4in6DN(b))
+#define CHK6in4(b)      (T6in4UP(b) || T6in4DN(b)) 
+#define CHK4to4(b)      (RX_IPV4ONLY(b) && TX_IPV4ONLY(b))
+#define CHK6to6(b)      (RX_IPV6ONLY(b) && TX_IPV6ONLY(b))
+
+/* RX/TX is ESPv4 */
+#define RX_E4(b)        (((b)->rx.info.hdrs & HDRS_IPinIP)==((1 << PLD_IPv4)|(1 << ESP)))
+#define TX_E4(b)        (((b)->tx.info.hdrs & HDRS_IPinIP)==((1 << PLD_IPv4)|(1 << ESP)))
+
+/* RX/TX ESPv4 over DSLite tunnel WAN side */
+#define RX_E4in6(b)    (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in6)
+#define TX_E4in6(b)    (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in6)
+
+/* ESPv4 pass-thru over DSLite tunnel */
+#define EoT4in6UP(b)  (RX_E4(b) && TX_E4in6(b))
+#define EoT4in6DN(b)  (RX_E4in6(b) && TX_E4(b))
+
+#define HDRS_GIP4in4    ((1<<GRE) | HDRS_IP4in4)
+#define HDRS_GIP6in4    ((1<<GRE) | HDRS_IP6in4)
+#define HDRS_GIP2in4    ((1<<GRE) | HDRS_IP2in4)
+
+#define HDRS_GIP4in6    ((1<<GRE) | HDRS_IP4in6)
+#define HDRS_GIP6in6    ((1<<GRE) | HDRS_IP6in6)
+#define HDRS_GIP2in6    ((1<<GRE) | HDRS_IP2in6)
+
+#define RX_GIPV4ONLY(b)  (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GIP4)
+#define TX_GIPV4ONLY(b)  (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GIP4)
+#define RX_GIPV6ONLY(b)  (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GIP6)
+#define TX_GIPV6ONLY(b)  (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GIP6)
+#define RX_GL2ONLY(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GL2)
+#define TX_GL2ONLY(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GL2)
+
+#define RX_GIP4in4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in4)
+#define TX_GIP4in4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in4)
+#define RX_GIP6in4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in4)
+#define TX_GIP6in4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in4)
+#define RX_GIP2in4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in4)
+#define TX_GIP2in4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in4)
+#define RX_GIP46in4(b)  (RX_GIP4in4(b) || RX_GIP6in4(b))
+#define TX_GIP46in4(b)  (TX_GIP4in4(b) || TX_GIP6in4(b))
+
+#define RX_GIP4in6(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in6)
+#define TX_GIP4in6(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in6)
+#define RX_GIP6in6(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in6)
+#define TX_GIP6in6(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in6)
+#define RX_GIP2in6(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in6)
+#define TX_GIP2in6(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in6)
+#define RX_GIP46in6(b)  (RX_GIP4in6(b) || RX_GIP6in6(b))
+#define TX_GIP46in6(b)  (TX_GIP4in6(b) || TX_GIP6in6(b))
+
+#define TG4in4UP(b)     (RX_IPV4ONLY(b) && TX_GIP4in4(b))
+#define TG4in4DN(b)     (RX_GIP4in4(b) && TX_IPV4ONLY(b))
+#define TG6in4UP(b)     (RX_IPV6ONLY(b) && TX_GIP6in4(b))
+#define TG6in4DN(b)     (RX_GIP6in4(b) && TX_IPV6ONLY(b))
+#define TG2in4UP(b)     (RX_L2ONLY(b) && TX_GIP2in4(b))
+#define TG2in4DN(b)     (RX_GIP2in4(b) && TX_L2ONLY(b))
+
+#define TGL3_4in4UP(b)  (RX_IPV4ONLY(b) && !TX_GRE_ETH(b) && TX_GIP4in4(b))
+#define TGL3_4in4DN(b)  (!RX_GRE_ETH(b) && RX_GIP4in4(b) && TX_IPV4ONLY(b))
+#define TGL2_4in4UP(b)  (RX_IPV4ONLY(b) && TX_GRE_ETH(b) && TX_GIP4in4(b))
+#define TGL2_4in4DN(b)  (RX_GRE_ETH(b) && RX_GIP4in4(b) && TX_IPV4ONLY(b))
+#define TGL2_2in4UP(b)  (RX_L2ONLY(b) && TX_GRE_ETH(b) && TX_GIP2in4(b))
+#define TGL2_2in4DN(b)  (RX_GRE_ETH(b) && RX_GIP2in4(b) && TX_L2ONLY(b))
+
+#define TG4in6UP(b)     (RX_IPV4ONLY(b) && TX_GIP4in6(b))
+#define TG4in6DN(b)     (RX_GIP4in6(b) && TX_IPV4ONLY(b))
+#define TG6in6UP(b)     (RX_IPV6ONLY(b) && TX_GIP6in6(b))
+#define TG6in6DN(b)     (RX_GIP6in6(b) && TX_IPV6ONLY(b))
+#define TG2in6UP(b)     (RX_L2ONLY(b) && TX_GIP2in6(b))
+#define TG2in6DN(b)     (RX_GIP2in6(b) && TX_L2ONLY(b))
+
+#define TG24in4UP(b)    (TG4in4UP(b) || TG2in4UP(b))
+#define TG24in4DN(b)    (TG4in4DN(b) || TG2in4DN(b))
+
+#define TG24in6UP(b)    (TG4in6UP(b) || TG2in6UP(b))
+#define TG24in6DN(b)    (TG4in6DN(b) || TG2in6DN(b))
+
+#define CHKG4in4(b)     (TG4in4UP(b) || TG4in4DN(b))
+#define CHKG6in4(b)     (TG6in4UP(b) || TG6in4DN(b))
+#define CHKG2in4(b)     (TG2in4UP(b) || TG2in4DN(b))
+#define CHKG46in4UP(b)  (TG4in4UP(b) || TG6in4UP(b))
+#define CHKG46in4DN(b)  (TG4in4DN(b) || TG6in4DN(b))
+#define CHKG46in4(b)    (CHKG4in4(b) || CHKG6in4(b))
+#define CHKG246in4UP(b) (TG4in4UP(b) || TG6in4UP(b) || TG2in4UP(b))
+#define CHKG246in4DN(b) (TG4in4DN(b) || TG6in4DN(b) || TG2in4DN(b))
+#define CHKG246in4(b)   (CHKG4in4(b) || CHKG6in4(b) || CHKG2in4(b))
+
+#define CHKG4in6(b)     (TG4in6UP(b) || TG4in6DN(b))
+#define CHKG6in6(b)     (TG6in6UP(b) || TG6in6DN(b))
+#define CHKG2in6(b)     (TG2in6UP(b) || TG2in6DN(b))
+#define CHKG46in6UP(b)  (TG4in6UP(b) || TG6in6UP(b))
+#define CHKG46in6DN(b)  (TG4in6DN(b) || TG6in6DN(b))
+#define CHKG46in6(b)    (CHKG4in6(b) || CHKG6in6(b))
+#define CHKG246in6UP(b) (TG4in6UP(b) || TG6in6UP(b) || TG2in6UP(b))
+#define CHKG246in6DN(b) (TG4in6DN(b) || TG6in6DN(b) || TG2in6DN(b))
+#define CHKG246in6(b)   (CHKG4in6(b) || CHKG6in6(b) || CHKG2in6(b))
+
+#define PTG4(b)         (RX_GIPV4ONLY(b) && TX_GIPV4ONLY(b) && PT(b))
+#define PTG6(b)         (RX_GIPV6ONLY(b) && TX_GIPV6ONLY(b) && PT(b))
+#define TOTG4(b)        (!PT(b) && ((RX_GIP4in4(b) && TX_GIP4in4(b)) || \
+                            (RX_GIP6in4(b) && TX_GIP6in4(b))))
+#define TOTG6(b)        (!PT(b) && ((RX_GIP4in6(b) && TX_GIP4in6(b)) || \
+                            (RX_GIP6in6(b) && TX_GIP6in6(b))))
+
+#define L2ACCEL_PTG(b)  (RX_GL2ONLY(b) && TX_GL2ONLY(b))
+
+#define HDRS_EIP4in4    ((1<<ESP) | HDRS_IP4in4)
+#define HDRS_EIP6in4    ((1<<ESP) | HDRS_IP6in4)
+
+#define RX_EIPV4ONLY(b)  (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_EIP4)
+#define TX_EIPV4ONLY(b)  (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_EIP4)
+
+#define RX_EIP4in4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in4)
+#define TX_EIP4in4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in4)
+#define RX_EIP6in4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP6in4)
+#define TX_EIP6in4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP6in4)
+
+#define TE4in4UP(b)     (RX_IPV4ONLY(b) && TX_EIP4in4(b))
+#define TE4in4DN(b)     (RX_EIP4in4(b) && TX_IPV4ONLY(b))
+#define TE6in4UP(b)     (RX_IPV6ONLY(b) && TX_EIP6in4(b))
+#define TE6in4DN(b)     (RX_EIP6in4(b) && TX_IPV6ONLY(b))
+
+#define CHKE4in4(b)     (TE4in4UP(b) || TE4in4DN(b))
+#define CHKE6in4(b)     (TE6in4UP(b) || TE6in4DN(b))
+#define CHKE46in4(b)    (CHKE4in4(b) || CHKE6in4(b))
+
+#define PTE4(b)         (RX_EIPV4ONLY(b) && TX_EIPV4ONLY(b))
+
+#define HDRS_404        (1<<DEL_IPv4|1<<PLD_IPv4)
+#define HDRS_464        (1<<DEL_IPv4|1<<HDR0_IPv6|1<<PLD_IPv4)
+#define HDRS_606        (1<<DEL_IPv6|1<<PLD_IPv6)
+#define HDRS_646        (1<<DEL_IPv6|1<<HDR0_IPv4|1<<PLD_IPv4)
+
+#define RX_404(b)       (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_404)
+#define RX_464(b)       (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_464)
+#define RX_606(b)       (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_606)
+#define RX_646(b)       (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_646)
+
+
+#define HDRS_444        (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_IPv4)
+#define HDRS_644        (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_IPv6)
+#define HDRS_244        (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_L2)
+
+
+/* GRE over ESP */
+#define HDRS_4oG4oE4    (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_444)
+#define HDRS_6oG4oE4    (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_644)
+#define HDRS_2oG4oE4    (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_244)
+/* HDRS_GE2 excludes IP Hdrs */
+#define HDRS_GE2        (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|1<<PLD_L2)
+
+#define RX_4oG4oE4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_4oG4oE4)
+#define TX_4oG4oE4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_4oG4oE4)
+#define RX_6oG4oE4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_6oG4oE4)
+#define TX_6oG4oE4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_6oG4oE4)
+#define RX_2oG4oE4(b)   (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_2oG4oE4)
+#define TX_2oG4oE4(b)   (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_2oG4oE4)
+#define RX_GoEo2(b)     (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GE2)
+#define TX_GoEo2(b)     (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GE2)
+
+#define T4oG4oE4UP(b)    (RX_IPV4ONLY(b) && TX_4oG4oE4(b))
+#define T4oG4oE4DN(b)    (RX_4oG4oE4(b) && TX_IPV4ONLY(b))
+#define T6oG4oE4UP(b)    (RX_IPV6ONLY(b) && TX_6oG4oE4(b))
+#define T6oG4oE4DN(b)    (RX_6oG4oE4(b) && TX_IPV6ONLY(b))
+#define T2oG4oE4UP(b)    (RX_L2ONLY(b) && (TX_2oG4oE4(b) || TX_GoEo2(b)))
+#define T2oG4oE4DN(b)    ((RX_2oG4oE4(b) || RX_GoEo2(b)) && TX_L2ONLY(b))
+
+#define CHK4oG4oE4UP(b)  (T4oG4oE4UP(b))
+#define CHK4oG4oE4DN(b)  (T4oG4oE4DN(b))
+#define CHK4oG4oE4(b)    (CHK4oG4oE4UP(b) || CHK4oG4oE4DN(b))
+
+#define CHK6oG4oE4UP(b)  (T6oG4oE4UP(b))
+#define CHK6oG4oE4DN(b)  (T6oG4oE4DN(b))
+#define CHK6oG4oE4(b)    (CHK6oG4oE4UP(b) || CHK6oG4oE4DN(b))
+
+#define CHK46oG4oE4DN(b) (CHK4oG4oE4DN(b) || CHK6oG4oE4DN(b))
+#define CHK46oG4oE4UP(b) (CHK4oG4oE4UP(b) || CHK6oG4oE4UP(b))
+#define CHK46oG4oE4(b)   (CHK4oG4oE4(b) || CHK6oG4oE4(b))
+
+#define CHK2oG4oE4UP(b)  (T2oG4oE4UP(b))
+#define CHK2oG4oE4DN(b)  (T2oG4oE4DN(b))
+#define CHK2oG4oE4(b)    (CHK2oG4oE4UP(b) || CHK2oG4oE4DN(b))
+
+
+#define CHK246oG4oE4UP(b) (CHK4oG4oE4UP(b) || CHK6oG4oE4UP(b) || CHK2oG4oE4UP(b))
+#define CHK246oG4oE4DN(b) (CHK4oG4oE4DN(b) || CHK6oG4oE4DN(b) || CHK2oG4oE4DN(b))
+#define CHK246oG4oE4(b)   (CHK4oG4oE4(b) || CHK6oG4oE4(b) || CHK2oG4oE4(b))
+
+
+#define RX_PPTP(b)       ((b)->rx.info.bmap.PPTP)
+#define TX_PPTP(b)       ((b)->tx.info.bmap.PPTP)
+
+#define RX_L2TP(b)       ((b)->rx.info.bmap.L2TP)
+#define TX_L2TP(b)       ((b)->tx.info.bmap.L2TP)
+
+#define CHK_RX_L2TP(b)    (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && RX_L2TP(b))
+#define CHK_TX_L2TP(b)    (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && TX_L2TP(b))
+
+#define RX_PPPOE(b)       ((b)->rx.info.bmap.PPPoE_2516)
+#define TX_PPPOE(b)       ((b)->tx.info.bmap.PPPoE_2516)
+#define PT_PPPOE(b)       (RX_PPPOE(b) && TX_PPPOE(b))
+
+#define PKT_IPV6_GET_TOS_WORD(word)       \
+   ((ntohl(word) & 0x0FF00000) >> 20)
+
+#define PKT_IPV6_SET_TOS_WORD(word, tos)  \
+   (word = htonl((ntohl(word) & 0xF00FFFFF) | ((tos << 20) & 0x0FF00000)))
+
+/* BLOG_LOCK Definitions */
+extern spinlock_t blog_lock_g;
+#define BLOG_LOCK_BH()      spin_lock_bh( &blog_lock_g )
+#define BLOG_UNLOCK_BH()    spin_unlock_bh( &blog_lock_g )
+
+typedef struct ip6_addr {
+    union {
+        uint8_t     p8[16];
+        uint16_t    p16[8];
+        uint32_t    p32[4];
+    };
+} ip6_addr_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Buffer to log IPv6 Tuple.
+ * Packed: 3 16byte cachelines
+ *------------------------------------------------------------------------------
+ */
+struct blogTupleV6_t {
+    union {
+        uint32_t    word0;
+    };
+
+    union {
+        uint32_t    word1;
+        struct {
+            uint16_t length; 
+            uint8_t next_hdr; 
+            uint8_t rx_hop_limit;
+        };
+    };
+
+    ip6_addr_t      saddr;
+    ip6_addr_t      daddr;
+
+    union {
+        struct {
+            uint16_t    source;     /* L4 source port */
+            uint16_t    dest;       /* L4 dest port */
+        }           port;
+        uint32_t    ports;
+    };
+
+    union {
+        struct {
+            uint8_t     exthdrs:6;  /* Bit field of IPv6 extension headers */
+            uint8_t     fragflag:1; /* 6in4 Upstream IPv4 fragmentation flag */
+            uint8_t     tunnel:1;   /* Indication of IPv6 tunnel */
+            uint8_t     tx_hop_limit;
+            uint16_t    ipid;       /* 6in4 Upstream IPv4 identification */
+        };
+        uint32_t   word2;
+    };
+    
+    union {      
+        struct {
+            uint8_t nextHdr; uint8_t hdrLen; uint16_t data16;
+            uint32_t data32;
+        };
+        uint64_t ip6_ExtHdr;
+    }; 
+
+    ip6_addr_t      addr_npt6;
+} ____cacheline_aligned;
+typedef struct blogTupleV6_t BlogTupleV6_t;
+
+typedef union blogGreFlags {
+    uint16_t    u16;
+    struct {
+        BE_DECL(
+            uint16_t csumIe : 1;
+            uint16_t rtgIe  : 1;
+            uint16_t keyIe  : 1;
+            uint16_t seqIe  : 1;
+            uint16_t srcRtIe: 1;
+            uint16_t recurIe: 3;
+            uint16_t ackIe  : 1;
+
+            uint16_t flags  : 4;
+            uint16_t ver    : 3;
+        )
+        LE_DECL(
+            uint16_t ver    : 3;
+            uint16_t flags  : 4;
+
+            uint16_t ackIe  : 1;
+            uint16_t recurIe: 3;
+            uint16_t srcRtIe: 1;
+            uint16_t seqIe  : 1;
+            uint16_t keyIe  : 1;
+            uint16_t rtgIe  : 1;
+            uint16_t csumIe : 1;
+        )
+    };
+} BlogGreFlags_t;
+
+struct blogGre_t {
+    uint8_t     l2hdr[ BLOG_HDRSZ_MAX ];    /* Data of all L2 headers */
+    BlogGreFlags_t  gre_flags;
+    union {
+        uint16_t    u16;
+        struct {
+            BE_DECL(
+                uint16_t reserved   : 10;
+                uint16_t fragflag   :  1;
+                uint16_t hlen       :  5;
+            )
+            LE_DECL(
+                uint16_t hlen       :  5;
+                uint16_t fragflag   :  1;
+                uint16_t reserved   : 10;
+            )
+        };
+    };
+    uint16_t    ipid;
+    uint16_t    l2_hlen;
+	
+    union { //pptp
+        struct {
+            uint16_t    keyLen;     
+            uint16_t    keyId;      
+        }; 
+        uint32_t    key;
+    };
+    uint32_t            seqNum; 
+    uint32_t            ackNum;
+    uint16_t            pppInfo;
+    uint16_t            pppProto;	
+};
+
+typedef struct blogGre_t BlogGre_t;
+
+typedef union blogL2tpFlags { 
+    uint16_t    u16;
+    struct {
+        BE_DECL(
+            uint16_t type       : 1;
+            uint16_t lenBit     : 3;
+            uint16_t seqBit     : 2;
+            uint16_t offsetBit  : 1;
+            uint16_t priority   : 1;
+            uint16_t reserved   : 4;
+            uint16_t version    : 4;
+        )
+        LE_DECL(
+            uint16_t version    : 4;
+            uint16_t reserved   : 4;
+            uint16_t priority   : 1;
+            int16_t offsetBit   : 1;
+            uint16_t seqBit     : 2;
+            uint16_t lenBit     : 3;
+            uint16_t type       : 1;            
+        )
+    };
+} BlogL2tpFlags_t;
+
+struct blogL2tp_t {
+    BlogL2tpFlags_t  l2tp_flags;
+    uint16_t    length;
+    uint16_t    tunnelId;
+    uint16_t    sessionId;
+    uint16_t    seqNum;
+    uint16_t    expSeqNum;
+    uint16_t    offsetSize;
+    uint16_t    offsetPad;
+    union {
+        uint16_t    u16;
+        struct {
+            BE_DECL(
+                uint16_t reserved   : 10;
+                uint16_t fragflag   :  1;
+                uint16_t hlen       :  5;
+            )
+            LE_DECL(
+                uint16_t hlen       :  5;
+                uint16_t fragflag   :  1;
+                uint16_t reserved   : 10;
+            )
+        };
+    };
+    uint16_t    ipid;
+    uint16_t    unused;
+    uint16_t    udpLen;
+    uint16_t    udpCheck;
+    uint16_t    pppInfo;
+    uint16_t    pppProto;
+
+};
+typedef struct blogL2tp_t BlogL2tp_t;
+
+#define BLOG_PPP_ADDR_CTL       0xFF03
+#define BLOG_L2TP_PPP_LEN       4   /* used when PPP address and control is 0xFF03 */
+#define BLOG_L2TP_PPP_LEN2      2   /* used when PPP address and control is NOT 0xFF03 */
+#define BLOG_L2TP_PORT          1701
+
+#define BLOG_PPTP_PPP_LEN       4
+#define BLOG_PPTP_NOAC_PPPINFO  0X2145  /* pptp packet without ppp address control field 0xff03 */
+
+#define BLOG_ESP_SPI_LEN         4
+#define BLOG_ESP_SEQNUM_LEN      4
+#define BLOG_ESP_PADLEN_LEN      1
+#define BLOG_ESP_NEXT_PROTO_LEN  1
+
+#define BLOG_ESP_ICV_LEN_64      8
+#define BLOG_ESP_ICV_LEN_96      12
+#define BLOG_ESP_ICV_LEN_128     16
+#define BLOG_ESP_ICV_LEN_192     24
+#define BLOG_ESP_ICV_LEN_224     28
+#define BLOG_ESP_ICV_LEN_256     32
+#define BLOG_ESP_ICV_LEN_384     48
+#define BLOG_ESP_ICV_LEN_512     64
+
+struct blogEsp_t {
+    uint32_t    u32;    
+    union {
+        uint16_t    u16;
+        struct {
+            BE_DECL(
+                uint16_t icvsize    :  7;
+                uint16_t pmtudiscen :  1;
+                uint16_t ipv6       :  1;
+                uint16_t ipv4       :  1;
+                uint16_t fragflag   :  1;
+                uint16_t ivsize     :  5;
+            )
+            LE_DECL(
+                uint16_t ivsize     :  5;
+                uint16_t fragflag   :  1;
+                uint16_t ipv4       :  1;
+                uint16_t ipv6       :  1;
+                uint16_t pmtudiscen :  1;
+                uint16_t icvsize    :  7;
+            )
+        };
+    };
+    uint16_t    ipid;
+    void        *dst_p;
+    void        *secPath_p;
+};
+typedef struct blogEsp_t BlogEsp_t;
+
+
+struct blogVxlan_t {
+    uint32_t vni;
+    union {
+        uint16_t u16;
+        struct {
+            BE_DECL(
+                uint16_t reserved   :  6;
+                uint16_t ipv6       :  1;
+                uint16_t ipv4       :  1;
+                uint16_t length     :  8;
+            )
+            LE_DECL(
+                uint16_t length     :  8;
+                uint16_t ipv4       :  1;
+                uint16_t ipv6       :  1;
+                uint16_t reserved   :  6;              
+            )
+        };
+    };
+    uint8_t     l2len;
+    uint8_t     unused; /*for alignment */
+    uint8_t     tunnel_data[BLOG_VXLAN_TUNNEL_MAX_LEN];
+};
+typedef struct blogVxlan_t BlogVxlan_t;
+
+
+/*
+ *------------------------------------------------------------------------------
+ * Buffer to log Layer 2 and IP Tuple headers.
+ * Packed: 4 16byte cachelines
+ *------------------------------------------------------------------------------
+ */
+struct blogHeader_t {
+
+    BlogTuple_t         tuple;          /* L3+L4 IP Tuple log */
+
+    union {
+        BlogInfo_t      info;
+        union {
+            struct {
+                uint32_t        word1;  /* channel, count, rfc2684, bmap */
+                uint32_t        word;   /* channel, count, rfc2684, bmap */
+            };
+            uint32_t        pktlen;     /* stats info */
+        };
+    };
+
+    struct {
+        uint8_t             vlan_8021ad :1;     /* 8021AD stacked */
+        uint8_t             wan_qdisc   :1;     /* device type */
+        uint8_t             multicast   :1;     /* multicast flag */
+        uint8_t             fkbInSkb    :1;     /* fkb from skb */
+        uint8_t             count       :4;     /* # of L2 encapsulations */
+    };
+    uint8_t             length;         /* L2 header total length */
+    uint8_t /*BlogEncap_t*/ encap[ BLOG_ENCAP_MAX ];/* All L2 header types */
+
+    uint8_t             l2hdr[ BLOG_HDRSZ_MAX ];    /* Data of all L2 headers */
+    struct {
+        uint8_t             unused;
+        uint8_t             len_offset;
+        union {
+            uint16_t        frame_len;
+            int16_t         len_delta;
+        };
+    } llc_snap;
+} ____cacheline_aligned;
+
+typedef struct blogHeader_t BlogHeader_t;           /* L2 and L3+4 tuple */
+
+/* Coarse hash key: L1, L3, L4 hash */
+union blogHash_t {
+    uint32_t        match;
+    struct {
+        union {
+            struct {
+                uint8_t  tcp_pure_ack : 1;
+                uint8_t  llc_snap     : 1;
+                uint8_t  unused       : 6;
+            };
+            uint8_t ext_match;
+        };
+        uint8_t     protocol;           /* IP protocol */
+
+        union {
+            uint16_t u16;
+            struct {
+                uint8_t         channel;
+                union {
+                    struct {
+                        uint8_t         phyLen   : 4;
+                        uint8_t         phyType  : 4;
+                    };
+                    uint8_t         phy;
+                };
+            };
+        } l1_tuple;
+    };
+};
+
+typedef union blogHash_t BlogHash_t;
+
+
+/* flow priority - used for packet buffer reseravtion */
+typedef enum  {
+	BLOG_DECL(flow_prio_normal)
+	BLOG_DECL(flow_prio_high)
+	BLOG_DECL(flow_prio_exclusive)
+} BlogFlowPrio_t;
+
+
+/* TBD : Rearrange following bit positions for optimization. */
+union blogWfd_t {
+    uint32_t    u32;
+    struct {
+        BE_DECL(
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_wmf_enabled       : 1; /* =0 unused */
+           uint32_t            chain_idx            : 16;/* Tx chain index */
+           uint32_t            is_chain             : 1;/* is_chain=1 */
+           uint32_t            reserved1            : 3;/* unused */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            reserved0            : 1;/* unused */
+           uint32_t            priority             : 4;/* Tx Priority */
+        )
+        LE_DECL(
+           uint32_t            priority             : 4;/* Tx Priority */
+           uint32_t            reserved0            : 1;/* unused */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            reserved1            : 3;/* unused */
+           uint32_t            is_chain             : 1;/* is_chain=1 */
+           uint32_t            chain_idx            : 16;/* Tx chain index */
+           uint32_t            is_wmf_enabled       : 1; /* =0 unused */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+        )
+    } nic_ucast;
+
+    struct {
+        BE_DECL(
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_wmf_enabled       : 1; /* =0 unused */
+           uint32_t            flowring_idx         :16;/* Tx flowring index */
+           uint32_t            is_chain             : 1;/* is_chain=0 */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            ssid                 : 4;/* SSID for WLAN */
+           uint32_t            reserved1            : 1;/* unused */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            priority             : 3;/* Tx Priority */
+        )
+        LE_DECL(
+           uint32_t            priority             : 3;/* Tx Priority */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            reserved1            : 1;/* unused */
+           uint32_t            ssid                 : 4;/* SSID for WLAN */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            is_chain             : 1;/* is_chain=0 */
+           uint32_t            flowring_idx         :16;/* Tx flowring index */
+           uint32_t            is_wmf_enabled       : 1; /* =0 unused */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+        )
+    } dhd_ucast;
+
+    struct {
+        BE_DECL(
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_wmf_enabled       : 1; /* =1 if wmf enabled */
+           uint32_t            sta_id               : 16;/* uniq wifi identifier, NIC max 2048*/
+           uint32_t            is_chain             : 1;/* is_chain=0 */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            reserved1            : 2;/* unused */
+           uint32_t            ssid                 : 4;/* SSID */
+           uint32_t            reserved0            : 2;/* unused */
+        )
+        LE_DECL(
+           uint32_t            reserved0            : 2; /* unused */
+           uint32_t            ssid                 : 4;/* SSID */
+           uint32_t            reserved1            : 2;/* unused */
+           uint32_t            wfd_prio             : 1;/* 0=high, 1=low */
+           uint32_t            wfd_idx              : 2;/* WFD idx */
+           uint32_t            is_chain             : 1;/* is_chain=0 */
+           uint32_t            sta_id               : 16;/* uniq wifi sta identifier, NIC max 2048*/
+           uint32_t            is_wmf_enabled       : 1; /* =1 if wmf enabled */
+           uint32_t            is_wfd               : 1;/* is_wfd=1 */
+           uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+           uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+        )
+    } mcast;
+};
+typedef union blogWfd_t BlogWfd_t;
+
+struct blogRnr_t {
+    BE_DECL(
+       uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+       uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+       uint32_t            is_wfd               : 1;/* rnr (is_wfd=0) */
+       uint32_t            is_wmf_enabled       : 1; /* =1 if wmf enabled */
+       uint32_t            flowring_idx         :16;/* Tx flowring index */
+       uint32_t            radio_idx            : 2;/* Radio index */
+       uint32_t            llcsnap_flag         : 1;/* llcsnap_flag */
+       uint32_t            priority             : 3;/* Tx Priority */
+       uint32_t            ssid                 : 4;/* SSID */
+       uint32_t            flow_prio            : 2;/* flow priority (normal,high, exclusive) - used for packet buffer reservation */
+       )
+    LE_DECL(
+       uint32_t            flow_prio            : 2;/* flow priority (normal,high, exclusive) - used for packet buffer reservation */
+       uint32_t            ssid                 : 4;/* SSID */
+       uint32_t            priority             : 3;/* Tx Priority */
+       uint32_t            llcsnap_flag         : 1;/* llcsnap_flag */
+       uint32_t            radio_idx            : 2;/* Radio index */
+       uint32_t            flowring_idx         :16;/* Tx flowring index */
+       uint32_t            is_wmf_enabled       : 1; /* =1 if wmf enabled */
+       uint32_t            is_wfd               : 1;/* rnr (is_wfd=0) */
+       uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+       uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+       )
+};
+
+typedef struct blogRnr_t BlogRnr_t;
+
+#define MAX_NUM_VLAN_TAG        2
+
+/* Blog ingress priority derived from IQOS */
+typedef enum  {
+    BLOG_DECL(BLOG_IQ_PRIO_LOW)
+    BLOG_DECL(BLOG_IQ_PRIO_HIGH)
+} BlogIqPrio_t;
+
+#define BLOG_GET_MASK(b)	    (1ULL<<(b))
+
+#define BLOG_BITS_PER_WORD		32
+#if (BLOG_BITS_PER_WORD != 32)
+#error "BLOG_BITS_PER_WORD should be 32"
+#endif
+
+#define BLOG_MCAST_CLIENT_BITMAP_MAX_WORDS ((CONFIG_BCM_MAX_MCAST_CLIENTS_PER_GROUP>>5)+1)
+#define BLOG_MCAST_CLIENT_BITMAP_SIZE (BLOG_MCAST_CLIENT_BITMAP_MAX_WORDS * BLOG_BITS_PER_WORD)
+#define BLOG_MCAST_MASTER_CLIENT_ID  0
+#define BLOG_MCAST_FIRST_CLIENT_ID   1
+
+/* DSL RDP: first few mcast client ids reserved for non-WLAN clients (Enet, XTM (DPU case, etc.) */
+#define BLOG_MCAST_ENET_CLIENT_RESERVED_IDS   7
+#define BLOG_MCAST_LAST_CLIENT_ID    (CONFIG_BCM_MAX_MCAST_CLIENTS_PER_GROUP)
+
+#define BLOG_MCAST_DEV_REALLOC_COUNT    16
+
+typedef struct {
+    uint16_t unused;
+    uint16_t max_dev;   /* max number of allocated devices in the table */
+    uint16_t num_dev;   /* number of used devices in the table */
+    uint16_t last_dev_idx;  /* index of last used device in the table */
+    uint8_t *ref_tbl_p;     /* table of ref count (of device) pointers */   
+    int8_t  *delta_tbl_p;   /* table of dev delta pointers */   
+    void    **dev_tbl_pp;   /* table of dev pointers */
+} mcast_dev_info_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * Buffer log structure.
+ * ARM 32: 704 bytes
+ * ARM 64: 896 bytes
+ * MIPS  : 704 bytes
+ * Marked the cacheline boundaries in the below structure. 
+ * Be cautious when adding new members to this structure.
+ *------------------------------------------------------------------------------
+ */
+struct blog_t {
+
+    union {
+        void            * void_p;
+        struct blog_t   * blog_p;       /* Free list of Blog_t */
+        struct sk_buff  * skb_p;        /* Associated sk_buff */
+    };
+    BlogHash_t          key;            /* Coarse hash search key */
+    uint32_t            hash;           /* hash */
+    union {
+        uint32_t        wl;
+        struct {
+            BE_DECL(
+               uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+               uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+               uint32_t            reserved             : 30;
+            )
+            LE_DECL(
+               uint32_t            reserved             : 30;
+               uint32_t            is_tx_hw_acc_en      : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */
+               uint32_t            is_rx_hw_acc_en      : 1;/* =1 if WLAN Receive is capable of HW Acceleration */
+            )
+        } wl_hw_support;
+        BlogWfd_t       wfd;
+        BlogRnr_t       rnr;
+    };
+    uint32_t            fc_context;     
+    void                * mc_fdb;       /* physical rx network device */
+
+    void                *map_p;
+    /* --- [ARM32]32 byte cacheline boundary --- */
+    BlogEthAddr_t       src_mac;        /* Flow src MAC */
+    BlogEthAddr_t       dst_mac;        /* Flow dst MAC */
+    /* --- [ARM64]64 byte cacheline boundary --- */
+
+    void                * fdb[2];       /* fdb_src and fdb_dst */
+    uint32_t            ifidx[2];       /* fdb src and fdb dst bridge ifidx */
+    int8_t              delta[MAX_VIRT_DEV];  /* octet delta info */
+    int8_t              tx_dev_delta; /* octet delta of TX dev */
+    uint8_t             l2_dirty_offset;
+    uint8_t             vtag_num:    4;
+    uint8_t             vtag_tx_num: 4;
+    uint16_t            eth_type;
+    /* --- [ARM32]32 byte cacheline boundary --- */
+
+    union {
+        uint32_t        flags;
+        struct {
+        BE_DECL(
+            uint32_t    fwd_and_trap:1;
+            uint32_t    mcast_fwd_exception: 1;
+            uint32_t    is_routed:   1;
+            uint32_t    fc_hybrid:   1;  /* hybrid flow accelarate in HW and SW */
+            uint32_t    l2_mode:     1;
+            uint32_t    is_ssm:      1;
+            uint32_t    unused2:     1;
+
+            uint32_t    l2_pppoe:    1; /* L2 packet is PPPoE */
+            uint32_t    l2_ipv6:     1; /* L2 packet is IPv6  */
+            uint32_t    l2_ipv4:     1; /* L2 packet is IPv4  */
+            uint32_t    is_mapt_us:  1; /* MAP-T Upstream flow */   
+            uint32_t    is_df:       1; /* IPv4 DF flag set */
+            uint32_t    ptm_us_bond: 1; /* PTM US Bonding Mode */
+            uint32_t    lag_port:    2; /* LAG port when trunking is done by internal switch/runner */
+
+            uint32_t    tos_mode_us: 1; /* ToS mode for US: fixed, inherit */
+            uint32_t    tos_mode_ds: 1; /* ToS mode for DS: fixed, inherit */
+            uint32_t    has_pppoe:   1;
+            uint32_t    ack_done:    1; /* TCP ACK prio decision made */
+            uint32_t    ack_cnt:     4; /* back to back TCP ACKs for prio */
+
+            uint32_t    nf_dir_pld:  1;
+            uint32_t    nf_dir_del:  1;
+            uint32_t    nf_ct_skip_ref_dec:  1; /* when set don't decrement ct refcnt */
+            uint32_t    pop_pppoa:   1;
+            uint32_t    insert_eth:  1;
+            uint32_t    iq_prio:     1;
+            uint32_t    mc_sync:     1;
+            uint32_t    rtp_seq_chk: 1; /* RTP sequence check enable       */
+            uint32_t    unused1:      1;
+        )
+        LE_DECL(
+            uint32_t    unused1:      1;
+            uint32_t    rtp_seq_chk: 1; /* RTP sequence check enable       */
+            uint32_t    mc_sync:     1;
+            uint32_t    iq_prio:     1;
+            uint32_t    insert_eth:  1;
+            uint32_t    pop_pppoa:   1;
+            uint32_t    nf_ct_skip_ref_dec:  1; /* when set don't decrement ct refcnt */
+            uint32_t    nf_dir_del:  1;
+            uint32_t    nf_dir_pld:  1;
+
+            uint32_t    ack_cnt:     4; /* back to back TCP ACKs for prio */
+            uint32_t    ack_done:    1; /* TCP ACK prio decision made */
+            uint32_t    has_pppoe:   1;
+            uint32_t    tos_mode_ds: 1; /* ToS mode for DS: fixed, inherit */
+            uint32_t    tos_mode_us: 1; /* ToS mode for US: fixed, inherit */
+
+            uint32_t    lag_port:    2; /* LAG port when trunking is done by internal switch/runner */
+            uint32_t    ptm_us_bond: 1; /* PTM US Bonding Mode */
+            uint32_t    is_df:       1; /* IPv4 DF flag set */
+            uint32_t    is_mapt_us:  1; /* MAP-T Upstream flow */   
+            uint32_t    l2_ipv4:     1; /* L2 packet is IPv4  */
+            uint32_t    l2_ipv6:     1; /* L2 packet is IPv6  */
+            uint32_t    l2_pppoe:    1; /* L2 packet is PPPoE */
+
+            uint32_t    unused2:     1;
+            uint32_t    is_ssm:      1;
+            uint32_t    l2_mode:     1;
+            uint32_t    fc_hybrid:   1;  /* hybrid flow accelarate in HW and SW */
+            uint32_t    is_routed:   1;
+            uint32_t    mcast_fwd_exception: 1;
+            uint32_t    fwd_and_trap:1;
+        )
+        };
+    };
+    union {
+        uint32_t        flags2;
+        struct {
+        BE_DECL(
+            uint32_t    unused:         31;
+            uint32_t    mcast_dev_added:  1;
+        )
+        LE_DECL(
+            uint32_t    mcast_dev_added:  1;
+            uint32_t    unused:         31;
+        )
+        };
+    };
+    union {
+        /* only the lower 32 bit in mark is used in 64 bit system
+         * but we declare it as unsigned long for the ease of blog
+         * to handle it in different architecture, since it part
+         * of union with a dst_entry pointer */
+        unsigned long       mark;           /* NF mark value on tx */
+        void                *dst_entry;     /* skb dst_entry for local_in */
+    };
+
+    union { 
+        uint32_t            priority;       /* Tx  priority */
+        uint32_t            flowid;         /* used only for local in */
+    };
+
+    void                * blogRule_p;   /* List of Blog Rules */
+
+    union {
+        struct {
+            uint32_t dosAttack : 16;
+            uint32_t lenPrior  :  1;
+            uint32_t vlanPrior :  1;
+            uint32_t dscpMangl :  1;
+            uint32_t tosMangl  :  1;
+            uint32_t preMod    :  1;
+            uint32_t postMod   :  1;
+            uint32_t dscp2pbit :  1;
+            uint32_t dscp2q    :  1;
+            uint32_t reserved  :  8;
+        };
+        uint32_t feature;       /* Feature set for per-packet modification */
+    };
+    union {
+        struct {
+            uint8_t vlanout_offset; /* Outer VLAN header offset */
+            uint8_t vlanin_offset;  /* Inner VLAN header offset */
+            uint8_t vpass_tx_offset; /* Passthru VLAN headers tx offset */
+            uint8_t vpass_len;      /* Passthru VLAN headers length */
+            uint8_t pppoe_offset;   /* PPPoE header offset */
+            uint8_t ip_offset;      /* IPv4 header offset */
+            uint8_t ip6_offset;     /* IPv6 header offset */
+            uint8_t l4_offset;      /* Layer 4 header offset */
+            uint8_t isWan;          /* Receiving by WAN interface */
+            uint8_t reserved8_3[3];
+        };
+        uint32_t offsets[3];
+    };
+    /* --- [ARM32][ARM64] cacheline boundary --- */
+    int (*preHook)(Blog_t *blog_p, void *nbuff_p);  /* Pre-modify hook */
+    int (*postHook)(Blog_t *blog_p, void *nbuff_p); /* Post-modify hook */
+    /* vtag[] stored in network order to improve fcache performance */
+    uint32_t            vtag[MAX_NUM_VLAN_TAG];
+    /* pointers to the devices which the flow goes thru */
+    void                * virt_dev_p[MAX_VIRT_DEV];
+    /* --- [ARM32][ARM64]cacheline boundary --- */
+    void                *fdb_npe_p[BLOG_FDB_NPE_MAX]; /* FDB NPEs */
+    void                *npe_p[BLOG_NPE_MAX]; /* non-FDB NPEs*/
+    /* --- [ARM32][ARM64]cacheline boundary --- */
+
+    //BlogTupleV6_t and BlogHeader_t is cacheline_aligned structure, be 
+    //be cautious when adding new variables around these memeber as it 
+    //will create unwanted holes in the structure.
+    BlogTupleV6_t       tupleV6;        /* L3+L4 IP Tuple log */
+    BlogTupleV6_t       del_tupleV6;    /* Del GRE L3+L4 IPV6 Tuple log */
+
+    BlogHeader_t        tx;             /* Transmit path headers */
+    BlogHeader_t        rx;             /* Receive path headers */
+    /* --- [ARM32][ARM64]cacheline boundary --- */
+
+    void                *rx_dev_p;      /* RX physical network device */
+    void                *tx_dev_p;      /* TX physical network device */
+
+    unsigned long       dev_xmit;
+    int (*dev_xmit_blog)(void * nbuff_p,const Blog_t * const blog_p); /* Xmit with blog */
+
+    /* Flow connection/session tracker */
+    void                *ct_p[BLOG_CT_MAX];
+    uint32_t            ct_ver[BLOG_CT_VER_MAX];
+    /* --- [ARM32]32 byte cacheline boundary --- */
+    void                *rx_tunl_p;
+    /* --- [ARM64]64 byte cacheline boundary --- */
+    void                *tx_tunl_p;
+    BlogActivateKey_t   activate_key;
+    uint8_t            tx_l4_offset; /*offset to inner most L4 header*/
+    uint8_t            tx_l3_offset; /*offset to inner most L3 header*/
+    uint16_t            mcast_port_map;
+    uint16_t            mcast_excl_udp_port;
+
+    uint16_t            minMtu;
+    uint8_t             dpi_queue;
+    uint8_t             tuple_offset; /* offset of flow tuple header */
+    uint8_t             hw_pathstat_idx;    /* HWACC Pathstat index */
+    uint8_t             host_mac_hashix;
+    uint8_t             spdtst;
+
+    /* To make cache alignment inserting dummy_ptr */
+    uint8_t             dummy_data2;
+    union {
+        uint16_t        wlinfo;
+        uint16_t        wlsta_id;
+    };
+
+    /* --- [ARM32]32 byte cacheline boundary --- */
+    BlogTuple_t         *grerx_tuple_p; /* gre proto RX Tuple pointer */
+    BlogTuple_t         *gretx_tuple_p; /* gre proto TX Tuple pointer */
+    union {
+        struct {
+            BlogGre_t grerx;
+    /* --- [ARM32][ARM64]cacheline boundary --- */
+            BlogGre_t gretx;
+        };
+        struct {
+            BlogL2tp_t l2tptx;
+        };
+        BlogVxlan_t     vxlan;
+    };
+    /* --- [ARM32]32 byte cacheline boundary (was 24 bytes ago)--- */
+    BlogTuple_t         *esprx_tuple_p; /* ESP proto RX Tuple pointer */
+    BlogTuple_t         *esptx_tuple_p; /* ESP proto TX Tuple pointer */
+    /* --- [ARM32]32 byte cacheline boundary --- */
+    struct {
+        BlogEsp_t esprx;
+    /* --- [ARM64]64 byte cacheline boundary --- */
+        BlogEsp_t esptx;
+    };
+    /* --- [ARM32]32 byte cacheline boundary --- */
+    BlogTuple_t         delrx_tuple;    /* Del proto RX L3+L4 IP Tuple log */
+    BlogTuple_t         deltx_tuple;    /* Del proto TX L3+L4 IP Tuple log */
+    /* --- [ARM32][ARM64]cacheline boundary --- */
+    BlogTuple_t         rx_tuple[1];    /* RX L3+L4 IP Tuple log */
+    BlogTuple_t         tx_tuple[1];    /* TX L3+L4 IP Tuple log */
+    void                *mega_p;
+    
+    uint32_t            l2_keymap;
+    uint32_t            l3_keymap;
+    uint8_t             mcast_client_type;
+    uint8_t             mcast_client_id;
+    int16_t             mcast_bitmap_idx; /* index into mcast bitmap pool */
+    mcast_dev_info_t   *mcast_dev_info_p; /* master mcast dev info */
+} ____cacheline_aligned;
+
+/*
+ * -----------------------------------------------------------------------------
+ * Engineering constants: Pre-allocated pool size 400 blogs Ucast+Mcast
+ *
+ * Extensions done in #blogs carved from a 2x4K page (external fragmentation)
+ * Blog size = 240, 8192/240 = 34 extension 32bytes internal fragmentation
+ *
+ * Number of extensions engineered to permit approximately max # of flows
+ * (assuming one blog per flow).
+ * -----------------------------------------------------------------------------
+ */
+#define CC_BLOG_SUPPORT_EXTEND              /* Conditional compile            */
+#define BLOG_POOL_SIZE_ENGG         400     /* Pre-allocated pool size        */
+/* Number of Blog_t per extension */
+#define BLOG_EXTEND_SIZE_ENGG      (8192/sizeof(Blog_t))
+
+/* There is one additional mcast flow entry for each mcast group because of a master flow */
+#define BLOG_CONFIG_MAX_MCAST_FLOWS (CONFIG_BCM_MAX_MCAST_GROUPS + CONFIG_BCM_MAX_MCAST_CLIENTS)
+#define BLOG_CONFIG_MAX_FLOWS       (CONFIG_BCM_MAX_UCAST_FLOWS + BLOG_CONFIG_MAX_MCAST_FLOWS)
+
+/* Maximum extensions allowed */
+#define BLOG_EXTEND_MAX_ENGG    ((BLOG_CONFIG_MAX_FLOWS/BLOG_EXTEND_SIZE_ENGG) + 1)
+
+
+
+extern const char       * strBlogAction[];
+extern const char       * strBlogEncap[];
+extern const char       * strRfc2684[];
+extern const uint8_t    rfc2684HdrLength[];
+extern const uint8_t    rfc2684HdrData[][16];
+
+
+#else
+struct blog_t {void * blogRule_p;};
+#define BLOG_LOCK_BH()
+#define BLOG_UNLOCK_BH()
+#endif /* defined(CONFIG_BLOG) */
+
+/*
+ * -----------------------------------------------------------------------------
+ * Blog functional interface
+ * -----------------------------------------------------------------------------
+ */
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Section 1. Extension of a packet context with a logging context
+ * -----------------------------------------------------------------------------
+ */
+
+#if defined(CONFIG_BLOG)
+#define blog_ptr(skb_p)         skb_p->blog_p
+#else
+#define blog_ptr(skb_p)         BLOG_NULL
+#endif
+
+/* Allocate or deallocate a Blog_t */
+Blog_t * blog_get(void);
+void blog_put(Blog_t * blog_p);
+
+/* Allocate a Blog_t and associate with sk_buff or fkbuff */
+extern Blog_t * blog_skb(struct sk_buff  * skb_p);
+extern Blog_t * blog_fkb(struct fkbuff  * fkb_p);
+
+/* Clear association of Blog_t with sk_buff */
+extern Blog_t * blog_snull(struct sk_buff * skb_p);
+extern Blog_t * blog_fnull(struct fkbuff  * fkb_p);
+
+/* increment refcount of ct's associated with blog */
+extern void blog_ct_get(Blog_t * blog_p);
+/* decrement refcount of ct's associated with blog */
+extern void blog_ct_put(Blog_t * blog_p);
+
+/* increment refcount for devices in virt_dev_p array */
+extern void blog_dev_hold(const Blog_t * blog_p);
+/* decrement refcount for devices in virt_dev_p array */
+extern void blog_dev_put(Blog_t * blog_p);
+
+/* Clear association of Blog_t with sk_buff and free Blog_t object */
+extern void blog_free( struct sk_buff * skb_p, blog_skip_reason_t reason );
+
+/* Disable further logging. Dis-associate with skb and free Blog object */
+extern void blog_skip(struct sk_buff * skb_p, blog_skip_reason_t reason);
+
+/* Transfer association of a Blog_t object between two sk_buffs. */
+extern void blog_xfer(struct sk_buff * skb_p, const struct sk_buff * prev_p);
+
+/* Duplicate a Blog_t object for another skb. */
+extern void blog_clone(struct sk_buff * skb_p, const struct blog_t * prev_p);
+
+/* Copy a Blog_t object another blog object. */
+extern void blog_copy(struct blog_t * new_p, const struct blog_t * prev_p);
+
+/* get the Ingress QoS Prio from the blog */
+extern int blog_iq(const struct sk_buff * skb_p);
+
+/* get the flow cache status */
+extern int blog_fc_enabled(void);
+
+/* get the GRE tunnel accelerated status */
+extern int blog_gre_tunnel_accelerated(void);
+
+#define BLOG_PTM_US_BONDING_DISABLED                      0
+#define BLOG_PTM_US_BONDING_ENABLED                       1
+
+extern void blog_ptm_us_bonding( struct sk_buff *skb_p, int mode );
+
+typedef int (*blog_dhd_flow_update_t)(void*, char*, char*, int);
+extern blog_dhd_flow_update_t blog_dhd_flow_update_fn;
+extern int blog_is_config_netdev_mac(void *dev_p, unsigned long incl_vmacs);
+extern int blog_preemptible_task(void);
+
+#if defined(CONFIG_BLOG)
+/* gets an NWE from blog based on the NPE type */
+static inline void *_blog_get_nwe(Blog_t *blog_p, uint32_t npe_type)
+{
+    blog_npe_t *npe_p = (blog_npe_t *)blog_p->npe_p[npe_type];
+    return (npe_p ? npe_p->nwe_p : (void *) NULL);
+}
+#endif
+
+/*
+ *------------------------------------------------------------------------------
+ *  Section 2. Associating native OS or 3rd-party network constructs
+ *------------------------------------------------------------------------------
+ */
+
+extern void blog_link(BlogNetEntity_t entity_type, Blog_t * blog_p,
+                      void * net_p, uint32_t param1, uint32_t param2);
+
+/*
+ *------------------------------------------------------------------------------
+ * Section 3. Network construct and Blog client co-existence call backs
+ *------------------------------------------------------------------------------
+ */
+
+extern unsigned long blog_request(BlogRequest_t event, void * net_p,
+                        unsigned long param1, unsigned long param2);
+
+extern int blog_query(BlogQuery_t query, void * net_p,
+                        uint32_t param1, uint32_t param2, unsigned long param3);
+
+/* 
+ * blog_notify():
+ * blog_notify() is a synchrounous notification from an entity to blog/flow_cache
+ * and will return once the notification/event has been completed. 
+ * This API should be called only when it is known that the event processing time
+ * is going to be short (process or interrupt context).
+ *
+ * Interrupt Context: It is NOT recommended to call blog_notify() from an 
+ *   interrupt context (like softirq/timer) because it will block all other 
+ *   processes/threads/softirq from running until the notification processing 
+ *   has been completed. Instead use blog_notify_async() from an interrupt 
+ *   context.
+ */
+extern void blog_notify(BlogNotify_t event, void *net_p,
+                        unsigned long param1, unsigned long param2);
+
+/* 
+ * fc_evt task will invoke this callback function asynchronously once the 
+ * event processing has been completed. It is upto each entity to decide what 
+ * it wants to do within this callback but it should not hold the fc_evt task 
+ * for too long. 
+ */
+typedef	void (*blog_notify_async_cb_fn_t)(void *notify_cb_data_p);
+
+/* 
+ * blog_notify_async():
+ * It is same as blog_notify() except two new parameters (notify_cb_fn and
+ * notify_cb_data_p) have been added, and it is asynchronous call. notify_cb_fn 
+ * function will be called with notify_cb_data_p parameter on completion of 
+ * the event processing. If an caller does not want to wait for the completion 
+ * of the event it can pass NULL values for notify_cb_fn and notify_cb_data_p.
+ *
+ * blog_notify_async() can be called from process or interrupt context, 
+ * it will not block/sleep in this call. If blocking is needed it should be
+ * done outside this API.
+ *
+ * CAUTION: Responsibility of the calling entity:
+ * - Serialization and/or locking, reference count of entry
+ * - the entry (e.g. flowring, FDB, etc.) for which flows are being flused 
+ *   is NOT freed or reallocated before the callback function is invoked.
+ *
+ * return: Caller MUST check the return value.
+ *         1 : caller's notify callback function will be called
+ *         0 : caller's notify callback function will NOT be called.
+ *             Situations where fc_evt task is not running.
+ */
+extern int blog_notify_async(BlogNotify_t event, void *net_p,
+        unsigned long param1, unsigned long param2,
+        blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p);
+
+/*
+ *------------------------------------------------------------------------------
+ * blog_notify_async_wait
+ * Calls blog_notify_async() and then waits for completion of event. No callback
+ * function needed from the caller, this function uses its own callback function.
+ * Note : If called from NOT preempt-safe context, this function will change 
+ *        blog_notify_async() to blog_notify(), which means the event is 
+ *        processed synchronously.
+ *        Caller should not call blog_lock()/blog_unlock() as this fucntion
+ *        internally calls blog_lock before calling blog_notify/_async() APIs,
+ *        and blog_unlock after calling.
+ *------------------------------------------------------------------------------
+ */
+extern void blog_notify_async_wait(BlogNotify_t event, void *net_p,
+        unsigned long param1, unsigned long param2);
+
+/* blog notify event enqueue function type */
+typedef	int (*blog_notify_evt_enqueue_hook_t)(blog_notify_evt_type_t evt_type, 
+        void *net_p, unsigned long param1, unsigned long param2,
+        blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p);
+
+void blog_bind_notify_evt_enqueue( 
+        blog_notify_evt_enqueue_hook_t blog_notify_evt_enqueue_fn );
+/*
+ *------------------------------------------------------------------------------
+ * Section 4. Network end-point binding of Blog client
+ *
+ * If rx hook is defined,
+ *  blog_sinit(): initialize a fkb from skb, and pass to hook
+ *          if packet is consumed, skb is released.
+ *          if packet is blogged, the blog is associated with skb.
+ *  blog_finit(): pass to hook
+ *          if packet is to be blogged, the blog is associated with fkb.
+ *
+ * If tx hook is defined, invoke tx hook, dis-associate and free Blog_t
+ *------------------------------------------------------------------------------
+ */
+extern BlogAction_t _blog_sinit( struct sk_buff * skb_p, void * dev_p,
+                                 uint32_t encap, uint32_t channel,
+                                 uint32_t phyHdr, BlogFcArgs_t *fc_args );
+
+static inline BlogAction_t blog_sinit( struct sk_buff * skb_p, void * dev_p,
+                                       uint32_t encap, uint32_t channel,
+                                       uint32_t phyHdr )
+{
+    /*TODO move this allocation to drivers calling this function */
+    BlogFcArgs_t fc_args;
+    memset(&fc_args, 0, sizeof(BlogFcArgs_t));
+    return _blog_sinit(skb_p, dev_p, encap, channel, phyHdr, &fc_args);
+}
+
+static inline BlogAction_t blog_sinit_args( struct sk_buff * skb_p, void * dev_p,
+                                            uint32_t encap, uint32_t channel,
+                                            uint32_t phyHdr, BlogFcArgs_t *fc_args )
+{
+    return _blog_sinit(skb_p, dev_p, encap, channel, phyHdr, fc_args);
+}
+
+extern BlogAction_t _blog_finit( struct fkbuff * fkb_p, void * dev_p,
+                                 uint32_t encap, uint32_t channel,
+                                 uint32_t phyHdr, BlogFcArgs_t *fc_args );
+
+static inline BlogAction_t blog_finit( struct fkbuff * fkb_p, void * dev_p,
+                                       uint32_t encap, uint32_t channel,
+                                       uint32_t phyHdr )
+{
+    /*TODO move this allocation to drivers calling this function */
+    BlogFcArgs_t fc_args;
+    memset(&fc_args, 0, sizeof(BlogFcArgs_t));
+    return _blog_finit(fkb_p, dev_p, encap, channel, phyHdr, &fc_args);
+}
+
+static inline BlogAction_t blog_finit_args( struct fkbuff * fkb_p, void * dev_p,
+                                            uint32_t encap, uint32_t channel,
+                                            uint32_t phyHdr, BlogFcArgs_t *fc_args )
+{
+    return _blog_finit(fkb_p, dev_p, encap, channel, phyHdr, fc_args);
+}
+
+#if defined(CONFIG_BLOG)
+extern BlogAction_t _blog_emit(void * nbuff_p, void * dev_p,
+                               uint32_t encap, uint32_t channel,
+                               uint32_t phyHdr, BlogFcArgs_t *fc_args);
+
+static inline BlogAction_t blog_emit_args(void * nbuff_p, void * dev_p,
+                                          uint32_t encap, uint32_t channel,
+                                          uint32_t phyHdr, BlogFcArgs_t *fc_args)
+{
+    if ( nbuff_p == NULL ) return PKT_NORM;
+    if ( !IS_SKBUFF_PTR(nbuff_p) ) return PKT_NORM;
+    // OK, this is something worth looking at, call real function
+    return ( _blog_emit(nbuff_p, dev_p, encap, channel, phyHdr, fc_args) );
+}
+
+static inline BlogAction_t blog_emit(void * nbuff_p, void * dev_p,
+                                     uint32_t encap, uint32_t channel,
+                                     uint32_t phyHdr)
+{
+    BlogFcArgs_t fc_args;
+    memset(&fc_args, 0, sizeof(BlogFcArgs_t));
+    return ( blog_emit_args(nbuff_p, dev_p, encap, channel, phyHdr, &fc_args) );
+}
+
+#else
+BlogAction_t blog_emit( void * nbuff_p, void * dev_p,
+                        uint32_t encap, uint32_t channel, uint32_t phyHdr );
+
+BlogAction_t blog_emit_args( void * nbuff_p, void * dev_p,
+                             uint32_t encap, uint32_t channel, uint32_t phyHdr,
+                             BlogFcArgs_t *fc_args);
+#endif
+
+/*
+ * blog_iq_prio determines the Ingress QoS priority of the packet
+ */
+extern int blog_iq_prio(struct sk_buff * skb_p, void * dev_p,
+                         uint32_t encap, uint32_t channel, uint32_t phyHdr);
+/*
+ *------------------------------------------------------------------------------
+ *  blog_activate(): static configuration function of blog application
+ *             pass a filled blog to the hook for configuration
+ *------------------------------------------------------------------------------
+ */
+#if defined(CONFIG_BLOG)
+extern BlogActivateKey_t *blog_activate( Blog_t * blog_p, BlogTraffic_t traffic );
+#else
+extern uint32_t blog_activate( Blog_t * blog_p, BlogTraffic_t traffic );
+#endif
+
+/*
+ *------------------------------------------------------------------------------
+ *  blog_deactivate(): static deconfiguration function of blog application
+ *------------------------------------------------------------------------------
+ */
+extern Blog_t * blog_deactivate( BlogActivateKey_t key, BlogTraffic_t traffic );
+
+/*
+ * -----------------------------------------------------------------------------
+ * User defined filter invoked invoked in the rx hook. A user may override the
+ * Blog action defined by the client. To enable the invocation of this API
+ * in blog_finit, ensure that CC_BLOG_SUPPORT_USER_FILTER is enabled. Also, a
+ * network device driver may directly invoke blog_filter() to override PKT_BLOG
+ * and return PKT_NORM (by releasing the associated Blog_t).
+ * -----------------------------------------------------------------------------
+ */
+extern BlogAction_t blog_filter(Blog_t * blog_p);
+
+/*
+ * -----------------------------------------------------------------------------
+ * Section 5. Binding Blog client applications:
+ *
+ * Blog defines three hooks:
+ *
+ *  RX Hook: If this hook is defined then blog_init() will pass the packet to
+ *           the Rx Hook using the FkBuff_t context. L1 and encap information
+ *           are passed to the receive hook. The private network device context 
+ *           may be extracted using the passed net_device object, if needed.
+ *
+ *  TX Hook: If this hook is defined then blog_emit() will check to see whether
+ *           the NBuff has a Blog_t, and if so pass the NBuff and Blog to the
+ *           bound Tx hook.
+ *
+ *  NotifHook: When blog_notify is invoked, the bound hook is invoked. Based on
+ *           event type the bound Blog client may perform a custom action.
+ *
+ *  SC Hook: If this hook is defined, blog_activate() will pass a blog with
+ *           necessary information for statical configuration.
+ *
+ *  SD Hook: If this hook is defined, blog_deactivate() will pass a pointer
+ *           to a network object with BlogActivateKey information. The
+ *           respective flow entry will be deleted.
+ *
+ *  QueryHook: When blog_query is invoked, the bound hook is invoked. Based on
+ *           query type the bound Blog client will return result of query.
+ * -----------------------------------------------------------------------------
+ */
+typedef union {
+    struct {
+        uint16_t         QR_HOOK     : 1;
+        uint16_t         RX_HOOK     : 1;
+        uint16_t         TX_HOOK     : 1;
+        uint16_t         XX_HOOK     : 1;
+        uint16_t         SC_HOOK     : 1;
+        uint16_t         SD_HOOK     : 1;
+        uint16_t         FA_HOOK     : 1;
+        uint16_t         FD_HOOK     : 1;
+        uint16_t         PA_HOOK     : 1;
+        uint16_t         BM_HOOK     : 1;
+        uint16_t         reserved    : 6;
+    } bmap;
+    uint16_t             hook_info;
+} BlogBind_t;
+
+typedef BlogAction_t (* BlogDevRxHook_t)(struct fkbuff *fkb_p, void * dev_p,
+                                       BlogFcArgs_t * args);
+
+typedef BlogAction_t (* BlogDevTxHook_t)(struct sk_buff *skb_p, void * dev_p,
+                                       uint32_t encap, uint32_t blogHash, BlogFcArgs_t * args);
+
+typedef int (* BlogNotifyHook_t)(blog_notify_api_t blog_notify_api, 
+        BlogNotify_t notification, 
+        void * net_p, unsigned long param1, unsigned long param2,
+        blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p);
+
+typedef int (* BlogQueryHook_t)(BlogQuery_t query, void * net_p,
+                            uint32_t param1, uint32_t param2, unsigned long param3);
+
+typedef BlogActivateKey_t * (* BlogScHook_t)(Blog_t * blog_p, BlogTraffic_t traffic);
+
+typedef Blog_t * (* BlogSdHook_t)(BlogActivateKey_t key, BlogTraffic_t traffic);
+
+typedef void (* BlogFaHook_t)(void *ct_p, BlogFlowEventInfo_t info, BlogFlowEventType_t type);
+
+typedef void (* BlogFdHook_t)(void *ct_p, BlogFlowEventInfo_t info, BlogFlowEventType_t type);
+
+typedef BlogAction_t (* BlogPaHook_t)(struct fkbuff * fkb_p, void * dev_p,
+                                      uint32_t encap, uint32_t channel, uint32_t phyHdr);
+
+typedef int (* BlogBitMapHook_t)(uint32_t bitmap_idx, uint32_t *dst_p, uint32_t dst_size_words);
+
+extern int blog_get_hw_accel(void);
+extern void blog_bind(BlogDevRxHook_t rx_hook,    /* Client Rx netdevice handler*/
+                      BlogDevTxHook_t tx_hook,    /* Client Tx netdevice handler*/
+                      BlogNotifyHook_t xx_hook, /* Client notification handler*/
+                      BlogQueryHook_t qr_hook,  /* Client query handler       */
+                      BlogBitMapHook_t blog_bm, /* Mcast BitMap copy handler */
+                      BlogBind_t   bind
+                     );
+                     
+extern void blog_bind_config(BlogScHook_t sc_hook,    /* Client static config handler*/
+                             BlogSdHook_t sd_hook,    /* Client static deconf handler*/
+                             BlogBind_t   bind
+                            );
+
+void blog_bind_packet_accelerator( BlogPaHook_t blog_pa, BlogBind_t bind );
+int blog_flowevent_register_notifier(struct notifier_block *nb);
+int blog_flowevent_unregister_notifier(struct notifier_block *nb);
+
+/*
+ *------------------------------------------------------------------------------
+ * blog notify event
+ *------------------------------------------------------------------------------
+ */
+typedef struct {
+    struct dll_t    node;       /* First element implements dll               */
+    blog_notify_evt_type_t evt_type;
+    void            *net_p;
+    unsigned long   param1;
+    unsigned long   param2;
+    blog_notify_async_cb_fn_t notify_cb_fn;
+    void            *notify_cb_data_p;
+} ____cacheline_aligned blog_notify_evt_t;
+
+/*
+ * -----------------------------------------------------------------------------
+ * Section 6. Miscellanous
+ * -----------------------------------------------------------------------------
+ */
+
+/* Dump a Blog_t object */
+extern void blog_hw_formatted_dump(Blog_t *blog_p);
+
+/* Logging of L2|L3 headers */
+extern void blog(struct sk_buff * skb_p, BlogDir_t dir, BlogEncap_t encap,  
+                 size_t len, void * data_p);
+
+/* Dump a Blog_t object */
+extern void blog_dump(Blog_t * blog_p);
+
+/* Get the minimum Tx MTU for a blog */
+uint16_t blog_getTxMtu(Blog_t * blog_p);
+
+/*
+ * Lock and unlock the blog layer.  This is used to reduce the number of
+ * times the blog lock must be acquired and released during bulk rx processing.
+ * See also blog_finit_locked.
+ */
+extern void blog_lock(void);
+extern void blog_unlock(void);
+
+/*
+  * Per packet basis modification feature
+  */
+#define BLOG_MAX_FEATURES               8
+
+#define BLOG_LEN_PARAM_INDEX            0
+#define BLOG_DSCP_PARAM_INDEX           1
+#define BLOG_TOS_PARAM_INDEX            2
+
+#define BLOG_MAX_LEN_TBLSZ              8
+#define BLOG_MAX_DSCP_TBLSZ            64
+#define BLOG_MAX_TOS_TBLSZ            256
+
+#define BLOG_LEN_PARAM_NUM              4
+#define BLOG_MAX_PARAM_NUM              4
+
+#define BLOG_MIN_LEN_INDEX              0
+#define BLOG_MAX_LEN_INDEX              1
+#define BLOG_ORIGINAL_MARK_INDEX        2
+#define BLOG_TARGET_MARK_INDEX          3
+
+#define BLOG_MATCH_DSCP_INDEX           0
+#define BLOG_TARGET_DSCP_INDEX          1
+
+#define BLOG_MATCH_TOS_INDEX            0
+#define BLOG_TARGET_TOS_INDEX           1
+
+#define BLOG_INVALID_UINT8   ((uint8_t)(-1))
+#define BLOG_INVALID_UINT16 ((uint16_t)(-1))
+#define BLOG_INVALID_UINT32 ((uint32_t)(-1))
+
+extern int blog_set_ack_tbl(uint32_t val[]);
+extern int blog_clr_ack_tbl(void);
+extern int blog_set_len_tbl(uint32_t val[]);
+extern int blog_clr_len_tbl(void);
+extern int blog_set_dscp_tbl(uint8_t idx, uint8_t val);
+extern int blog_clr_dscp_tbl(void);
+extern int blog_set_tos_tbl(uint8_t idx, uint8_t val);
+extern int blog_clr_tos_tbl(void);
+extern int blog_pre_mod_hook(Blog_t *blog_p, void *nbuff_p);
+extern int blog_post_mod_hook(Blog_t *blog_p, void *nbuff_p);
+
+#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE)
+#define BLOG_GRE_RCV_NOT_GRE             2
+#define BLOG_GRE_RCV_NO_SEQNO            1
+#define BLOG_GRE_RCV_IN_SEQ              0
+#define BLOG_GRE_RCV_NO_TUNNEL          -1
+#define BLOG_GRE_RCV_FLAGS_MISSMATCH    -2
+#define BLOG_GRE_RCV_CHKSUM_ERR         -3
+#define BLOG_GRE_RCV_OOS_LT             -4
+#define BLOG_GRE_RCV_OOS_GT             -5
+
+extern int blog_gre_rcv( struct fkbuff *fkb_p, void * dev_p, uint32_t h_proto, 
+                         void **tunl_pp, uint32_t *pkt_seqno_p);
+extern void blog_gre_xmit( struct sk_buff *skb_p, uint32_t h_proto );
+#endif
+
+#if defined(CONFIG_ACCEL_PPTP)
+#define BLOG_PPTP_ENCRYPTED               3
+#define BLOG_PPTP_RCV_NOT_PPTP            2
+#define BLOG_PPTP_RCV_NO_SEQNO            1
+#define BLOG_PPTP_RCV_IN_SEQ              0
+#define BLOG_PPTP_RCV_NO_TUNNEL          -1
+#define BLOG_PPTP_RCV_FLAGS_MISSMATCH    -2
+#define BLOG_PPTP_RCV_CHKSUM_ERR         -3
+#define BLOG_PPTP_RCV_OOS_LT             -4
+#define BLOG_PPTP_RCV_OOS_GT             -5
+extern int blog_pptp_rcv( struct fkbuff *fkb_p, uint32_t h_proto, 
+                          uint32_t *rcv_pktSeq);
+extern void blog_pptp_xmit( struct sk_buff *skb_p, uint32_t h_proto );
+#endif
+
+#define BLOG_L2TP_RCV_TUNNEL_FOUND       1
+#define BLOG_L2TP_RCV_NO_TUNNEL          0
+
+#define BLOG_INCLUDE_VIRTUAL_DEVS 1
+
+void blog_get_dev_stats(void *dev_p, void *bStats_p);
+void blog_clr_dev_stats(void *dev_p);
+void blog_get_dev_running_stats(void *dev_p, void * const bStats_p);
+void blog_get_dev_running_stats_wlan(void *dev_p, void * const bStats_p); /* Remove once WLAN falls in place */
+void blog_add_dev_accelerated_stats(void *dev_p, void *stats64_p);
+
+typedef struct {
+    wait_queue_head_t   wqh;
+    unsigned long       work_avail;
+#define BLOG_WORK_AVAIL               (1<<0)
+	spinlock_t		wakeup_lock;
+	bool wakeup_done;
+} wq_info_t;
+
+#define BLOG_WAKEUP_WORKER_THREAD(x, mask)                              \
+do {                                                                    \
+    if ( !((x)->work_avail & mask) ) {                                  \
+        (x)->work_avail |= mask;                                        \
+        wake_up_interruptible(&((x)->wqh));                             \
+    }                                                                   \
+} while (0)
+
+/*wake up with spinlock to avoid preemption/bh processing between
+ *setting work_avail & wakeup
+ */
+#define BLOG_WAKEUP_WORKER_THREAD_NO_PREEMPT(x, mask)               \
+do {                                                                \
+    spin_lock_bh(&((x)->wakeup_lock));								\
+    BLOG_WAKEUP_WORKER_THREAD(x, mask);	                         	\
+    (x)->wakeup_done = true;                                        \
+    spin_unlock_bh(&((x)->wakeup_lock));                            \
+} while (0)
+
+
+void blog_fold_stats(BlogStats_t * const d,
+                            const BlogStats_t * const s);
+int blog_copy_mcast_client_bitmap(uint16_t bitmap_idx, uint32_t *dst_p, uint32_t dst_size_words);
+
+void *blog_mcast_dev_realloc(Blog_t *mblog_p, uint8_t new);
+void blog_mcast_dev_free(Blog_t *mblog_p);
+int blog_mcast_find_matching_dev(Blog_t *mblog_p, void *dev_p, int8_t delta);
+int blog_mcast_add_rx_dev(Blog_t *mblog_p, Blog_t *cblog_p);
+void blog_mcast_del_rx_dev(Blog_t *mblog_p, Blog_t *cblog_p);
+int blog_mcast_add_tx_dev(Blog_t *mblog_p, Blog_t *cblog_p);
+void blog_mcast_del_tx_dev(Blog_t *mblog_p, Blog_t *cblog_p);
+void blog_mcast_del_all_devs(Blog_t *mblog_p);
+
+typedef struct blog_ctx {
+    uint32_t  blog_total;
+    uint32_t  blog_avail;
+    uint32_t  blog_mem_fails;
+    uint32_t  blog_extends;
+    uint32_t  blog_extend_fails;
+    blog_info_stats_t  info_stats;
+    blog_skip_reason_t blog_skip_stats_table[blog_skip_reason_max];
+    blog_free_reason_t blog_free_stats_table[blog_free_reason_max];
+    uint32_t  blog_dump;
+} blog_ctx_t;
+
+#endif /* defined(__BLOG_H_INCLUDED__) */
+
+#endif /* CONFIG_BCM_KF_BLOG */
diff --git a/include/linux/blog_net.h b/include/linux/blog_net.h
new file mode 100644
index 0000000000000000000000000000000000000000..d875958dcfe2d38985993c8dc390a0f164c3adb2
--- /dev/null
+++ b/include/linux/blog_net.h
@@ -0,0 +1,849 @@
+#ifndef __BLOG_NET_H_INCLUDED__
+#define __BLOG_NET_H_INCLUDED__
+
+/*
+<:copyright-BRCM:2003:DUAL/GPL:standard
+
+   Copyright (c) 2003 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+/*
+ *******************************************************************************
+ *
+ * File Name  : blog_net.h
+ *
+ * Description:
+ *
+ * Global definitions and declaration of Protocol Headers independent of OS as
+ * per IEEE and RFC standards.  Inlined utilities for header access.
+ *
+ * CAUTION: All protocol header structures are declared for Big Endian access
+ * and are not compatible for a Little Endian machine.
+ *
+ * CAUTION: It is also assumed that the Headers are AT LEAST 16bit aligned.
+ *
+ *******************************************************************************
+ */
+
+#if defined(CONFIG_CPU_BIG_ENDIAN)
+#define BE_DECL(declarations)   declarations
+#define BE_CODE(statements)     do { statements } while (0)
+#define LE_DECL(declarations)
+#define LE_CODE(statements)     NULL_STMT
+#elif defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+#define BE_DECL(declarations)
+#define BE_CODE(statements)     NULL_STMT
+#define LE_DECL(declarations)   declarations
+#define LE_CODE(statements)     do { statements } while (0)
+#else
+#error "Compile: fix endianess in platform.h"
+#endif
+
+
+/*TODO rename these PHY types to BCM_XXXPHY */
+#undef  BLOG_DECL
+#define BLOG_DECL(x)                x,
+/*
+ *------------------------------------------------------------------------------
+ * Denotes the type of physical interface and the presence of a preamble.
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+    BLOG_DECL(BLOG_NOPHY) /* index 0 placeholder for non-bloggable interface */
+    BLOG_DECL(BLOG_XTMPHY)
+    BLOG_DECL(BLOG_ENETPHY)
+    BLOG_DECL(BLOG_GPONPHY)
+    BLOG_DECL(BLOG_EPONPHY)
+    BLOG_DECL(BLOG_USBPHY)
+    BLOG_DECL(BLOG_WLANPHY)
+    BLOG_DECL(BLOG_MOCAPHY)
+    BLOG_DECL(BLOG_EXTRA1PHY)
+    BLOG_DECL(BLOG_LTEPHY)
+    BLOG_DECL(BLOG_SIDPHY)
+    BLOG_DECL(BLOG_TCP4_LOCALPHY)
+    BLOG_DECL(BLOG_SPU_DS)
+    BLOG_DECL(BLOG_SPU_US)
+    BLOG_DECL(BLOG_NETXLPHY)
+    BLOG_DECL(BLOG_SPDTST)
+    BLOG_DECL(BLOG_MAXPHY)
+} BlogPhy_t;
+
+/*
+ *------------------------------------------------------------------------------
+ * RFC 2684 header logging.
+ * CAUTION: 0'th enum corresponds to either header was stripped or zero length
+ *          header. VC_MUX_PPPOA and VC_MUX_IPOA have 0 length RFC2684 header.
+ *          PTM does not have an rfc2684 header.
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+        BLOG_DECL(RFC2684_NONE)         /*                               */
+        BLOG_DECL(LLC_SNAP_ETHERNET)    /* AA AA 03 00 80 C2 00 07 00 00 */
+        BLOG_DECL(LLC_SNAP_ROUTE_IP)    /* AA AA 03 00 00 00 08 00       */
+        BLOG_DECL(LLC_ENCAPS_PPP)       /* FE FE 03 CF                   */
+        BLOG_DECL(VC_MUX_ETHERNET)      /* 00 00                         */
+        BLOG_DECL(VC_MUX_IPOA)          /*                               */
+        BLOG_DECL(VC_MUX_PPPOA)         /*                               */
+        BLOG_DECL(PTM)                  /*                               */
+        BLOG_DECL(RFC2684_MAX)
+} Rfc2684_t;
+
+/*----- LinkType: First header type ------------------------------------------*/
+/* Used by network drivers to determine the Layer 1 encapsulation or LinkType */
+typedef enum {
+        BLOG_DECL(TYPE_ETH)             /* LAN: ETH, WAN: EoA, MER, PPPoE     */
+        BLOG_DECL(TYPE_PPP)             /*           WAN: PPPoA               */
+        BLOG_DECL(TYPE_IP)              /*           WAN: IPoA                */
+} BlogLinkType_t;
+
+#define BLOG_SET_PHYHDR(a, b)   ( (((a) & 0xf) << 4) | ((b) & 0xf) )
+#define BLOG_GET_PHYTYPE(a)     ( (a) & 0xf )
+#define BLOG_GET_PHYLEN(a)      ( (a) >> 4 )
+
+#define BLOG_PHYHDR_MASK        0xff
+#define BLOG_SET_HW_ACT(a)      ( ((a) & 0xf) << 8 )
+#define BLOG_GET_HW_ACT(a)      ( (a) >> 8 )
+
+/*----- ETH_TYPE: Standard well-defined Ethernet Encapsulations --------------*/
+#define BLOG_ETH_P_ETH_BRIDGING 0x6558  /* Transparent Ethernet bridging      */
+#define BLOG_ETH_P_IPV4         0x0800  /* IPv4 in Ethernet                   */
+#define BLOG_ETH_P_ARP          0x0806  /* Address Resolution packet          */
+#define BLOG_ETH_P_RARP         0x8035  /* Reverse ARP                        */
+#define BLOG_ETH_P_APPLTK_AARP  0x80F3  /* AppleTalk AARP                     */
+#define BLOG_ETH_P_8021Q        0x8100  /* 802.1Q VLAN Extended Header        */
+#define BLOG_ETH_P_8021AD       0x88A8  /* VLAN Stacking 802.1ad              */
+#define BLOG_ETH_P_NOVELL       0x8137  /* Novell, Inc.                       */
+#define BLOG_ETH_P_IPV6         0x86DD  /* Internet Protocol Version 6        */
+#define BLOG_ETH_P_MPLS_UC      0x8847  /* MPLS - Unicast                     */
+#define BLOG_ETH_P_MPLS_MC      0x8848  /* MPLS - Multicast                   */
+#define BLOG_ETH_P_ATMMPOA      0x884c  /* MultiProtocol Over ATM             */
+#define BLOG_ETH_P_PPP_DIS      0x8863  /* PPPoE Discovery                    */
+#define BLOG_ETH_P_PPP_SES      0x8864  /* PPPoE Session                      */
+#define BLOG_ETH_JUMBO_FRAME    0x8870  /* Jumbo frame indicator              */
+#define BLOG_ETH_P_BRCM6TAG     0x8874  /* BRCM Switch Hdr : 6 byte           */
+#define BLOG_ETH_P_BRCM4TAG     0x888A  /* BRCM Switch Hdr : 4 byte           */
+#define BLOG_ETH_P_PAUSE        0x8808  /* IEEE Pause frames. 802.3 31B       */
+#define BLOG_ETH_P_SLOW         0x8809  /* Slow Protocol. See 802.3ad 43B     */
+#define BLOG_ETH_P_8021AG       0x8902  /* 802.1ag Connectivity FaultMgmt     */
+                                            /* ITU-T recomm Y.1731 (OAM)      */
+#define BLOG_ETH_FCOE           0x8906  /* Fibre Channel over Ethernet        */
+#define BLOG_ETH_FCOE_INIT      0x8914  /* FCoE Initialization Protocol       */
+#define BLOG_ETH_QINQ1          0x9100  /* 802.1Q in Q, alternate 1           */
+#define BLOG_ETH_QINQ2          0x9200  /* 802.1Q in Q, alternate 2           */
+
+/*----- PPP_TYPE: Standard well-defined PPP Encapsulations -------------------*/
+#define BLOG_PPP_IPV4           0x0021  /* IPv4 in PPP                        */
+#define BLOG_PPP_IPCP           0x8021  /* IP Control Protocol                */
+#define BLOG_PPP_LCP            0xC021  /* Link Control Protocol              */
+#define BLOG_PPP_MP             0x003D  /* Multilink protocol                 */
+#define BLOG_PPP_IPV6           0x0057  /* IPv6 in PPP                        */
+#define BLOG_PPP_IPV6CP         0x8057  /* IPv6 Control Protocol              */
+#define BLOG_PPP_MPLSCP         0x80FD  /* MPLS Control Protocol???           */
+#define BLOG_PPP_MPLS_UC        0x0281  /* MPLS - Unicast                     */
+#define BLOG_PPP_MPLS_MC        0x0283  /* MPLS - Multicast                   */
+
+#define BLOG_GRE_PPP            0x880B  /* PPTP: PPP in GRE Tunnel            */
+
+/*----- IPPROTO: Standard well-defined IP Encapsulations ---------------------*/
+#define BLOG_IPPROTO_HOPOPTV6   0       /* IPv6 ext: Hop-by-Hop Option Header */
+#define BLOG_IPPROTO_ICMP       1       /* Internet Control Message Protocol  */
+#define BLOG_IPPROTO_IGMP       2       /* Internet Group Management Protocol */
+#define BLOG_IPPROTO_IPIP       4       /* IPIP tunnels e.g. 4in6             */
+#define BLOG_IPPROTO_TCP        6       /* Transmission Control Protocol      */
+#define BLOG_IPPROTO_EGP        8       /* Exterior Gateway Protocol          */
+#define BLOG_IPPROTO_UDP        17      /* User Datagram Protocol             */
+#define BLOG_IPPROTO_IPV6       41      /* IPv6-in-IPv4 tunnelling            */
+#define BLOG_IPPROTO_ROUTING    43      /* IPv6 ext: Routing Header           */
+#define BLOG_IPPROTO_FRAGMENT   44      /* IPv6 ext: Fragmentation Header     */
+#define BLOG_IPPROTO_RSVP       46      /* RSVP Protocol                      */
+#define BLOG_IPPROTO_GRE        47      /* Cisco GRE tunnels (rfc 1701,1702)  */
+#define BLOG_IPPROTO_ESP        50      /* Encapsulation Security Payload     */
+#define BLOG_IPPROTO_AH         51      /* Authentication Header Protocol     */
+#define BLOG_IPPROTO_ICMPV6     58      /* IPv6 ext: ICMPv6 Header            */
+#define BLOG_IPPROTO_NONE       59      /* IPv6 ext: NONE                     */
+#define BLOG_IPPROTO_DSTOPTS    60      /* IPv6 ext: Destination Options Hdr  */
+#define BLOG_IPPROTO_ANY_HOST_INTERNAL_PROTO   61  /* Any host internel proto */
+#define BLOG_IPPROTO_MTP        92      /* IPv6 ext: Mcast Transport Protocol */
+#define BLOG_IPPROTO_ENCAP      98      /* IPv6 ext: Encapsulation Header     */
+#define BLOG_IPPROTO_PIM        103     /* Protocol Independent Multicast     */
+#define BLOG_IPPROTO_COMP       108     /* Compression Header Protocol        */
+#define BLOG_IPPROTO_ANY_0HOP   114     /* Any Zero HOP                       */
+#define BLOG_IPPROTO_SCTP       132     /* Stream Control Transport Protocol  */
+#define BLOG_IPPROTO_UDPLITE    136     /* UDP-Lite (RFC 3828)                */
+
+#define BLOG_IPPROTO_UNASSIGN_B 141     /* Begin of unassigned range          */
+#define BLOG_IPPROTO_UNASSIGN_E 252     /* End of unassigned range            */
+#define BLOG_IPPROTO_RSVD_EXPT1 253     /* Reserved for experimentation       */
+#define BLOG_IPPROTO_RSVD_EXPT2 254     /* Reserved for experimentation       */
+#define BLOG_IPPROTO_RAW        255     /* Raw IP Packets                     */
+
+
+/* IGRS/UPnP using Simple Service Discovery Protocol SSDP over HTTPMU         */
+#define BLOG_HTTP_MCAST_UDP_DSTPORT 1900
+
+/* Known L4 Ports */
+#define BLOG_DNS_SERVER_PORT      53
+#define BLOG_DHCP_SERVER_PORT     67
+#define BLOG_DHCP_CLIENT_PORT     68
+
+/*----- Ethernet IEEE 802.3 definitions ------------------------------------- */
+#define BLOG_LLC_SAP_SNAP       (0xAA)
+#define BLOG_LLC_SNAP_8023_DSAP (BLOG_LLC_SAP_SNAP)
+#define BLOG_LLC_SNAP_8023_SSAP (BLOG_LLC_SAP_SNAP)
+#define BLOG_LLC_SNAP_8023_Ctrl (0x3)
+#define BLOG_LLC_SNAP_8023_LEN  8
+
+#define BLOG_ETH_ADDR_LEN       6
+#define BLOG_ETH_TYPE_LEN       sizeof(uint16_t)
+#define BLOG_ETH_HDR_LEN        ((BLOG_ETH_ADDR_LEN * 2) + BLOG_ETH_TYPE_LEN)
+#define BLOG_ETH_TYPE_MIN       1536
+
+#define BLOG_ETH_MIN_LEN        60
+#define BLOG_ETH_FCS_LEN        4
+#define BLOG_ETH_MTU_LEN        0xFFFF    /* Initial minMtu value               */
+
+#define BLOG_ETH_ADDR_FMT       "[%02X:%02X:%02X:%02X:%02X:%02X]"
+#define BLOG_ETH_ADDR(e)        e.u8[0],e.u8[1],e.u8[2],e.u8[3],e.u8[4],e.u8[5]
+
+typedef union BlogEthAddr {
+    uint8_t      u8[BLOG_ETH_ADDR_LEN];
+    uint16_t    u16[BLOG_ETH_ADDR_LEN/sizeof(uint16_t)];
+} BlogEthAddr_t;
+
+typedef struct BlogEthHdr {
+    union {
+        uint8_t     u8[BLOG_ETH_HDR_LEN];
+        uint16_t   u16[BLOG_ETH_HDR_LEN/sizeof(uint16_t)];
+        struct {
+            BlogEthAddr_t macDa;
+            BlogEthAddr_t macSa;
+    /*
+     * CAUTION: Position of ethType field of an Ethernet header depends on
+     * the presence and the number of VLAN Tags
+     * E.g. A single tagged Ethernet frame will have the ethType at offset 16.
+     */
+            uint16_t    ethType;    /* or length */
+        };
+    };
+} BlogEthHdr_t;
+
+/* 16bit aligned access MAC Address functgions */
+static inline int blog_is_zero_eth_addr(uint8_t * addr_p)
+{
+    uint16_t * u16_p = (uint16_t *)addr_p;  /* assert u16_p is 16bit aligned */
+    return ( (u16_p[0] & u16_p[1] & u16_p[2]) == 0x0000 );
+}
+
+static inline int blog_is_bcast_eth_addr(uint8_t * addr_p)
+{
+    uint16_t * u16_p = (uint16_t *)addr_p;  /* assert u16_p is 16bit aligned */
+    return ( (u16_p[0] & u16_p[1] & u16_p[2]) == 0xFFFF );
+}
+
+/* Caution an IP mcast over PPPoE need not have a mcast MacDA */
+static inline int blog_is_mcast_eth_addr(uint8_t * addr_p)
+{
+#if 1
+    return *(addr_p+0) & 0x01;
+#else   /* Multicast (e.g. over PPPoE) may use unicast MacDA */
+    uint16_t * u16_p = (uint16_t *)addr_p;  /* assert u16_p is 16bit aligned */
+    if ( ((u16_p[0] == 0x0100)              /* IPv4: 01:00:5E:`1b0 */
+           && (*(addr_p+2) == 0x5e) && ((*(addr_p+3) & 0x80) == 0) )
+       || ( u16_p[0] == 0x3333)             /* IPv6: 33:33 */
+       )
+        return 1;
+    else
+        return 0;
+#endif
+}
+
+static inline int blog_cmp_eth_addr(uint8_t * addr1_p, uint8_t * addr2_p)
+{
+    uint16_t *a1 = (uint16_t *)addr1_p;
+    uint16_t *a2 = (uint16_t *)addr2_p;
+    return ( ((a1[0] ^ a2[0]) | (a1[1] ^ a2[1]) | (a1[2] ^ a2[2])) != 0 );
+}
+
+
+/*----- 6Byte Brcm6Hdr layout for 5397/98 Switch Management Port Tag ---------*/
+#define BLOG_BRCM6_HDR_LEN      6
+
+typedef struct BlogBrcm6Hdr {
+    union {
+        uint8_t     u8[BLOG_BRCM6_HDR_LEN];
+        uint16_t   u16[BLOG_BRCM6_HDR_LEN/sizeof(uint16_t)];
+            /*
+             * egress:          opcode:3, fbcount:14, rsvd:11, srcPortId:4
+             * ingress_port     opcode:3, rsvd:25, dstPortId:4
+             * ingress_map      opcode:3, rsvd:20, fwdMap:9
+             */
+    };
+} BlogBrcm6Hdr_t;
+
+
+/*----- 4Byte Brcm4Hdr layout for 53115 Switch Management Port Tag -----------*/
+#define BLOG_BRCM4_HDR_LEN      4
+
+typedef struct BlogBrcm4Hdr {
+    union {
+        uint8_t      u8[BLOG_BRCM4_HDR_LEN];
+        uint16_t    u16[BLOG_BRCM4_HDR_LEN/sizeof(uint16_t)];
+        /*
+         * egress       opcode:3, rsvd:13, rsvd2:2,
+         *              flooding:1, snooping:1, protocol:1, switching:1
+         *              learning:1, mirroring:1, tclass:3, srcpid:5
+         * ingress      opcode:3, tclass:3,
+         *              tagenforce:2, rsvd:1, dstmap:23
+         */
+    };
+} BlogBrcm4Hdr_t;
+
+/*----- Composite Ethernet with BRCM Tag -------------------------------------*/
+
+#define BLOG_ETHBRCM6_HDR_LEN   (BLOG_ETH_HDR_LEN + BLOG_BRCM6_HDR_LEN)
+#define BLOG_ETHBRCM4_HDR_LEN   (BLOG_ETH_HDR_LEN + BLOG_BRCM4_HDR_LEN)
+
+typedef struct BlogEthBrcm6Hdr {
+    union {
+        uint8_t      u8[BLOG_ETHBRCM6_HDR_LEN];
+        uint16_t    u16[BLOG_ETHBRCM6_HDR_LEN/sizeof(uint16_t)];
+        struct {
+            BlogEthAddr_t   macDa;
+            BlogEthAddr_t   macSa;
+            BlogBrcm6Hdr_t  brcm6;
+            uint16_t        ethType;
+        };
+    };
+} BlogEthBrcm6Hdr_t;
+
+typedef struct BlogEthBrcm4Hdr {
+    union {
+        uint8_t      u8[BLOG_ETHBRCM4_HDR_LEN];
+        uint16_t    u16[BLOG_ETHBRCM4_HDR_LEN/sizeof(uint16_t)];
+        struct {
+            BlogEthAddr_t   macDa;
+            BlogEthAddr_t   macSa;
+            BlogBrcm4Hdr_t  brcm4;
+            uint16_t        ethType;
+        };
+    };
+} BlogEthBrcm4Hdr_t;
+
+
+/*----- Vlan IEEE 802.1Q definitions -----------------------------------------*/
+#define BLOG_VLAN_HDR_LEN       4
+#define BLOG_VLAN_HDR_FMT       "[0x%08X] tpid<0x%04X> tci<0x%04X> "\
+                                "pbit<%u> dei<%u> vid<0x%03X>"
+#define BLOG_VLAN_HDR(v)        v.u32[0], v.tpid, v.tci.u16[0], \
+                                v.tci.pbits, v.tci.dei, v.tci.vid
+
+typedef struct BlogVlanTci {
+    union {
+        uint8_t     u8[sizeof(uint16_t)];
+        uint16_t    u16[1];
+        struct {
+            BE_DECL( uint16_t pbits:3; uint16_t dei:1; uint16_t vid:12; )
+            LE_DECL( uint16_t vid:12; uint16_t dei:1; uint16_t pbits:3; )
+        };
+    };
+} BlogVlanTci_t;
+
+typedef struct BlogVlanHdr {
+    union {
+        uint8_t      u8[BLOG_VLAN_HDR_LEN];
+        uint16_t    u16[BLOG_VLAN_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_VLAN_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            uint16_t tpid; BlogVlanTci_t tci; /* u8[ 88, A8, EA, AA ] */
+        };
+    };
+} BlogVlanHdr_t;
+
+
+/*----- PPPoE + PPP Header layout. PPPoE RFC 2516, PPP RFC 1661 --------------*/
+#define BLOG_PPPOE_HDR_LEN      8   /* Including PPP Header "PPP Type" */
+#define BLOG_PPP_HDR_LEN        sizeof(uint16_t)
+#define BLOG_PPPOE_HDR_FMT      "[0x%08X 0x%08X] ver<%u> type<%u> code<0x%02X>"\
+                                " sId<0x%04X> len<%u> pppType<0x%04X>"
+#define BLOG_PPPOE_HDR(p)       p.u32[0], p.u32[1], p.ver, p.type, p.code,\
+                                p.sId, p.len, p.pppType
+
+typedef uint16_t BlogPppHdr_t;
+
+typedef struct BlogPppoeHdr {   /* includes 2 byte PPP Type */
+    union {
+        uint8_t      u8[BLOG_PPPOE_HDR_LEN];
+        uint16_t    u16[BLOG_PPPOE_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_PPPOE_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            BE_DECL( uint16_t ver:4; uint16_t type:4; uint16_t code:8; )
+            LE_DECL( uint16_t code:8; uint16_t type:4; uint16_t ver:4; )
+            uint16_t sId; uint16_t len; BlogPppHdr_t pppType;
+        };
+    };
+} BlogPppoeHdr_t;
+
+
+/*----- Multi Protocol Label Switiching Architecture: RFC 3031 -----------------
+ *
+ * 20b-label, 3b-tos, 1b-Stack, 8b-TTL
+ * StackBit==1? if label==0 then next is IPV4, if label==1 then next is IPV6
+ *------------------------------------------------------------------------------
+ */
+#define BLOG_MPLS_HDR_LEN       4
+
+typedef struct BlogMplsHdr {
+    union {
+        uint8_t   u8[BLOG_MPLS_HDR_LEN];
+        uint16_t u16[BLOG_MPLS_HDR_LEN/sizeof(uint16_t)];
+        uint32_t u32[BLOG_MPLS_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            BE_DECL( uint32_t label:20; uint32_t cos:3; uint32_t sbit:1; uint32_t ttl:8; )
+            LE_DECL( uint32_t ttl:8; uint32_t sbit:1; uint32_t cos:3; uint32_t label:20; )
+        };
+    };
+} BlogMplsHdr_t;
+
+
+/*----- IPv4: RFC 791 definitions --------------------------------------------*/
+#define BLOG_IPV4_HDR_LEN       20  /* Not including IP Options */
+#define BLOG_IPV4_ADDR_LEN      4
+#define BLOG_IPV4_HDR_FMT       "[0x%08X] ver<%u> ihl<%u> tos<0x%02X> len<%u> "\
+                                "[0x%08X] id<%u> df<%u> mf<%u> "\
+                                "fragOffset<0x%04X> [0x%08X] "\
+                                "ttl<%u> proto<%u> chkSum<0x%04X> "\
+#define BLOG_IPV4_HDR(i)        i.u32[0], i.ver, i.ihl, i.tos, i.len, \
+                                i.u32[1], i.id, i.df, i.mf, i.fragOffset,\
+                                i.u32[2], i.ttl, i.proto, i.chkSum,
+#define BLOG_IPTOS2DSCP(tos)    ((tos) >> 2)
+#define BLOG_IPDSCP2TOS(dscp)   ((dscp) << 2)
+
+#define BLOG_IPV4_ADDR_FMT      "<%03u.%03u.%03u.%03u>"
+#define BLOG_IPV4_ADDR_PORT_FMT "<%03u.%03u.%03u.%03u:%u>"
+#define BLOG_IPV4_ADDR(ip)      ((uint8_t*)&ip)[0], ((uint8_t*)&ip)[1],     \
+                                ((uint8_t*)&ip)[2], ((uint8_t*)&ip)[3]
+
+#if defined(CONFIG_CPU_BIG_ENDIAN)
+#define BLOG_IPV4_ADDR_HOST(ip)      ((uint8_t*)&ip)[0], ((uint8_t*)&ip)[1], \
+                                     ((uint8_t*)&ip)[2], ((uint8_t*)&ip)[3]
+#elif defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+#define BLOG_IPV4_ADDR_HOST(ip)      ((uint8_t*)&ip)[3], ((uint8_t*)&ip)[2], \
+                                     ((uint8_t*)&ip)[1], ((uint8_t*)&ip)[0]
+#endif
+
+typedef union BlogIpv4Addr {
+    uint8_t   u8[BLOG_IPV4_ADDR_LEN];
+    uint16_t u16[BLOG_IPV4_ADDR_LEN/sizeof(uint16_t)];
+    uint32_t u32[BLOG_IPV4_ADDR_LEN/sizeof(uint32_t)];
+} BlogIpv4Addr_t;
+
+#define BLOG_IP_FLAG_CE         0x8000      /* Congestion */
+#define BLOG_IP_FLAG_DF         0x4000      /* Do Not Fragment */
+#define BLOG_IP_FLAG_MF         0x2000      /* More Fragment */
+#define BLOG_IP_FRAG_OFFSET     0x1FFF 
+
+typedef struct BlogIpv4Hdr {
+    union {
+        uint8_t      u8[BLOG_IPV4_HDR_LEN];
+        uint16_t    u16[BLOG_IPV4_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_IPV4_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            union {
+                struct {
+                    BE_DECL( uint8_t ver:4; uint8_t ihl:4; ) 
+                    LE_DECL( uint8_t ihl:4; uint8_t ver:4; )
+                };
+                uint8_t ver_ihl;
+            };
+            uint8_t   tos; uint16_t len;
+            uint16_t  id;
+            union {
+                uint16_t flagsFrag;
+                struct {
+                    BE_DECL( uint16_t cong:1; uint16_t df:1; 
+                             uint16_t moreFrag:1; uint16_t fragOffset:13; )
+                    LE_DECL( uint16_t fragOffset:13; uint16_t moreFrag:1; 
+                             uint16_t df:1; uint16_t cong:1; )
+                };
+            };
+            uint8_t ttl; uint8_t proto; uint16_t chkSum;
+            BlogIpv4Addr_t  sAddr;
+            BlogIpv4Addr_t  dAddr;
+        };
+    };
+} BlogIpv4Hdr_t;
+
+
+/*----- IPv6: RFC 2460 RFC 3513 definitions ----------------------------------*/
+/*
+  * Well know IPv6 Address prefixes
+ *      Multicast:   FFXX::
+ *      Site local:  FEC0::
+ *      Link Local:  FE80::
+ *      Ucast 6to4:  2002::
+ */
+#define BLOG_IPV6_HDR_LEN       40
+#define BLOG_IPV6_ADDR_LEN      16
+
+#define BLOG_IPV6_ADDR_FMT      "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x>"
+#define BLOG_IPV6_ADDR_PORT_FMT "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u>"
+#define BLOG_IPV6_ADDR(ip)      \
+    ntohs(((uint16_t*)&ip)[0]), ntohs(((uint16_t*)&ip)[1]),   \
+    ntohs(((uint16_t*)&ip)[2]), ntohs(((uint16_t*)&ip)[3]),   \
+    ntohs(((uint16_t*)&ip)[4]), ntohs(((uint16_t*)&ip)[5]),   \
+    ntohs(((uint16_t*)&ip)[6]), ntohs(((uint16_t*)&ip)[7])
+
+typedef union BlogIpv6Addr {
+    uint8_t   u8[BLOG_IPV6_ADDR_LEN];
+    uint16_t  u16[BLOG_IPV6_ADDR_LEN/sizeof(uint16_t)];
+    uint32_t  u32[BLOG_IPV6_ADDR_LEN/sizeof(uint32_t)];
+} BlogIpv6Addr_t;
+
+typedef struct BlogIpv6Hdr {
+    union {
+        uint8_t      u8[BLOG_IPV6_HDR_LEN];
+        uint16_t    u16[BLOG_IPV6_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_IPV6_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            /* ver_tos bits -> ver 4: tos 8: flowlblHi 4 
+               using bit field results in unaligned access */
+            uint16_t ver_tos; uint16_t flowLblLo;
+            uint16_t len; uint8_t nextHdr; uint8_t hopLmt;
+            BlogIpv6Addr_t  sAddr;
+            BlogIpv6Addr_t  dAddr;
+        };
+    };
+} BlogIpv6Hdr_t;
+
+#define BLOG_IPV6EXT_HDR_LEN    8   /* multiple of 8 octets */
+typedef struct BlogIpv6ExtHdr {
+    union {
+        uint8_t      u8[BLOG_IPV6EXT_HDR_LEN];
+        uint16_t    u16[BLOG_IPV6EXT_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_IPV6EXT_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            uint8_t nextHdr; uint8_t hdrLen; uint16_t data16;
+            uint32_t data32;
+        };
+    };
+} BlogIpv6ExtHdr_t;
+
+
+/*----- Transmission Control Protocol: RFC 793 definitions -------------------*/
+
+#define BLOG_TCP_HDR_LEN        20
+
+#define TCPH_DOFF(t)            (((htons(t->offFlags.u16)) >> 12) & 0xF)
+#define TCPH_CWR(t)             (((htons(t->offFlags.u16)) >>  7) & 0x1)
+#define TCPH_ECE(t)             (((htons(t->offFlags.u16)) >>  6) & 0x1)
+#define TCPH_URG(t)             (((htons(t->offFlags.u16)) >>  5) & 0x1)
+#define TCPH_ACK(t)             (((htons(t->offFlags.u16)) >>  4) & 0x1)
+#define TCPH_PSH(t)             (((htons(t->offFlags.u16)) >>  3) & 0x1)
+#define TCPH_RST(t)             (((htons(t->offFlags.u16)) >>  2) & 0x1)
+#define TCPH_SYN(t)             (((htons(t->offFlags.u16)) >>  1) & 0x1)
+#define TCPH_FIN(t)             (((htons(t->offFlags.u16)) >>  0) & 0x1)
+
+typedef struct BlogTcpOffFlags {
+    union {
+        uint16_t u16;
+        struct { uint8_t off; uint8_t flags; };
+        struct {
+            BE_DECL(
+                uint16_t   dOff:   4;
+                uint16_t   res1:   4;
+                uint16_t   cwr :   1;
+                uint16_t   ece :   1;
+                uint16_t   urg :   1;
+                uint16_t   ack :   1;
+                uint16_t   psh :   1;
+                uint16_t   rst :   1;
+                uint16_t   syn :   1;
+                uint16_t   fin :   1;
+            )
+            LE_DECL(
+                uint16_t   fin :   1;
+                uint16_t   syn :   1;
+                uint16_t   rst :   1;
+                uint16_t   psh :   1;
+                uint16_t   ack :   1;
+                uint16_t   urg :   1;
+                uint16_t   ece :   1;
+                uint16_t   cwr :   1;
+                uint16_t   res1:   4;
+                uint16_t   dOff:   4;
+            )
+        };
+    };
+} BlogTcpOffFlags_t;
+
+typedef struct BlogTcpHdr {
+    union {
+        uint8_t      u8[BLOG_TCP_HDR_LEN];
+        uint16_t    u16[BLOG_TCP_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_TCP_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            uint16_t sPort; uint16_t dPort;
+            uint32_t seq;
+            uint32_t ackSeq;
+            BlogTcpOffFlags_t offFlags; uint16_t window;
+            uint16_t chkSum; uint16_t urgPtr;
+        };
+    };
+} BlogTcpHdr_t;
+
+
+/*----- User Datagram Protocol: RFC 768 definitions --------------------------*/
+#define BLOG_UDP_HDR_LEN        8
+
+typedef struct BlogUdpHdr {
+    union {
+        uint8_t      u8[BLOG_UDP_HDR_LEN];
+        uint16_t    u16[BLOG_UDP_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_UDP_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            uint16_t sPort; uint16_t dPort;
+            uint16_t len; uint16_t chkSum;
+        };
+    };
+} BlogUdpHdr_t;
+
+
+/*----- L2TP: RFC 2661 definitions -------------------------------------------*/
+#define BLOG_L2TP_HDR_LEN       8
+
+typedef struct BlogL2tpIeFlagsVer {
+    union {
+        uint16_t u16;
+        struct {
+            BE_DECL(
+                uint16_t   type   : 1;
+                uint16_t   lenIe  : 1;
+                uint16_t   rsvd2  : 2;
+                uint16_t   seqIe  : 1;
+                uint16_t   rsvd1  : 1;
+                uint16_t   offIe  : 1;
+                uint16_t   prio   : 1;
+                uint16_t   rsvd4  : 4;
+                uint16_t   ver    : 4;
+            )
+            LE_DECL(
+                uint16_t   ver    : 4;
+                uint16_t   rsvd4  : 4;
+                uint16_t   prio   : 1;
+                uint16_t   offIe  : 1;
+                uint16_t   rsvd1  : 1;
+                uint16_t   seqIe  : 1;
+                uint16_t   rsvd2  : 2;
+                uint16_t   lenIe  : 1;
+                uint16_t   type   : 1;
+            )
+        };
+    };
+} BlogL2tpIeFlagsVer_t;
+
+typedef struct BlogL2tpHdr {
+    union {
+        uint8_t      u8[BLOG_L2TP_HDR_LEN];
+        uint16_t    u16[BLOG_L2TP_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_L2TP_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            BlogL2tpIeFlagsVer_t ieFlagsVer; uint16_t len;
+            uint16_t tId; uint16_t sId;
+            /* uint16_t ns; uint16_t nr;
+               uint16_t offSz; uint16_t offPad; */
+        };
+    };
+} BlogL2tpHdr_t;
+
+
+/*----- Generic Routing Encapsulation: RFC 2637, PPTP session, RFC 2784 ------*/
+#define BLOG_GRE_HDR_LEN        8
+
+typedef struct BlogGreIeFlagsVer {
+    union {
+        uint16_t    u16;
+        struct {
+            BE_DECL(
+                uint16_t   csumIe : 1;
+                uint16_t   rtgIe  : 1;
+                uint16_t   keyIe  : 1;
+                uint16_t   seqIe  : 1;
+                uint16_t   srcRtIe: 1;
+                uint16_t   recurIe: 3;
+                uint16_t   ackIe  : 1;
+                uint16_t   flags  : 4;
+                uint16_t   ver    : 3;
+            )
+            LE_DECL(
+                uint16_t   ver    : 3;
+                uint16_t   flags  : 4;
+                uint16_t   ackIe  : 1;
+                uint16_t   recurIe: 3;
+                uint16_t   srcRtIe: 1;
+                uint16_t   seqIe  : 1;
+                uint16_t   keyIe  : 1;
+                uint16_t   rtgIe  : 1;
+                uint16_t   csumIe : 1;
+            )
+        };
+    };
+} BlogGreIeFlagsVer_t;
+
+typedef struct BlogGreHdr {
+    union {
+        uint8_t      u8[BLOG_GRE_HDR_LEN];
+        uint16_t    u16[BLOG_GRE_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_GRE_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            BlogGreIeFlagsVer_t ieFlagsVer; uint16_t proto;
+            /* RFC2784 specifies csum instead of len, for GRE ver = 0 */
+            /* RFC2637 specifies len, for GRE ver=1 used with PPTP    */
+            uint16_t len; uint16_t callId;
+            /* uint32_t seqNum; present if seqIe = 1 */
+            /* uint32_t ackNum; present if ackIe = 1 */
+        };
+    };
+} BlogGreHdr_t;
+
+/*----- VXLAN: RFC 7348 definitions --------------------------------------------------*/
+#define BLOG_VXLAN_PORT     4789
+#define BLOG_VXLAN_HDR_LEN  8
+#define BLOG_VXLAN_TUNNEL_MAX_LEN (BLOG_IPV6_HDR_LEN + BLOG_UDP_HDR_LEN + BLOG_VXLAN_HDR_LEN)
+#define BLOG_VXLAN_HF_VNI (1UL << 27)
+#define BLOG_VXLAN_VNI_OFFSET 8
+typedef struct BlogVxlanHdr {
+    union {
+        uint8_t      u8[BLOG_VXLAN_HDR_LEN];
+        uint16_t    u16[BLOG_VXLAN_HDR_LEN/sizeof(uint16_t)];
+        uint32_t    u32[BLOG_VXLAN_HDR_LEN/sizeof(uint32_t)];
+        struct {
+            uint32_t flags;
+            uint32_t vni;
+        };
+    };
+} BlogVxlanHdr_t;
+
+/*
+ *------------------------------------------------------------------------------
+ *  Assert that headers are properly packed (without using attribute packed) 
+ *
+ *  #include <stdio.h>
+ *  #include <stdint.h>
+ *  #include "blog_net.h"
+ *  int main() {
+ *      printf("blog_net_audit_hdrs %d\n", blog_net_audit_hdrs() );
+ *      return blog_net_audit_hdrs();
+ *  }
+ *------------------------------------------------------------------------------
+ */
+static inline int blog_net_audit_hdrs(void)
+{
+#define BLOG_NET_AUDIT(hdrlen,hdrtype)  \
+    if (hdrlen != sizeof(hdrtype))      \
+        return (-1)
+
+    BLOG_NET_AUDIT( BLOG_ETH_ADDR_LEN, BlogEthAddr_t );
+    BLOG_NET_AUDIT( BLOG_ETH_HDR_LEN, BlogEthHdr_t );
+    BLOG_NET_AUDIT( BLOG_BRCM6_HDR_LEN, BlogBrcm6Hdr_t );
+    BLOG_NET_AUDIT( BLOG_BRCM4_HDR_LEN, BlogBrcm4Hdr_t );
+    BLOG_NET_AUDIT( BLOG_ETHBRCM6_HDR_LEN, BlogEthBrcm6Hdr_t );
+    BLOG_NET_AUDIT( BLOG_ETHBRCM4_HDR_LEN, BlogEthBrcm4Hdr_t );
+    BLOG_NET_AUDIT( BLOG_VLAN_HDR_LEN, BlogVlanHdr_t );
+    BLOG_NET_AUDIT( BLOG_PPPOE_HDR_LEN, BlogPppoeHdr_t );
+    BLOG_NET_AUDIT( BLOG_MPLS_HDR_LEN, BlogMplsHdr_t );
+    BLOG_NET_AUDIT( BLOG_IPV4_ADDR_LEN, BlogIpv4Addr_t );
+    BLOG_NET_AUDIT( BLOG_IPV4_HDR_LEN, BlogIpv4Hdr_t );
+    BLOG_NET_AUDIT( BLOG_IPV6_ADDR_LEN, BlogIpv6Addr_t );
+    BLOG_NET_AUDIT( BLOG_IPV6_HDR_LEN, BlogIpv6Hdr_t );
+    BLOG_NET_AUDIT( BLOG_TCP_HDR_LEN, BlogTcpHdr_t );
+    BLOG_NET_AUDIT( BLOG_UDP_HDR_LEN, BlogUdpHdr_t );
+    BLOG_NET_AUDIT( BLOG_L2TP_HDR_LEN, BlogL2tpHdr_t );
+    BLOG_NET_AUDIT( BLOG_GRE_HDR_LEN, BlogGreHdr_t );
+    BLOG_NET_AUDIT( BLOG_VXLAN_HDR_LEN, BlogVxlanHdr_t);
+
+    return 0;
+}
+
+
+
+
+
+/*
+ *------------------------------------------------------------------------------
+ * Network Utilities  : 16bit aligned
+ *------------------------------------------------------------------------------
+ */
+#if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+/*
+ *------------------------------------------------------------------------------
+ * Function     : blog_read32_align16
+ * Description  : Read a 32bit value from a 16 byte aligned data stream
+ *------------------------------------------------------------------------------
+ */
+static inline uint32_t blog_read32_align16( uint16_t * from )
+{
+    return (uint32_t)( (from[1] << 16) | from[0] );
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Function     : blog_write32_align16
+ * Description  : Write a 32bit value to a 16bit aligned data stream
+ *------------------------------------------------------------------------------
+ */
+static inline void blog_write32_align16( uint16_t * to, uint32_t from )
+{
+    to[1] = (uint16_t)htons(from >> 16);
+    to[0] = (uint16_t)htons(from >> 0);
+}
+
+#elif defined(CONFIG_CPU_BIG_ENDIAN)
+
+/*
+ *------------------------------------------------------------------------------
+ * Function     : blog_read32_align16
+ * Description  : Read a 32bit value from a 16 byte aligned data stream
+ *------------------------------------------------------------------------------
+ */
+static inline uint32_t blog_read32_align16( uint16_t * from )
+{
+    return (uint32_t)( (from[0] << 16) | (from[1]) );
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Function     : blog_write32_align16
+ * Description  : Write a 32bit value to a 16bit aligned data stream
+ *------------------------------------------------------------------------------
+ */
+static inline void blog_write32_align16( uint16_t * to, uint32_t from )
+{
+    to[0] = (uint16_t)(from >> 16);
+    to[1] = (uint16_t)(from >>  0);
+}
+#endif /* defined(CONFIG_CPU_BIG_ENDIAN) */
+
+#endif /* defined(__BLOG_NET_H_INCLUDED__) */
diff --git a/include/linux/blog_rule.h b/include/linux/blog_rule.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4c099831c344f01632076af45cc651d8e36062e
--- /dev/null
+++ b/include/linux/blog_rule.h
@@ -0,0 +1,256 @@
+#if defined(CONFIG_BLOG)
+#ifndef __BLOG_RULE_H_INCLUDED__
+#define __BLOG_RULE_H_INCLUDED__
+
+/* 
+* <:copyright-BRCM:2010:DUAL/GPL:standard
+* 
+*    Copyright (c) 2010 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+:>
+*/
+
+/*
+ *******************************************************************************
+ *
+ * File Name  : blog_rule.h
+ *
+ * Description: Blog rules are extensions to a Blog structure that can be used
+ *              to specify additional fiters and modifications.
+ *
+ *******************************************************************************
+ */
+
+#define CC_CONFIG_BLOG_RULE_DEBUG
+
+#define BLOG_RULE_VERSION      "v1.0"
+
+#define BLOG_RULE_VLAN_TAG_MAX  3
+
+#define BLOG_RULE_ACTION_MAX    16
+
+#define BLOG_RULE_PBITS_MASK    0xE000
+#define BLOG_RULE_PBITS_SHIFT   13
+#define BLOG_RULE_DEI_MASK      0x1000
+#define BLOG_RULE_DEI_SHIFT     12
+#define BLOG_RULE_VID_MASK      0x0FFF
+#define BLOG_RULE_VID_SHIFT     0
+
+#define BLOG_RULE_GET_TCI_PBITS(_tci) \
+    ( ((_tci) & BLOG_RULE_PBITS_MASK) >> BLOG_RULE_PBITS_SHIFT )
+
+#define BLOG_RULE_GET_TCI_DEI(_tci) \
+    ( ((_tci) & BLOG_RULE_DEI_MASK) >> BLOG_RULE_DEI_SHIFT )
+
+#define BLOG_RULE_GET_TCI_VID(_tci) \
+    ( (_tci) & BLOG_RULE_VID_MASK )
+
+#define BLOG_RULE_DSCP_IN_TOS_MASK    0xFC
+#define BLOG_RULE_DSCP_IN_TOS_SHIFT   2
+
+#define BLOG_RULE_IP_PROTO_MASK    0xFF
+#define BLOG_RULE_IP_PROTO_SHIFT   0
+#define BLOG_RULE_IP6_NXT_HDR_MASK    0xFF
+#define BLOG_RULE_IP6_NXT_HDR_SHIFT   0
+
+#define blog_rule_filterInUse(_filter)                          \
+    ({                                                          \
+        char *_filter_p = (char *)(&_filter);                   \
+        int _i, _val;                                           \
+        for(_i=0; _i<sizeof(_filter); ++_i) {                   \
+            if((_val = _filter_p[_i]) != 0) break;              \
+        }                                                       \
+        _val;                                                   \
+    })
+
+typedef struct {
+    struct ethhdr mask;
+    struct ethhdr value;
+} blogRuleFilterEth_t;
+
+typedef struct {
+    union {
+        struct vlan_hdr mask;
+        uint32_t mask32;
+    };
+    union {
+        struct vlan_hdr value;
+        uint32_t value32;
+    };
+} blogRuleFilterVlan_t;
+
+typedef struct {
+    /* only contains the fields we are interested */
+    uint8_t tos;
+    uint8_t ip_proto;
+} blogRuleIpv4Header_t;
+
+typedef struct {
+    blogRuleIpv4Header_t mask;
+    blogRuleIpv4Header_t value;
+} blogRuleFilterIpv4_t;
+
+typedef struct {
+    /* only contains the fields we are interested */
+    uint8_t tclass;
+    uint8_t nxtHdr;
+} blogRuleIpv6Header_t;
+
+typedef struct {
+    blogRuleIpv6Header_t mask;
+    blogRuleIpv6Header_t value;
+} blogRuleFilterIpv6_t;
+
+typedef struct {
+    uint32_t priority;     /* skb priority filter value is offset by 1 because
+                            * 0 is reserved to indicate filter not in use.
+                            * Therefore the supported skb priority range is
+                            * [0 to 0xfffffffe].
+                            */
+    uint16_t markFlowId;
+    uint16_t markPort;     /* port mark filter value is offset by 1 because
+                            * 0 is reserved to indicate filter not in use.
+                            * Therefore use 16-bit to cover the supported
+                            * port range [0 to 255].
+                            */ 
+} blogRuleFilterSkb_t;
+
+typedef struct {
+    blogRuleFilterEth_t eth;
+    uint32_t nbrOfVlanTags;
+    blogRuleFilterVlan_t vlan[BLOG_RULE_VLAN_TAG_MAX];
+    uint32_t hasPppoeHeader;
+    blogRuleFilterIpv4_t ipv4;
+    blogRuleFilterIpv6_t ipv6;
+    blogRuleFilterSkb_t  skb;
+    uint32_t flags;
+#define BLOG_RULE_FILTER_FLAGS_IS_UNICAST   0x0001
+#define BLOG_RULE_FILTER_FLAGS_IS_MULTICAST 0x0002
+#define BLOG_RULE_FILTER_FLAGS_IS_BROADCAST 0x0004
+} blogRuleFilter_t;
+
+#define BLOG_RULE_FILTER_FLAGS_ALL               \
+    ( BLOG_RULE_FILTER_FLAGS_IS_UNICAST   |      \
+      BLOG_RULE_FILTER_FLAGS_IS_MULTICAST |      \
+      BLOG_RULE_FILTER_FLAGS_IS_BROADCAST )
+
+#undef  BLOG_RULE_DECL
+#define BLOG_RULE_DECL(x) x
+
+typedef enum {
+    BLOG_RULE_DECL(BLOG_RULE_CMD_NOP=0),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_MAC_DA),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_MAC_SA),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_ETHERTYPE),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_PUSH_VLAN_HDR),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_POP_VLAN_HDR),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_PBITS),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_DEI),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_VID),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_VLAN_PROTO),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_PBITS),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_DEI),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_VID),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_VLAN_PROTO),
+//    BLOG_RULE_DECL(BLOG_RULE_CMD_XLATE_DSCP_TO_PBITS),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_POP_PPPOE_HDR),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_DSCP),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_DECR_TTL),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_DECR_HOP_LIMIT),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_DROP),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_SKB_MARK_PORT),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_SKB_MARK_QUEUE),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_OVRD_LEARNING_VID),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_SET_STA_MAC_ADDRESS),
+    BLOG_RULE_DECL(BLOG_RULE_CMD_MAX)
+} blogRuleCommand_t;
+
+typedef struct {
+    uint8_t cmd; // blogRuleCommand_t
+    uint8_t toTag;
+    union {
+        uint16_t etherType;
+        uint16_t tpid;
+        uint16_t pbits;
+        uint16_t dei;
+        uint16_t vid;
+        uint16_t vlanProto;
+        uint16_t dscp;
+        uint16_t fromTag;
+        uint16_t skbMarkQueue;
+        uint16_t skbMarkPort;
+        uint16_t arg;
+        uint8_t macAddr[ETH_ALEN];
+    };
+} blogRuleAction_t;
+
+typedef struct blogRule {
+    blogRuleFilter_t filter;
+    uint32_t actionCount;
+    blogRuleAction_t action[BLOG_RULE_ACTION_MAX];
+    struct blogRule *next_p;
+} blogRule_t;
+
+typedef enum {
+    BLOG_RULE_VLAN_NOTIFY_DIR_RX,
+    BLOG_RULE_VLAN_NOTIFY_DIR_TX,
+    BLOG_RULE_VLAN_NOTIFY_DIR_MAX
+} blogRuleVlanNotifyDirection_t;
+
+/*
+ * blogRuleVlanHook_t: The Linux VLAN manager must use this hook to register
+ * the handler that creates Blog Rules based on the configured VLAN Rules.
+ */
+typedef int (* blogRuleVlanHook_t)(void *arg_p,
+                                   struct net_device *rxVlanDev,
+                                   struct net_device *txVlanDev);
+
+/*
+ * blogRuleVlanNotifyHook_t: The Linux VLAN manager uses this hook to notify
+ * the registered handler whenever VLAN Rules are added or removed.
+ * The device (dev) can be either a VLAN interface or a Real interface.
+ */
+typedef void (* blogRuleVlanNotifyHook_t)(struct net_device *dev,
+                                          blogRuleVlanNotifyDirection_t direction,
+                                          uint32_t nbrOfTags);
+
+extern blogRuleVlanHook_t blogRuleVlanHook;
+extern blogRuleVlanNotifyHook_t blogRuleVlanNotifyHook;
+
+typedef int (* blogArlHook_t)(void *e);
+
+extern blogArlHook_t bcm_arl_process_hook_g;
+
+/* -------------- User API -------------- */
+
+blogRule_t *blog_rule_alloc(void);
+void blog_rule_free(blogRule_t *blogRule_p);
+int blog_rule_free_list(void *blogRule_p);
+void blog_rule_init(blogRule_t *blogRule_p);
+void blog_rule_dump(blogRule_t *blogRule_p);
+int blog_rule_add_action(blogRule_t *blogRule_p, blogRuleAction_t *action_p);
+int blog_rule_delete_action(void *rule_p);
+
+#endif /* defined(__BLOG_RULE_H_INCLUDED__) */
+#endif /* defined(CONFIG_BLOG) */
diff --git a/include/linux/br_fp.h b/include/linux/br_fp.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b0a4c4d3030b661eba1a469d64b67334c24db0a
--- /dev/null
+++ b/include/linux/br_fp.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; 
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef BR_FP_H
+#define BR_FP_H
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#define BR_FP_FDB_ADD 1
+#define BR_FP_FDB_REMOVE 2
+#define BR_FP_FDB_MODIFY 3
+#define BR_FP_FDB_CHECK_AGE 4
+#define BR_FP_PORT_ADD 5
+#define BR_FP_PORT_REMOVE 6
+#define BR_FP_LOCAL_SWITCHING_DISABLE 7
+#define BR_FP_BRIDGE_TYPE 8
+
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+struct br_fp_data
+{
+    int (*rdpa_hook)(int cmd, void *in, void *out);
+    void *rdpa_obj;
+};
+#endif /* CONFIG_BCM_RDPA_BRIDGE || CONFIG_BCM_RDPA_BRIDGE_MODULE */
+
+struct bcm_br_ext
+{
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+    struct  br_fp_data br_fp_data;
+#define bridge_fp_data_hook_get(_br_dev)        (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.br_fp_data.rdpa_hook))
+#define bridge_fp_data_hook_set(_br_dev, _hook) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.br_fp_data.rdpa_hook, (_hook))
+#define bridge_fp_data_obj_get(_br_dev)         (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.br_fp_data.rdpa_obj))
+#define bridge_fp_data_obj_set(_br_dev, _obj)   bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.br_fp_data.rdpa_obj, (_obj))
+
+#define br_fp_hook(_br_dev, _cmd, _arg1, _arg2) (bridge_fp_data_hook_get((_br_dev)) ? bridge_fp_data_hook_get((_br_dev))((_cmd), (_arg1), (_arg2)) : 0)
+#endif
+
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+    int     local_switching_disable;
+#define bridge_local_switching_disable_get(_br_dev)       (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.local_switching_disable))
+#define bridge_local_switching_disable_set(_br_dev, _val) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.local_switching_disable, (_val))
+#else
+#define bridge_local_switching_disable_get(_br_dev)       ((void)(_br_dev), 0)
+#define bridge_local_switching_disable_set(_br_dev, _val) ((void)(_br_dev), (void)(_val), 0)
+#endif
+
+#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE)
+    u32     mac_entry_discard_counter;
+#define bridge_mac_entry_discard_counter_get(_br_dev) (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.mac_entry_discard_counter))
+#define bridge_mac_entry_discard_counter_set(_br_dev, _val) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.mac_entry_discard_counter, (_val))
+#define bridge_mac_entry_discard_counter_inc(_br_dev) ((bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.mac_entry_discard_counter)++))
+#else
+#define bridge_mac_entry_discard_counter_get(_br_dev) ((void)(br_dev), 0)
+#define bridge_mac_entry_discard_counter_set(_br_dev, _val) do {} while(0)
+#define bridge_mac_entry_discard_counter_inc(_br_dev) do {} while(0)
+#endif
+};
+
+#endif /* BR_FP_H */
diff --git a/include/linux/brcm_dll.h b/include/linux/brcm_dll.h
new file mode 100644
index 0000000000000000000000000000000000000000..3358c2de7d252635b585744f795016f377d68bc0
--- /dev/null
+++ b/include/linux/brcm_dll.h
@@ -0,0 +1,123 @@
+#ifndef _dll_t_
+#define _dll_t_
+/*
+<:copyright-BRCM:2014:DUAL/GPL:standard 
+
+   Copyright (c) 2014 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+#if !defined(_envelope_of)
+/* derived from container_of, without "const", for gcc -Wcast-qual compile */
+#define _envelope_of(ptr, type, member) \
+({ \
+	typeof(((type *)0)->member) *__mptr = (ptr); \
+	(type *)((char *)__mptr - offsetof(type, member)); \
+})
+#endif /* _envelope_of */
+
+
+typedef struct dll_t dll_t; /* common to wlan bcmutils.h, pktHdr.h */
+typedef struct dll_t {
+	dll_t * next_p;
+	dll_t * prev_p;
+} Dll_t, * PDll_t;
+
+#define dll dll_t
+
+#define DLL_STRUCT_INITIALIZER(struct_name, dll_name) \
+	{ .next_p = &(struct_name).dll_name, .prev_p = &(struct_name).dll_name }
+
+#define dll_init(node_p)        ((node_p)->next_p = (node_p)->prev_p = (node_p))
+
+/* dll macros returing a "dll_t *" */
+#define dll_head_p(list_p)      ((list_p)->next_p)
+#define dll_tail_p(list_p)      ((list_p)->prev_p)
+
+#define dll_next_p(node_p)      ((node_p)->next_p)
+#define dll_prev_p(node_p)      ((node_p)->prev_p)
+
+#define dll_empty(list_p)       ((list_p)->next_p == (list_p))
+#define dll_end(list_p, node_p) ((list_p) == (node_p))
+
+/* inserts the node new_p "after" the node at_p */
+#define dll_insert(new_p, at_p) \
+({ \
+	(new_p)->next_p = (at_p)->next_p; \
+	(new_p)->prev_p = (at_p); \
+	(at_p)->next_p = (new_p); \
+	(new_p)->next_p->prev_p = (new_p); \
+})
+
+#define dll_append(list_p, node_p)      dll_insert((node_p), dll_tail_p(list_p))
+#define dll_prepend(list_p, node_p)     dll_insert((node_p), (list_p))
+
+/* deletes a node from any list that it "may" be in, if at all. */
+#define dll_delete(node_p) \
+({ \
+	(node_p)->prev_p->next_p = (node_p)->next_p; \
+	(node_p)->next_p->prev_p = (node_p)->prev_p; \
+})
+
+/**
+ * dll_for_each -   iterate over a list
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @head:   the head for your list.
+ *
+ * Iterator "pos" may not be moved.
+ *
+ * If you need to delete the iterator, then use the below sample.
+ *   dll_t * iter_p, * next_p;
+ *   for (iter_p = dll_head_p(&someList); ! dll_end(&someList, iter_p);
+ *        iter_p = next_p)
+ *   {
+ *       next_p = dll_next_p(iter_p);
+ *       ... use iter_p at will, including removing it from list ...
+ *   }
+ *
+ */
+#define dll_for_each(pos, head) \
+	for (pos = (head)->next_p; pos != (head); pos = pos->next_p)
+
+/**
+ * Take all elements of list A and join them to the tail of list B.
+ * List A must not be empty and list A will be returned as an empty list.
+ */
+#define dll_join(listA_p, listB_p) \
+({ \
+	dll_t *_listB_p = (listB_p); \
+	dll_t *headA_p  = dll_head_p(listA_p); \
+	dll_t *tailA_p  = dll_tail_p(listA_p); \
+	dll_t *tailB_p  = dll_tail_p(listB_p); \
+	/* Link up list B's tail to list A's head */ \
+	headA_p->prev_p = tailB_p; \
+	tailB_p->next_p = headA_p; \
+	/* Make list A's tail to be list B's new tail */ \
+	tailA_p->next_p = (listB_p); \
+	_listB_p->prev_p = tailA_p; \
+	dll_init(listA_p); \
+})
+
+#endif  /* ! defined(_dll_t_) */
diff --git a/include/linux/buzzz_kevt.h b/include/linux/buzzz_kevt.h
new file mode 100644
index 0000000000000000000000000000000000000000..1530b1655d0a77870cfde9a3557c7690fe78b62c
--- /dev/null
+++ b/include/linux/buzzz_kevt.h
@@ -0,0 +1,81 @@
+#ifndef __buzzz_kevt_h_included__
+#define __buzzz_kevt_h_included__
+
+#if defined(CONFIG_BUZZZ_KEVT) || defined(CONFIG_BUZZZ_FUNC)
+/*
+ * +----------------------------------------------------------------------------
+ *
+ * BCM BUZZZ ARM Cortex A9 Router Kernel events
+ *
+ * $Copyright Open Broadcom Corporation$
+ * $Id$
+ *
+ * vim: set ts=4 noet sw=4 tw=80:
+ * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+ *
+ * +----------------------------------------------------------------------------
+ */
+
+#include <uapi/linux/buzzz.h>
+
+#undef BUZZZ_KEVT
+#define BUZZZ_KEVT(event)       BUZZZ_KEVT__ ## event,
+
+#define BUZZZ_KEVT_REG(event, format) \
+    buzzz_event_reg(BUZZZ_KEVT__## event, "\t\t" format);
+
+/**
+ * DO NOT SUBMIT USER EVENTS
+ *
+ * For private debug (not for submission), a user event may be added by:
+ * 1. Add an enum entry to buzzz_rtr_dpid,
+ *        e.g. BUZZZ_KEVT(HELLO_WORLD)
+ *
+ * 2. Add an entry to buzzz_dp_init(),
+ *        e.g. BUZZZ_KEVT_REG(HELLO_WORLD,   "hello world at %pS from %pS")
+ *
+ * 3. In source code base, insert instrumentation:
+ *        e.g. BUZZZ_DPL3(HELLO_WORLD, 2,
+ *                       BUZZZ32(BUZZZ_CUR_IP_), BUZZZ32(BUZZZ_RET_IP_));
+ *
+ *    See uapi/linux/buzzz.h, where BUZZZ_DPL tracing level is set to 3, thereby
+ *    enabling all instrumentations BUZZZ_DPL1(), BUZZZ_DPL2() and BUZZZ_DPL3() 
+ *    Instrumentation with BUZZZ_DPL4() and BUZZZ_DPL5() are compiled out.
+ *
+ *    Second parameter to BUZZZ_DPL#() specifies the number of arguments to be
+ *    logged, in the above example, it is 2 arguments (maximum 3 arguments).
+ *    - First argument in example is current instruction address, and
+ *    - Second argument is return address.
+ *    Arguments are 32bit values. [Gets messy on 64b aarch]
+ *
+ * Do not forget to invoke, buzzz_dp_init() once ... say in a module init.
+ */
+typedef
+enum buzzz_rtr_dpid
+{
+    BUZZZ_KEVT__DATAPATH_START = 100,
+
+    BUZZZ_KEVT(SAMPLE)
+    /* Define user events here */
+
+} buzzz_rtr_dpid_t;
+
+
+/* Invoke this once in a datapath module's init */
+static inline int
+buzzz_dp_init(void)
+{
+    BUZZZ_KEVT_REG(SAMPLE,                "sample pkt<%p>")
+    /* Add user event logs here */
+
+    return 0;
+}
+#else  /* ! CONFIG_BUZZZ */
+#define BUZZZ_DPL1(ID, N, ARG...)   do {} while (0)
+#define BUZZZ_DPL2(ID, N, ARG...)   do {} while (0)
+#define BUZZZ_DPL3(ID, N, ARG...)   do {} while (0)
+#define BUZZZ_DPL4(ID, N, ARG...)   do {} while (0)
+#define BUZZZ_DPL5(ID, N, ARG...)   do {} while (0)
+#endif /* ! CONFIG_BUZZZ */
+
+#endif /* __buzzz_kevt_h_included__ */
diff --git a/include/linux/dpi.h b/include/linux/dpi.h
new file mode 100644
index 0000000000000000000000000000000000000000..2213408ea66cbfc4b27d8c866da3b421a7a028bc
--- /dev/null
+++ b/include/linux/dpi.h
@@ -0,0 +1,116 @@
+#if defined(CONFIG_BCM_KF_DPI)
+#ifndef _LINUX_DPI_H
+#define _LINUX_DPI_H
+
+#include <linux/if_ether.h>
+#include <linux/list.h>
+
+#define DPI_APPID_ONGOING_BIT		0
+#define DPI_APPID_IDENTIFIED_BIT	1
+#define DPI_APPID_FINAL_BIT		2
+#define DPI_APPID_STOP_CLASSIFY_BIT	3
+#define DPI_APPID_RESYNC_BIT		4
+#define DPI_DEVID_ONGOING_BIT		5
+#define DPI_DEVID_IDENTIFIED_BIT	6
+#define DPI_DEVID_FINAL_BIT		7
+#define DPI_DEVID_STOP_CLASSIFY_BIT	8
+#define DPI_URL_STOP_CLASSIFY_BIT	9
+#define DPI_CLASSIFICATION_STOP_BIT	14
+#define DPI_CT_INIT_FROM_WAN_BIT	15
+#define DPI_CT_DS_BYPASS_BIT		29
+#define DPI_CT_US_BYPASS_BIT		30
+#define DPI_CT_BLOCK_BIT		31
+
+#define DPI_NL_CHANGE_MASK		(1 << DPI_CT_BLOCK_BIT)
+
+#define DPI_URLINFO_MAX_HOST_LEN	64
+/* 256 was chosen as the max length of a hostname in a DHCP packet is 255. */
+#define DPI_HOSTNAME_MAX_LEN		256
+
+#define dpi_ct_init_from_wan(ct) \
+	test_bit(DPI_CT_INIT_FROM_WAN_BIT, &(ct)->bcm_ext.dpi.flags)
+
+struct dpi_ct_stats {
+	u64	pkts;
+	u64	bytes;
+};
+
+struct dpi_app {
+	u32			app_id;
+	atomic_t		refcount;
+	struct hlist_node	node;
+};
+
+struct dpi_dev {
+	u8			mac[ETH_ALEN];
+
+	u32			dev_id;
+	u16			category;
+	u16			family;
+	u16			vendor;
+	u16			os;
+	u16			os_class;
+	u16			prio;
+	char			hostname[DPI_HOSTNAME_MAX_LEN];
+
+	struct dpi_ct_stats	us;
+	struct dpi_ct_stats	ds;
+
+	atomic_t		refcount;
+	struct hlist_node	node;
+};
+
+struct dpi_appinst {
+	struct dpi_app		*app;
+	struct dpi_dev		*dev;
+	struct dpi_ct_stats	us;
+	struct dpi_ct_stats	ds;
+	atomic_t		refcount;
+	struct hlist_node	node;
+};
+
+struct dpi_url {
+	u32			len;
+	char			hostname[DPI_URLINFO_MAX_HOST_LEN];
+	atomic_t		refcount;
+	struct hlist_node	node;
+};
+
+struct dpi_info {
+	struct dpi_dev		*dev;
+	struct dpi_app		*app;
+	struct dpi_appinst	*appinst;
+	struct dpi_url		*url;
+	unsigned long		flags;
+};
+
+struct nf_conn;
+
+struct dpi_core_hooks {
+	void (*delete)(struct nf_conn *ct);
+};
+
+struct dpi_ct_hooks {
+	int (*event_report)(int eventmask, struct nf_conn *ct, u32 portid,
+			    int report);
+};
+
+/* ----- dpi functions ----- */
+struct dpi_info *dpi_info_get(struct nf_conn *conn);
+u32 dpi_app_id(struct dpi_app *app);
+u32 dpi_dev_id(struct dpi_dev *dev);
+u8 *dpi_mac(struct dpi_dev *dev);
+int dpi_url_len(struct dpi_url *url);
+char *dpi_url(struct dpi_url *url);
+struct dpi_ct_stats *dpi_appinst_stats(struct nf_conn *ct, int dir);
+struct dpi_ct_stats *dpi_dev_stats(struct nf_conn *ct, int dir);
+void dpi_block(struct nf_conn *conn);
+void dpi_nf_ct_delete(struct nf_conn *ct);
+int dpi_core_hooks_register(struct dpi_core_hooks *h);
+void dpi_core_hooks_unregister(void);
+int dpi_nf_ct_event_report(struct nf_conn *ct, u32 portid);
+void dpi_conntrack_init(void);
+void dpi_conntrack_cleanup(void);
+
+#endif /* _LINUX_DPI_H */
+#endif /* defined(CONFIG_BCM_KF_DPI) */
diff --git a/include/linux/gbpm.h b/include/linux/gbpm.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fbaf90bbec6c633703eeed747be880c1f977e2e
--- /dev/null
+++ b/include/linux/gbpm.h
@@ -0,0 +1,344 @@
+#ifndef __GBPM_H_INCLUDED__
+#define __GBPM_H_INCLUDED__
+
+/*
+ *
+<:copyright-BRCM:2007:DUAL/GPL:standard
+
+   Copyright (c) 2007 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+/*
+ *******************************************************************************
+ * File Name : gbpm.h
+ *
+ *******************************************************************************
+ */
+#define GBPM_VERSION             "v0.1"
+#define GBPM_VER_STR             GBPM_VERSION
+#define GBPM_MODNAME             "Broadcom GBPM "
+
+#define GBPM_ERROR               (-1)
+#define GBPM_SUCCESS             0
+
+#define GBPM_RXCHNL_MAX              4
+#define GBPM_RXCHNL_DISABLED         0
+#define GBPM_RXCHNL_ENABLED          1
+
+#define CONFIG_GBPM_API_HAS_GET_TOTAL_BUFS 1
+#define CONFIG_GBPM_API_HAS_GET_AVAIL_BUFS 1
+
+
+#if defined(CONFIG_BCM_XTMCFG) || defined(CONFIG_BCM_XTMCFG_MODULE)
+#define GBPM_XTM_SUPPORT
+#endif
+
+typedef enum {
+    GBPM_PORT_ETH,
+    GBPM_PORT_XTM,
+    GBPM_PORT_FWD,
+    GBPM_PORT_WLAN,
+    GBPM_PORT_USB,
+    GBPM_PORT_MAX
+} gbpm_port_t;
+
+#if defined(CONFIG_BCM_BPM_BUF_TRACKING)
+typedef enum {
+    GBPM_REF_BUFF,
+    GBPM_REF_FKB,
+    GBPM_REF_SKB
+} gbpm_reftype_t;
+
+typedef enum {
+    GBPM_DRV_BPM,
+    GBPM_DRV_ETH,
+    GBPM_DRV_XTM,
+    GBPM_DRV_KERN,
+    GBPM_DRV_BDMF,
+    GBPM_DRV_ARCHER,
+    GBPM_DRV_MAX
+} gbpm_driver_t;
+
+typedef enum {
+    GBPM_VAL_UNMARKED,
+    GBPM_VAL_ALLOC,
+    GBPM_VAL_CLONE,
+    GBPM_VAL_RECYCLE,
+    GBPM_VAL_FREE,
+    GBPM_VAL_RX,
+    GBPM_VAL_TX,
+    GBPM_VAL_ENTER,
+    GBPM_VAL_EXIT,
+    GBPM_VAL_INFO,
+    GBPM_VAL_INIT,
+    GBPM_VAL_COPY_SRC,
+    GBPM_VAL_COPY_DST,
+    GBPM_VAL_XLATE,
+    GBPM_VAL_MAX
+} gbpm_value_t;
+
+typedef struct
+{
+    size_t addr;
+    union {
+        uint16_t word;
+        struct {
+            uint16_t driver:4;
+            uint16_t info:4;
+            uint16_t reftype:2;
+            uint16_t value:6;
+        };
+    };
+} gbpm_mark_t;
+
+typedef struct
+{
+    atomic_t ref_cnt;
+    atomic_t idle_cnt;
+    uint32_t write;
+    gbpm_mark_t * mbuf_p;
+} gbpm_trail_t;
+
+typedef void  (* gbpm_mark_buf_hook_t) ( void *, void *, int, int, int, int );
+typedef void  (* gbpm_add_ref_hook_t) ( void *, int );
+#endif /* bpm tracking */
+
+/*
+ *-----------------------------------------------------------------------------
+ * GBPM callbacks are managed in a single global instantiation of gbpm_t gbpm_g
+ * GBPM Hooks may be viewed as "BPM" callbacks and "User" callbacks.
+ * - GBPM_BIND() lists all BPM callbacks
+ * - GBPM_USER() lists all USER callbacks (bind per user driver module).
+ *-----------------------------------------------------------------------------
+ */
+
+/* GBPM_DECL may be undef/define, for GBPM_BIND and GBPM_USER template usage */
+#define GBPM_BIND()                         \
+    /* --- BPM BUF POOL --- */              \
+    GBPM_DECL(alloc_mult_buf)               \
+    GBPM_DECL(alloc_mult_buf_ex)            \
+    GBPM_DECL(free_mult_buf)                \
+    GBPM_DECL(alloc_buf)                    \
+    GBPM_DECL(free_buf)                     \
+    /* --- BPM SKB POOL --- */              \
+    GBPM_DECL(total_skb)                    \
+    GBPM_DECL(avail_skb)                    \
+    GBPM_DECL(attach_skb)                   \
+    GBPM_DECL(alloc_skb)                    \
+    GBPM_DECL(alloc_buf_skb_attach)         \
+    GBPM_DECL(alloc_mult_skb)               \
+    GBPM_DECL(free_skb)                     \
+    GBPM_DECL(free_skblist)                 \
+    GBPM_DECL(invalidate_dirtyp)                 \
+    GBPM_DECL(recycle_skb)                  \
+    /* --- BPM pNBuff --- */                \
+    GBPM_DECL(recycle_pNBuff)               \
+    /* --- BPM Get Accessors --- */         \
+    GBPM_DECL(get_dyn_buf_lvl)              \
+    GBPM_DECL(get_total_bufs)               \
+    GBPM_DECL(get_avail_bufs)               \
+    GBPM_DECL(get_max_dyn_bufs)             \
+    /* --- BPM Runtime --- */               \
+    GBPM_DECL(resv_rx_buf)                  \
+    GBPM_DECL(unresv_rx_buf)
+
+
+    /* --- BPM Users --- */
+#define GBPM_ENET()                         \
+    GBPM_DECL(enet_status)
+#if defined(GBPM_XTM_SUPPORT)
+#define GBPM_XTM()                          \
+    GBPM_DECL(xtm_status)                   \
+    GBPM_DECL(xtm_thresh)
+#else
+#define GBPM_XTM()
+#endif /* GBPM_XTM_SUPPORT */
+
+#define GBPM_USER()                         \
+        GBPM_ENET()                         \
+        GBPM_XTM()
+
+/*
+ * typedefs for callbacks managed by GBPM.
+ */
+
+/* --- BPM BUF POOL --- */
+typedef int      (* gbpm_alloc_mult_buf_hook_t)(uint32_t, void **);
+typedef void     (* gbpm_free_mult_buf_hook_t)( uint32_t, void **);
+typedef int      (* gbpm_alloc_mult_buf_ex_hook_t)( uint32_t num, void **buf_p, uint32_t prio );
+typedef void *   (* gbpm_alloc_buf_hook_t)(void);
+typedef void     (* gbpm_free_buf_hook_t)(void *);
+typedef void     (* gbpm_recycle_pNBuff_hook_t)(void *, unsigned long, uint32_t);
+
+/* --- BPM SKB POOL --- */
+typedef uint32_t (* gbpm_total_skb_hook_t)(void);
+typedef uint32_t (* gbpm_avail_skb_hook_t)(void);
+typedef void     (* gbpm_attach_skb_hook_t)(void *, void *, uint32_t);
+typedef void *   (* gbpm_alloc_skb_hook_t)(void);
+typedef void *   (* gbpm_alloc_buf_skb_attach_hook_t)(uint32_t);
+typedef void *   (* gbpm_alloc_mult_skb_hook_t)(uint32_t);
+typedef void     (* gbpm_free_skb_hook_t)(void *);
+typedef void     (* gbpm_free_skblist_hook_t)(void *head, void *tail, uint32_t len, void **bufp_arr);
+typedef void *   (* gbpm_invalidate_dirtyp_hook_t)(void *);
+typedef void     (* gbpm_recycle_skb_hook_t)(void *, unsigned long, uint32_t);
+
+/* --- BPM Get Accessors --- */
+typedef int      (* gbpm_get_dyn_buf_lvl_hook_t)(void);
+typedef uint32_t (* gbpm_get_total_bufs_hook_t)(void);
+typedef uint32_t (* gbpm_get_avail_bufs_hook_t)(void);
+typedef uint32_t (* gbpm_get_max_dyn_bufs_hook_t)(void);
+
+/* --- BPM Set Accessors --- */
+typedef void     (* gbpm_upd_buf_lvl_hook_t)(int);
+
+/* --- BPM Runtime --- */
+typedef int      (* gbpm_resv_rx_buf_hook_t)(gbpm_port_t, uint32_t, uint32_t, uint32_t);
+typedef int      (* gbpm_unresv_rx_buf_hook_t)(gbpm_port_t, uint32_t);
+
+
+/* --- BPM User --- */
+typedef void     (* gbpm_evt_hook_t)(void);
+typedef void     (* gbpm_thresh_hook_t)(void);
+typedef void     (* gbpm_status_hook_t)(void);
+
+
+/* --- BPM User instantiations --- */
+typedef gbpm_status_hook_t      gbpm_enet_status_hook_t;
+typedef gbpm_status_hook_t      gbpm_fap_status_hook_t;
+typedef gbpm_thresh_hook_t      gbpm_fap_thresh_hook_t;
+typedef gbpm_thresh_hook_t      gbpm_enet_thresh_hook_t;
+typedef gbpm_thresh_hook_t      gbpm_fap_enet_thresh_hook_t;
+typedef gbpm_upd_buf_lvl_hook_t gbpm_fap_upd_buf_lvl_hook_t;
+/* gbpm_fap_evt_hook_g is instantiated in dev.c and not part of gbpm_g */
+typedef gbpm_evt_hook_t         gbpm_fap_evt_hook_t;
+
+typedef gbpm_status_hook_t      gbpm_xtm_status_hook_t;
+typedef gbpm_thresh_hook_t      gbpm_xtm_thresh_hook_t;
+
+
+/* Typedef of the Global BPM hook manager */
+#undef  GBPM_DECL
+#define GBPM_DECL(HOOKNAME)     gbpm_ ## HOOKNAME ## _hook_t HOOKNAME;
+
+typedef struct gbpm
+{
+    GBPM_BIND() /* List of BPM "BIND" hooks */
+    GBPM_USER() /* List of DRV "USER" hooks */
+    uint32_t debug;
+} gbpm_t;
+
+extern gbpm_t gbpm_g; /* exported global */
+
+
+/* BPM registering callbacks into GBPM */
+#undef  GBPM_DECL
+#define GBPM_DECL(HOOKNAME)     gbpm_ ## HOOKNAME ## _hook_t HOOKNAME,
+
+void gbpm_bind( GBPM_BIND() uint32_t debug );
+void gbpm_unbind(void);
+
+void gbpm_queue_work(void);
+
+/*
+ * Wrappers for GBPM callbacks
+ */
+
+/* --- BPM BUF POOL --- */
+static inline int gbpm_alloc_mult_buf(uint32_t num, void **buf_p)
+        { return gbpm_g.alloc_mult_buf(num, buf_p); }
+static inline int gbpm_alloc_mult_buf_ex( uint32_t num, void **buf_p, uint32_t prio )
+        { return gbpm_g.alloc_mult_buf_ex(num, buf_p, prio); }
+static inline void gbpm_free_mult_buf(uint32_t num, void **buf_p)
+        { gbpm_g.free_mult_buf(num, buf_p); }
+static inline void * gbpm_alloc_buf(void)
+        { return gbpm_g.alloc_buf(); }
+static inline void gbpm_free_buf(void * buf_p)
+        { return gbpm_g.free_buf(buf_p); }
+
+/* --- BPM SKB --- */
+static inline uint32_t gbpm_total_skb(void)
+        { return gbpm_g.total_skb(); }
+static inline uint32_t gbpm_avail_skb(void)
+        { return gbpm_g.avail_skb(); }
+static inline void gbpm_attach_skb(void *skbp, void *data, uint32_t datalen)
+        { gbpm_g.attach_skb(skbp, data, datalen); }
+static inline void * gbpm_alloc_skb(void)
+        { return gbpm_g.alloc_skb(); }
+static inline void * gbpm_alloc_buf_skb_attach(uint32_t datalen)
+        { return gbpm_g.alloc_buf_skb_attach(datalen); }
+static inline void * gbpm_alloc_mult_skb(uint32_t num)
+        { return gbpm_g.alloc_mult_skb(num); }
+static inline void gbpm_free_skb(void *skbp)
+        { gbpm_g.free_skb(skbp); }
+static inline void gbpm_free_skblist(void *head, void *tail, uint32_t len, void **bufp_arr)
+        { gbpm_g.free_skblist(head, tail, len, bufp_arr); }
+static inline void * gbpm_invalidate_dirtyp(void *skb)
+        { return gbpm_g.invalidate_dirtyp(skb); }
+static inline void gbpm_recycle_skb(void *skbp, unsigned long context,
+        uint32_t recycle_action)
+         { gbpm_g.recycle_skb(skbp, context, recycle_action); }
+
+/* --- BPM pNBuff --- */
+static inline void gbpm_recycle_pNBuff(void * pNBuff, unsigned long context,
+        uint32_t recycle_action)
+         { gbpm_g.recycle_pNBuff(pNBuff, context, recycle_action); }
+
+
+/* --- BPM Get Accessors --- */
+static inline int gbpm_get_dyn_buf_lvl(void)
+        { return gbpm_g.get_dyn_buf_lvl(); }
+static inline uint32_t gbpm_get_total_bufs(void)
+        { return gbpm_g.get_total_bufs(); }
+static inline uint32_t gbpm_get_avail_bufs(void)
+        { return gbpm_g.get_avail_bufs(); }
+static inline uint32_t gbpm_get_max_dyn_bufs(void)
+        { return gbpm_g.get_max_dyn_bufs(); }
+
+/* --- BPM Runtime --- */
+static inline int gbpm_resv_rx_buf(gbpm_port_t port, uint32_t chnl,
+             uint32_t num_rx_buf, uint32_t bulk_alloc_cnt)
+        { return gbpm_g.resv_rx_buf(port, chnl, num_rx_buf, bulk_alloc_cnt); }
+static inline int gbpm_unresv_rx_buf(gbpm_port_t port, uint32_t chnl)
+        { return gbpm_g.unresv_rx_buf( port, chnl ); }
+
+#if defined(CONFIG_BCM_BPM_BUF_TRACKING)
+void gbpm_mark_buf( void * buf_p, void * addr, int reftype, int driver, int value, int info);
+void gbpm_add_ref( void * buf_p, int i );
+
+#define GBPM_TRACK_BUF(buf, drv, value, info)        do { gbpm_mark_buf( (void *)(buf), (void *)0, GBPM_REF_BUFF, (drv), (value), (info) ); } while(0)
+#define GBPM_TRACK_SKB(skb, drv, value, info)        do { gbpm_mark_buf( (void *)((skb)->data), (void *)(skb), GBPM_REF_SKB, (drv), (value), (info) ); } while(0)
+#define GBPM_TRACK_FKB(fkb, drv, value, info)        do { gbpm_mark_buf( (void *)((fkb)->data), (void *)(fkb), GBPM_REF_FKB, (drv), (value), (info) ); } while(0)
+#define GBPM_INC_REF(buf)                            do { gbpm_add_ref( (buf), 1); } while (0)
+#define GBPM_DEC_REF(buf)                            do { gbpm_add_ref( (buf), -1); } while (0)
+#else
+#define GBPM_TRACK_BUF(buf, drv, value, info)        do{}while(0)
+#define GBPM_TRACK_SKB(skb, drv, value, info)        do{}while(0)
+#define GBPM_TRACK_FKB(fkb, drv, value, info)        do{}while(0)
+#define GBPM_INC_REF(buf)                            do{}while(0)
+#define GBPM_DEC_REF(buf)                            do{}while(0)
+#endif
+
+#endif  /* defined(__GBPM_H_INCLUDED__) */
diff --git a/include/linux/iqos.h b/include/linux/iqos.h
new file mode 100644
index 0000000000000000000000000000000000000000..58440890fbffd163d197a7f4f9cda80b1289d6b2
--- /dev/null
+++ b/include/linux/iqos.h
@@ -0,0 +1,268 @@
+#ifndef __IQOS_H_INCLUDED__
+#define __IQOS_H_INCLUDED__
+
+/*
+<:copyright-BRCM:2009:DUAL/GPL:standard
+
+   Copyright (c) 2009 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+
+/*
+ *******************************************************************************
+ * File Name : ingqos.h
+ *
+ *******************************************************************************
+ */
+#define IQOS_VERSION	"v1.0"
+#define IQOS_VER_STR	IQOS_VERSION
+#define IQOS_MODNAME	"Broadcom IQoS "
+
+#include <linux/if_ether.h>
+
+typedef enum {
+	IQOS_PARAM_TYPE_KEYMASK,
+	IQOS_PARAM_TYPE_KEY,
+	IQOS_PARAM_TYPE_MAX
+} iqos_param_type_t;
+
+typedef enum {
+	IQOS_FIELD_INGRESS_DEVICE,
+	IQOS_FIELD_SRC_MAC,
+	IQOS_FIELD_DST_MAC,
+	IQOS_FIELD_ETHER_TYPE,
+	IQOS_FIELD_OUTER_VID,
+	IQOS_FIELD_OUTER_PBIT,
+	IQOS_FIELD_INNER_VID,
+	IQOS_FIELD_INNER_PBIT,
+	IQOS_FIELD_L2_PROTO,
+	IQOS_FIELD_L3_PROTO,
+	IQOS_FIELD_IP_PROTO,
+	IQOS_FIELD_SRC_IP,
+	IQOS_FIELD_DST_IP,
+	IQOS_FIELD_DSCP,
+	IQOS_FIELD_IPV6_FLOW_LABEL,
+	IQOS_FIELD_SRC_PORT,
+	IQOS_FIELD_DST_PORT,
+	IQOS_FIELD_OFFSET_0,
+	IQOS_FIELD_OFFSET_START = IQOS_FIELD_OFFSET_0,
+	IQOS_FIELD_OFFSET_0_TYPE,
+	IQOS_FIELD_OFFSET_0_START,
+	IQOS_FIELD_OFFSET_0_SIZE,
+	IQOS_FIELD_OFFSET_0_MASK,
+	IQOS_FIELD_OFFSET_1,
+	IQOS_FIELD_OFFSET_1_TYPE,
+	IQOS_FIELD_OFFSET_1_START,
+	IQOS_FIELD_OFFSET_1_SIZE,
+	IQOS_FIELD_OFFSET_1_MASK,
+	IQOS_FIELD_OFFSET_END = IQOS_FIELD_OFFSET_1_MASK,
+	IQOS_FIELD_MAX
+} iqos_field_t;
+
+typedef enum {
+	IQOS_ACTION_NOP,
+	IQOS_ACTION_PRIO,
+	IQOS_ACTION_DROP,
+	IQOS_ACTION_DST_Q,
+	IQOS_ACTION_TRAP,
+	IQOS_ACTION_MAX
+} iqos_action_t;
+
+typedef enum {
+	IQOS_OFFSET_TYPE_L2,
+	IQOS_OFFSET_TYPE_L3,
+	IQOS_OFFSET_TYPE_L4,
+	IQOS_OFFSET_TYPE_MAX
+} iqos_offset_type_t;
+
+typedef struct {
+	uint32_t type;
+	uint32_t start;
+	uint32_t size;
+	uint32_t mask;
+} iqos_offset_data_t;
+
+#define IQOS_PACKET_CACHE_MAX_SIZE	128
+typedef struct {
+	uint32_t ingress_device;
+	uint8_t src_mac[ETH_HLEN];
+	uint8_t dst_mac[ETH_HLEN];
+	uint16_t eth_type;
+	uint16_t outer_vid;
+	uint8_t outer_pbit;
+	uint16_t inner_vid;
+	uint8_t inner_pbit;
+	uint16_t l2_proto;
+	uint16_t l3_proto;
+	uint8_t ip_proto;
+	uint8_t is_ipv6;
+	uint32_t src_ip[4];
+	uint32_t dst_ip[4];
+	uint8_t dscp;
+	uint32_t flow_label;
+	uint16_t l4_src_port;
+	uint16_t l4_dst_port;
+	uint16_t l2_offset;
+	uint16_t l3_offset;
+	uint16_t l4_offset;
+	/* used for storing part of packet buffer for offset check */
+	uint8_t packet_cache[IQOS_PACKET_CACHE_MAX_SIZE];
+} iqos_data_t;
+
+typedef struct {
+	uint32_t param_type;
+	uint8_t prio;
+	uint8_t type;
+	uint32_t field_mask;
+	uint32_t action;
+	uint32_t action_value;
+	iqos_data_t data;
+	iqos_offset_data_t offset0;
+	iqos_offset_data_t offset1;
+} iqos_param_t;
+
+typedef enum {
+	IQOS_ENT_DYN,
+	IQOS_ENT_STAT,
+	IQOS_ENT_MAX
+} iqos_ent_t;
+
+typedef enum {
+	IQOS_PRIO_LOW,
+	IQOS_PRIO_HIGH,
+	IQOS_PRIO_MAX
+} iqos_prio_t;
+
+typedef enum {
+	IQOS_CONG_STATUS_LO,
+	IQOS_CONG_STATUS_HI,
+	IQOS_CONG_STATUS_MAX
+} iqos_cong_status_t;
+
+typedef enum {
+	IQOS_STATUS_DISABLE,
+	IQOS_STATUS_ENABLE,
+	IQOS_STATUS_MAX
+} iqos_status_t;
+
+typedef struct {
+	uint8_t ipProto;
+	uint16_t destPort;
+	iqos_ent_t ent;
+	iqos_prio_t prio;
+} iqos_config_t;
+
+typedef int (*iqos_common_hook_t)(iqos_param_t *param);
+typedef void (*iqos_void_hook_t)(void);
+typedef int (*iqos_int_hook_t)(uint32_t val);
+
+/* the original APIs that are backward supported by the new driver/module */
+int iqos_add_L4port(uint8_t ipProto, uint16_t destPort, iqos_ent_t ent,
+		    iqos_prio_t prio);
+int iqos_rem_L4port(uint8_t ipProto, uint16_t destPort, iqos_ent_t ent);
+int iqos_prio_L4port(uint8_t ipProto, uint16_t destPort);
+
+/* the new APIs */
+
+/* APIs for setting up keymask:
+ * WARNING!! one will have to perform iqos_flush() to delete all the dynamic
+ * entry before making any change of the keymasks.
+ * Deleting a keymask that has key refer to it will fail and return error */
+int iqos_keymask_param_start(iqos_param_t *param);
+int iqos_keymask_param_field_set(iqos_param_t *param, uint32_t field, uint32_t *val_ptr);
+int iqos_keymask_commit_and_add(iqos_param_t *param, uint8_t prio);
+int iqos_keymask_commit_and_delete(iqos_param_t *param);
+
+/* APIs for setting up key,
+ * example can be found in iqos_[add/rem/prio]_L4port */
+int iqos_key_param_start(iqos_param_t *param);
+int iqos_key_param_field_set(iqos_param_t *param, uint32_t field,
+			     uint32_t *val_ptr, uint32_t val_size);
+int iqos_key_param_action_set(iqos_param_t *param, uint32_t action,
+			      uint32_t value);
+int iqos_key_commit_and_add(iqos_param_t *param, uint8_t type);
+int iqos_key_commit_and_delete(iqos_param_t *param, uint8_t type);
+int iqos_key_commit_and_get(iqos_param_t *param);
+
+/* API to flush all the dynamic entries, and
+ * delete keymask if no key refers to it */
+void iqos_flush(void);
+
+/* API to set the status for IQOS to enabled(1) or disabled(0) */
+int iqos_set_status(uint32_t status);
+
+void iqos_bind(iqos_common_hook_t iqos_add_keymask,
+	       iqos_common_hook_t iqos_rem_keymask,
+	       iqos_common_hook_t iqos_add_key,
+	       iqos_common_hook_t iqos_rem_key,
+	       iqos_common_hook_t iqos_get_key,
+	       iqos_int_hook_t iqos_set_status,
+	       iqos_void_hook_t iqos_flush);
+
+
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+#define IQOS_LOCK_IRQSAVE()         spin_lock_irqsave( &iqos_cong_lock_g, flags )
+#define IQOS_UNLOCK_IRQRESTORE()    spin_unlock_irqrestore( &iqos_cong_lock_g, flags )
+#define IQOS_LOCK_BH()              spin_lock_bh( &iqos_lock_g )
+#define IQOS_UNLOCK_BH()            spin_unlock_bh( &iqos_lock_g )
+#else
+#define IQOS_LOCK_IRQSAVE()		local_irq_save(flags)
+#define IQOS_UNLOCK_IRQRESTORE()	local_irq_restore(flags)
+#define IQOS_LOCK_BH()			NULL_STMT
+#define IQOS_UNLOCK_BH()		NULL_STMT
+#endif
+
+#if IS_ENABLED(CONFIG_BCM_INGQOS)
+#define IQOS_RXCHNL_MAX		4
+#define IQOS_RXCHNL_DISABLED	0
+#define IQOS_RXCHNL_ENABLED	1
+#define IQOS_MAX_RX_RING_SIZE	4096
+
+typedef enum {
+	IQOS_IF_ENET,
+	IQOS_IF_ENET_RXCHNL0 = IQOS_IF_ENET,
+	IQOS_IF_ENET_RXCHNL1,
+	IQOS_IF_ENET_RXCHNL2,
+	IQOS_IF_ENET_RXCHNL3,
+	IQOS_IF_XTM,
+	IQOS_IF_XTM_RXCHNL0 = IQOS_IF_XTM,
+	IQOS_IF_XTM_RXCHNL1,
+	IQOS_IF_XTM_RXCHNL2,
+	IQOS_IF_XTM_RXCHNL3,
+	IQOS_IF_FWD,
+	IQOS_IF_FWD_RXCHNL0 = IQOS_IF_FWD,
+	IQOS_IF_FWD_RXCHNL1,
+	IQOS_IF_WL,
+	IQOS_IF_USB,
+	IQOS_IF_MAX,
+} iqos_if_t;
+
+iqos_cong_status_t iqos_get_sys_cong_status(void);
+iqos_cong_status_t iqos_get_cong_status(iqos_if_t iface, uint32_t chnl);
+uint32_t iqos_set_cong_status(iqos_if_t iface, uint32_t chnl,
+			      iqos_cong_status_t status);
+#endif
+#endif /* defined(__IQOS_H_INCLUDED__) */
diff --git a/include/linux/nbuff.h b/include/linux/nbuff.h
new file mode 100755
index 0000000000000000000000000000000000000000..e0fb6ec30ed94b0125616a988b04c3eb27eca24e
--- /dev/null
+++ b/include/linux/nbuff.h
@@ -0,0 +1,1793 @@
+#ifndef __NBUFF_H_INCLUDED__
+#define __NBUFF_H_INCLUDED__
+
+
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+/*
+ *******************************************************************************
+ *
+ * File Name  : nbuff.h
+ * Description: Definition of a network buffer to support various forms of
+ *      network buffer, to include Linux socket buff (SKB), lightweight
+ *      fast kernel buff (FKB), BRCM Free Pool buffer (FPB), and traffic
+ *      generator support buffer (TGB)
+ *
+ *      nbuff.h may also be used to provide an interface to common APIs 
+ *      available on other OS (in particular BSD style mbuf).
+ *
+ * Common APIs provided: pushing, pulling, reading, writing, cloning, freeing
+ *
+ * Implementation Note:
+ *
+ * One may view NBuff as a base class from which other buff types are derived.
+ * Examples of derived network buffer types are sk_buff, fkbuff, fpbuff, tgbuff
+ *
+ * A pointer to a buffer is converted to a pointer to a special (derived) 
+ * network buffer type by encoding the type into the least significant 2 bits
+ * of a word aligned buffer pointer. pBuf points to the real network 
+ * buffer and pNBuff refers to pBuf ANDed with the Network Buffer Type.
+ * C++ this pointer to a virtual class (vtable based virtual function thunks).
+ *
+ * Thunk functions to redirect the calls to the appropriate buffer type, e.g.
+ * SKB or FKB uses the Network Buffer Pointer type information.
+ *
+ * This file also implements the Fast Kernel Buffer API. The fast kernel buffer
+ * carries a minimal context of the received buffer and associated buffer
+ * recycling information.
+ *
+ ******************************************************************************* */
+
+#include <linux/version.h>
+#include <generated/autoconf.h>
+#include <linux/types.h>            /* include ISO C99 inttypes.h             */
+#include <linux/skbuff.h>           /* include corresponding BSD style mbuf   */
+#include <bcm_pkt_lengths.h>
+#include <linux/netdevice.h>
+
+#ifdef CONFIG_BLOG
+#include <linux/blog.h>
+#endif
+#include <linux/blog_net.h> /*TODO rename this file as bcm_net.h as it's not specific to blog */
+
+#define NBUFF_VERSION              "v1.0"
+
+#if defined(CONFIG_BCM96855)
+// temporary untill network is enabled
+#define CONFIG_BCM_MAX_MCAST_GROUPS 1
+#define CONFIG_BCM_MAX_MCAST_CLIENTS 1
+#endif
+
+/* Engineering Constants for Fast Kernel Buffer Global Pool (used for clones) */
+#define SUPPORT_FKB_EXTEND
+#define FKBC_POOL_SIZE_ENGG         (2080)  /*1280 more to be allocated for wireless*/
+#define FKBC_EXTEND_SIZE_ENGG       32      /* Number of FkBuf_t per extension*/
+#define FKBC_EXTEND_MAX_ENGG        16      /* Maximum extensions allowed     */
+
+#define FKBM_POOL_SIZE_ENGG         128
+#define FKBM_EXTEND_SIZE_ENGG       32
+#define FKBM_EXTEND_MAX_ENGG        \
+    (((CONFIG_BCM_MAX_MCAST_GROUPS * (CONFIG_BCM_MAX_MCAST_CLIENTS+1))/FKBM_EXTEND_SIZE_ENGG) + 1)
+
+/*
+ * Network device drivers ported to NBUFF must ensure that the headroom is at
+ * least 186 bytes in size. Remove this dependancy (TBD).
+ */
+// #define CC_FKB_HEADROOM_AUDIT
+
+/* Conditional compile of FKB functional APIs as inlined or non-inlined */
+#define CC_CONFIG_FKB_FN_INLINE
+#ifdef CC_CONFIG_FKB_FN_INLINE
+#define FKB_FN(fn_name, fn_signature, body)                                    \
+static inline fn_signature { body; }    /* APIs inlined in header file */
+#else
+#ifdef FKB_IMPLEMENTATION_FILE
+#define FKB_FN(fn_name, fn_signature, body)                                    \
+fn_signature { body; }                                                         \
+EXPORT_SYMBOL(fn_name);                 /* APIs declared in implementation */
+#else
+#define FKB_FN(fn_name, fn_signature, body)                                    \
+extern fn_signature;
+#endif  /* !defined(FKB_IMPLEMENTATION_FILE) */
+#endif  /* !defined(FKB_FN) */
+
+/* LAB ONLY: Design development */
+//#define CC_CONFIG_FKB_STATS
+//#define CC_CONFIG_FKB_COLOR
+//#define CC_CONFIG_FKB_DEBUG
+//#define CC_CONFIG_FKB_AUDIT
+//#define CC_CONFIG_FKB_STACK
+
+// #include <linux/smp.h>       /* smp_processor_id() CC_CONFIG_FKB_AUDIT */
+
+#if defined(CC_CONFIG_FKB_STATS)
+#define FKB_STATS(stats_code)   do { stats_code } while(0)
+#else
+#define FKB_STATS(stats_code)   NULL_STMT
+#endif
+
+#if defined(CC_CONFIG_FKB_STACK)
+extern void dump_stack(void);
+#define DUMP_STACK()            dump_stack()
+#else
+#define DUMP_STACK()            NULL_STMT
+#endif
+
+#if defined(CC_CONFIG_FKB_AUDIT)
+#define FKB_AUDIT(audit_code)   do { audit_code } while(0)
+#else
+#define FKB_AUDIT(audit_code)   NULL_STMT
+#endif
+
+extern int nbuff_dbg;
+#if defined(CC_CONFIG_FKB_DEBUG)
+#define fkb_dbg(lvl, fmt, arg...) \
+    if (nbuff_dbg >= lvl) printk( "FKB %s :" fmt "[<%pS>]\n", \
+        __FUNCTION__, ##arg, __builtin_return_address(0) )
+#define FKB_DBG(debug_code)     do { debug_code } while(0)
+#else
+#define fkb_dbg(lvl, fmt, arg...)      do {} while(0)
+#define FKB_DBG(debug_code)     NULL_STMT
+#endif
+
+#define CC_NBUFF_FLUSH_OPTIMIZATION
+
+/* CACHE OPERATIONS */
+#define FKB_CACHE_FLUSH         0
+#define FKB_CACHE_INV           1
+
+/* OS Specific Section Begin */
+#if defined(__KERNEL__)     /* Linux Cache Specific */
+/*
+ *------------------------------------------------------------------------------
+ * common cache operations:
+ *
+ * - addr is rounded down to the cache line
+ * - end is rounded up to cache line.
+ *
+ * - if ((addr == end) and (addr was cache aligned before rounding))
+ *       no operation is performed.
+ *   else
+ *       flush data cache line UPTO but NOT INCLUDING rounded up end.
+ *
+ * Note:
+ * if before rounding, (addr == end)  AND addr was not cache aligned,
+ *      we would flush at least one line.
+ *
+ * Uses: L1_CACHE_BYTES
+ *------------------------------------------------------------------------------
+ */
+#include <asm/cache.h>
+
+extern void cache_flush_data_len(void *addr, int len);
+
+/*
+ * Macros to round down and up, an address to a cachealigned address
+ */
+#define ADDR_ALIGN_DN(addr, align)  ( (addr) & ~((align) - 1) )
+#define ADDR_ALIGN_UP(addr, align)  ( ((addr) + (align) - 1) & ~((align) - 1) )
+
+#if defined(CONFIG_ARM)
+
+#include <asm/cacheflush.h>
+
+#ifdef CONFIG_CPU_CACHE_V7
+#define __cpuc_flush_line(_addr)	\
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c14, 1" : : "r" (_addr))
+#define __cpuc_clean_line(_addr)	\
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 1" : : "r" (_addr))
+#define __cpuc_inv_line(_addr)		\
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r" (_addr))
+#else
+#define __cpuc_flush_line(_addr)	do {} while(0)
+#define __cpuc_clean_line(_addr)	do {} while(0)
+#define __cpuc_inv_line(_addr)		do {} while(0)
+#endif
+
+#if defined(CONFIG_ARM_L1_CACHE_SHIFT)
+#define L1_CACHE_LINE_SIZE	(0x1 << CONFIG_ARM_L1_CACHE_SHIFT)
+#else
+#warning There is no L1 cache line size defined!
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+
+#if defined(CONFIG_CACHE_L2X0)
+#define L2_CACHE_LINE_SIZE	32
+#endif
+
+#if defined(L2_CACHE_LINE_SIZE) && (L1_CACHE_LINE_SIZE != L2_CACHE_LINE_SIZE)
+#warning  L1 Cache line size is different from L2 cache line size!
+#endif
+
+#define CONFIG_OPTIMIZED_CACHE_FLUSH	1
+#endif
+
+static inline void cache_flush_len(void *addr, int len);
+static inline void _cache_flush_len(void *addr, int len);
+
+#ifdef CONFIG_BCM_GLB_COHERENCY
+#define cache_invalidate_len_outer_first(virt_addr, len)
+#define cache_invalidate_region_outer_first(virt_addr, end)
+#define cache_invalidate_len(virt_addr, len)
+#define cache_invalidate_region(virt_addr, end)
+#define cache_flush_region(addr, end)
+#else
+
+/* the following functions are optimized that it does NOT support
+ * HIGHMEM in 32-bit system, please make sure buffer allocated
+ * are in memory zone 'Normal' or before */
+static inline void cache_invalidate_len_outer_first(void *virt_addr, int len)
+{
+	uintptr_t start_vaddr = (uintptr_t)virt_addr;
+	uintptr_t end_vaddr = start_vaddr + len;
+#if defined(CONFIG_OUTER_CACHE)
+	uintptr_t start_paddr = virt_to_phys(virt_addr);
+	uintptr_t end_paddr = start_paddr + len;
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+	outer_spin_lock_irqsave();
+#endif
+	/* 1st, flush & invalidate if start addr and / or end addr are not
+	 * cache line aligned */
+	if (start_vaddr & (L1_CACHE_LINE_SIZE - 1)) {
+		start_vaddr &= ~(L1_CACHE_LINE_SIZE - 1);
+		__cpuc_flush_line(start_vaddr);
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+#endif
+		start_vaddr += L1_CACHE_LINE_SIZE;
+	}
+
+#if defined(CONFIG_OUTER_CACHE)
+	if (start_paddr & (L2_CACHE_LINE_SIZE - 1)) {
+		start_paddr &= ~(L2_CACHE_LINE_SIZE - 1);
+		outer_flush_line_no_lock(start_paddr);
+		outer_sync_no_lock();
+		start_paddr += L2_CACHE_LINE_SIZE;
+	}
+#endif
+
+	if (end_vaddr & (L1_CACHE_LINE_SIZE - 1)) {
+		end_vaddr &= ~(L1_CACHE_LINE_SIZE - 1);
+		__cpuc_flush_line(end_vaddr);
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+#endif
+	}
+
+#if defined(CONFIG_OUTER_CACHE)
+	if (end_paddr & (L2_CACHE_LINE_SIZE - 1)) {
+		end_paddr &= ~(L2_CACHE_LINE_SIZE - 1);
+		outer_flush_line_no_lock(end_paddr);
+		outer_sync_no_lock();
+	}
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+	/* now do the real invalidation jobs */
+	while (start_paddr < end_paddr) {
+		outer_inv_line_no_lock(start_paddr);
+		start_paddr += L2_CACHE_LINE_SIZE;
+	}
+	outer_sync_no_lock();
+#endif
+
+	/* now do the real invalidation jobs */
+	while (start_vaddr < end_vaddr) {
+		__cpuc_inv_line(start_vaddr);
+		start_vaddr += L1_CACHE_LINE_SIZE;
+	}
+
+	dsb();
+#if defined(CONFIG_OUTER_CACHE)
+	outer_spin_unlock_irqrestore();
+#endif
+
+	if ((len >= PAGE_SIZE) && (((uintptr_t)virt_addr & ~PAGE_MASK) == 0))
+		set_bit(PG_dcache_clean, &phys_to_page(virt_to_phys(virt_addr))->flags);
+}
+
+static inline void cache_invalidate_region_outer_first(void *virt_addr, void *end)
+{
+	cache_invalidate_len_outer_first(virt_addr,
+			(uintptr_t)end - (uintptr_t)virt_addr);
+}
+
+static inline void cache_invalidate_len(void *virt_addr, int len)
+{
+	uintptr_t start_vaddr = (uintptr_t)virt_addr;
+	uintptr_t end_vaddr = start_vaddr + len;
+#if defined(CONFIG_OUTER_CACHE)
+	uintptr_t start_paddr = virt_to_phys(virt_addr);
+	uintptr_t end_paddr = start_paddr + len;
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+	outer_spin_lock_irqsave();
+#endif
+	/* 1st, flush & invalidate if start addr and / or end addr are not
+	 * cache line aligned */
+	if (start_vaddr & (L1_CACHE_LINE_SIZE - 1)) {
+		start_vaddr &= ~(L1_CACHE_LINE_SIZE - 1);
+		__cpuc_flush_line(start_vaddr);
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+#endif
+		start_vaddr += L1_CACHE_LINE_SIZE;
+	}
+
+#if defined(CONFIG_OUTER_CACHE)
+	if (start_paddr & (L2_CACHE_LINE_SIZE - 1)) {
+		start_paddr &= ~(L2_CACHE_LINE_SIZE - 1);
+		outer_flush_line_no_lock(start_paddr);
+		start_paddr += L2_CACHE_LINE_SIZE;
+	}
+#endif
+
+	if (end_vaddr & (L1_CACHE_LINE_SIZE - 1)) {
+		end_vaddr &= ~(L1_CACHE_LINE_SIZE - 1);
+		__cpuc_flush_line(end_vaddr);
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+#endif
+	}
+
+#if defined(CONFIG_OUTER_CACHE)
+	if (end_paddr & (L2_CACHE_LINE_SIZE - 1)) {
+		end_paddr &= ~(L2_CACHE_LINE_SIZE - 1);
+		outer_flush_line_no_lock(end_paddr);
+	}
+#endif
+
+	/* now do the real invalidation jobs */
+	while (start_vaddr < end_vaddr) {
+		__cpuc_inv_line(start_vaddr);
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+		outer_inv_line_no_lock(start_paddr);
+		start_paddr += L2_CACHE_LINE_SIZE;
+#endif
+		start_vaddr += L1_CACHE_LINE_SIZE;
+	}
+#if defined(CONFIG_OUTER_CACHE)
+	outer_sync_no_lock();
+	outer_spin_unlock_irqrestore();
+#else
+	dsb();
+#endif
+
+	if ((len >= PAGE_SIZE) && (((uintptr_t)virt_addr & ~PAGE_MASK) == 0))
+		set_bit(PG_dcache_clean, &phys_to_page(virt_to_phys(virt_addr))->flags);
+}
+
+static inline void cache_invalidate_region(void *virt_addr, void *end)
+{
+	cache_invalidate_len(virt_addr,
+			(uintptr_t)end - (uintptr_t)virt_addr);
+}
+
+static inline void cache_flush_region(void *addr, void *end)
+{
+	cache_flush_len(addr, (uintptr_t)end - (uintptr_t)addr);
+}
+
+#endif /* CONFIG_BCM_GLB_COHERENCY */
+
+static inline void cache_flush_len(void *addr, int len)
+{
+#ifndef CONFIG_BCM_GLB_COHERENCY
+    _cache_flush_len(addr, len);
+#endif
+}
+static inline void fpm_cache_flush_len(void *addr, int len)
+{
+#if !defined(CONFIG_BCM_GLB_COHERENCY) || defined(CONFIG_BCM_FPM_COHERENCY_EXCLUDE)
+    _cache_flush_len(addr, len);
+#endif
+}
+
+static inline void _cache_flush_len(void *addr, int len)
+{
+	uintptr_t start_vaddr = (uintptr_t)addr & ~(L1_CACHE_LINE_SIZE - 1);
+	uintptr_t end_vaddr = (uintptr_t)addr + len;
+#if defined(CONFIG_OUTER_CACHE)
+	uintptr_t start_paddr = (uintptr_t)virt_to_phys((void *)start_vaddr);
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+	outer_spin_lock_irqsave();
+#endif
+#if defined(CONFIG_OPTIMIZED_CACHE_FLUSH)
+	/* this function has been optimized in a non-recommended way, if any
+	 * type of packet error occurs, please try undefine
+	 * CONFIG_OPTIMIZED_CACHE_FLUSH to use the recommended algorithm
+	 * provided by ARM cache document.
+	 * Usually, when we have multiple levels of cache, in a cache_flush
+	 * case, we do L1_clean -> L2_clean -> L2_invalidate -> L1_clean
+	 * -> L1_invalidate, we can optimize this sequence to L1_clean ->
+	 * L2_flush -> L1_flush.  This is our original approach.  However,
+	 * this will introduce 3 loops of cache operation.
+	 * This optimized method will do L1_flush -> L2_flush.  This will only
+	 * introduce 2 loops of cache operation, but it also puts us into
+	 * danger that L2 cache might update L1 cache on the cache line
+	 * that should have been invalidated. */
+
+	while (start_vaddr < end_vaddr) {
+		__cpuc_flush_line(start_vaddr);
+		start_vaddr += L1_CACHE_LINE_SIZE;
+#if defined(CONFIG_OUTER_CACHE)
+		dsb();
+		outer_flush_line_no_lock(start_paddr);
+		start_paddr += L2_CACHE_LINE_SIZE;
+#endif
+	}
+#if defined(CONFIG_OUTER_CACHE)
+	outer_sync_no_lock();
+#else
+	wmb();
+#endif
+#else	/* the non-optimized cache_flush */
+	while (start_vaddr < end_vaddr) {
+#if defined(CONFIG_OUTER_CACHE)
+		__cpuc_clean_line(start_vaddr);
+		dsb();
+		outer_flush_line_no_lock(start_paddr);
+		start_paddr += L2_CACHE_LINE_SIZE;
+		outer_sync_no_lock();
+#endif
+		__cpuc_flush_line(start_vaddr);
+		start_vaddr += L1_CACHE_LINE_SIZE;
+	}
+	wmb();
+#endif
+#if defined(CONFIG_OUTER_CACHE)
+	outer_spin_unlock_irqrestore();
+#endif
+}
+
+
+static inline uint32_t _is_kptr_(const void * vptr)
+{
+	return ( (uintptr_t)vptr > 0x0FFFFFFF );
+}
+
+#elif defined(CONFIG_ARM64)
+
+#define nbuff_flush_dcache_area(addr, len)		\
+	__asm__ __volatile__ (				\
+	"mov	x0, %0 \n"				\
+	"mov	x1, %1 \n"				\
+	"mrs	x3, ctr_el0 \n"				\
+	"ubfm	x3, x3, #16, #19 \n"			\
+	"mov	x2, #4 \n"				\
+	"lsl	x2, x2, x3  \n"				\
+	"add	x1, x0, x1 \n"				\
+	"sub	x3, x2, #1 \n"				\
+	"bic	x0, x0, x3 \n"				\
+	"1:	dc	civac, x0 \n"			\
+	"add	x0, x0, x2 \n"				\
+	"cmp	x0, x1 \n"				\
+	"b.lo	1b \n"					\
+	"dsb	sy \n"					\
+	: : "r" ((uintptr_t)addr), "r" ((uintptr_t)len) \
+	: "x0", "x1", "x2", "x3", "cc")
+
+#define nbuff_inval_dcache_range(start, end)		\
+	__asm__ __volatile__ (				\
+	"mov	x0, %0 \n"				\
+	"mov	x1, %1 \n"				\
+	"mrs	x3, ctr_el0 \n"				\
+	"ubfm	x3, x3, #16, #19 \n"			\
+	"mov	x2, #4 \n"				\
+	"lsl	x2, x2, x3 \n"				\
+	"sub	x3, x2, #1 \n"				\
+	"tst	x1, x3 \n"				\
+	"bic	x1, x1, x3 \n"				\
+	"b.eq	1f \n"					\
+	"dc	civac, x1 \n"				\
+	"1:	tst	x0, x3 \n"			\
+	"bic	x0, x0, x3 \n"				\
+	"b.eq	2f \n"					\
+	"dc	civac, x0 \n"				\
+	"b	3f \n"					\
+	"2:	dc	ivac, x0 \n"			\
+	"3:	add	x0, x0, x2 \n"			\
+	"cmp	x0, x1 \n"				\
+	"b.lo	2b \n"					\
+	"dsb	sy \n"					\
+	: : "r" ((uintptr_t)start), "r" ((uintptr_t)end)\
+	: "x0", "x1", "x2", "x3", "cc")
+
+static inline void cache_flush_region(void *addr, void *end)
+{
+#ifndef CONFIG_BCM_GLB_COHERENCY
+	nbuff_flush_dcache_area(addr, (uintptr_t)end - (uintptr_t)addr);
+#endif
+}
+
+static inline void cache_flush_len(void *addr, int len)
+{
+#ifndef CONFIG_BCM_GLB_COHERENCY
+	nbuff_flush_dcache_area(addr, len);
+#endif
+}
+
+static inline void fpm_cache_flush_len(void *addr, int len)
+{
+#if !defined(CONFIG_BCM_GLB_COHERENCY) || defined(CONFIG_BCM_FPM_COHERENCY_EXCLUDE)
+	nbuff_flush_dcache_area(addr, len);
+#endif
+}
+
+static inline void cache_invalidate_region(void *addr, void *end)
+{
+#ifndef CONFIG_BCM_GLB_COHERENCY
+	nbuff_inval_dcache_range(addr, end);
+#endif
+}
+
+static inline void cache_invalidate_len(void *addr, int len)
+{
+#ifndef CONFIG_BCM_GLB_COHERENCY
+	nbuff_inval_dcache_range(addr, (void*)((uintptr_t)addr+len));
+#endif
+}
+
+#define cache_invalidate_region_outer_first(a, b)	cache_invalidate_region(a, b)
+#define cache_invalidate_len_outer_first(a, b)		cache_invalidate_len(a, b)
+
+static inline uint32_t _is_kptr_(const void * vptr)
+{
+	return ( (uintptr_t)vptr > 0xFFFFFF8000000000 );
+}
+#endif
+
+#endif  /* defined(__KERNEL__) Linux MIPS Cache Specific */
+/* OS Specific Section End */
+
+
+/*
+ * For BSD style mbuf with FKB : 
+ * generate nbuff.h by replacing "SKBUFF" to "BCMMBUF", and,
+ * use custom arg1 and arg2 instead of mark and priority, respectively.
+ */
+ 
+#ifdef TRACE_COMPILE
+#pragma message "got here 4"
+#endif
+
+struct sk_buff;
+#if defined(CONFIG_BLOG)
+struct blog_t;
+#endif
+struct net_device;
+typedef int (*HardStartXmitFuncP) (struct sk_buff *skb,
+                                   struct net_device *dev);
+
+struct fkbuff;
+typedef struct fkbuff FkBuff_t;
+
+#define FKB_NULL                    ((FkBuff_t *)NULL)
+
+#include <linux/nbuff_types.h>
+
+/*
+ *------------------------------------------------------------------------------
+ *
+ * Pointer conversion between pBuf and pNBuff encoded buffer pointers
+ * uint8_t * pBuf;
+ * pNBuff_t  pNBuff;
+ * ...
+ * // overlays FKBUFF_PTR into pointer to build a virtual pNBuff_t
+ * pNBuff = PBUF_2_PNBUFF(pBuf,FKBUFF_PTR);
+ * ...
+ * // extracts a real uint8_t * from a virtual pNBuff_t
+ * pBuf = PNBUFF_2_PBUF(pNBuff);
+ *
+ *------------------------------------------------------------------------------
+ */
+#define PBUF_2_PNBUFF(pBuf,realType) \
+            ( (pNBuff_t) ((uintptr_t)(pBuf)   | (uintptr_t)(realType)) )
+#define PNBUFF_2_PBUF(pNBuff)       \
+            ( (uint8_t*) ((uintptr_t)(pNBuff) & (uintptr_t)NBUFF_PTR_MASK) )
+
+#if (MUST_BE_ZERO != 0)
+#error  "Design assumption SKBUFF_PTR == 0"
+#endif
+#define PNBUFF_2_SKBUFF(pNBuff)     ((struct sk_buff *)(pNBuff))
+
+#define SKBUFF_2_PNBUFF(skb)        ((pNBuff_t)(skb)) /* see MUST_BE_ZERO */
+#define FKBUFF_2_PNBUFF(fkb)        PBUF_2_PNBUFF(fkb,FKBUFF_PTR)
+
+/*
+ *------------------------------------------------------------------------------
+ *
+ * Cast from/to virtual "pNBuff_t" to/from real typed pointers
+ *
+ *  pNBuff_t pNBuff2Skb, pNBuff2Fkb;    // "void *" with NBuffPtrType_t
+ *  struct sk_buff * skb_p;
+ *  struct fkbuff  * fkb_p;
+ *  ...
+ *  pNBuff2Skb = CAST_REAL_TO_VIRT_PNBUFF(skb_p,SKBUFF_PTR);
+ *  pNBuff2Fkb = CAST_REAL_TO_VIRT_PNBUFF(fkb_p,FKBUFF_PTR);
+ *  ...
+ *  skb_p = CAST_VIRT_TO_REAL_PNBUFF(pNBuff2Skb, struct sk_buff *);
+ *  fkb_p = CAST_VIRT_TO_REAL_PNBUFF(pNBuff2Fkb, struct fkbuff  *);
+ * or,
+ *  fkb_p = PNBUFF_2_FKBUFF(pNBuff2Fkb);  
+ *------------------------------------------------------------------------------
+ */
+
+#define CAST_REAL_TO_VIRT_PNBUFF(pRealNBuff,realType) \
+            ( (pNBuff_t) (PBUF_2_PNBUFF((pRealNBuff),(realType))) )
+
+#define CAST_VIRT_TO_REAL_PNBUFF(pVirtNBuff,realType) \
+            ( (realType) PNBUFF_2_PBUF(pVirtNBuff) )
+
+#define PNBUFF_2_FKBUFF(pNBuff) CAST_VIRT_TO_REAL_PNBUFF((pNBuff), struct fkbuff*)
+
+
+
+/*
+ *------------------------------------------------------------------------------
+ *  FKB: Fast Kernel Buffers placed directly into Rx DMA Buffer
+ *  May be used ONLY for common APIs such as those available in BSD-Style mbuf
+ *------------------------------------------------------------------------------
+ */
+
+struct fkbuff
+{
+    /* List pointer must be the first field */
+    union {
+		void	  * word0;
+        FkBuff_t  * list;           /* SLL of free FKBs for cloning           */
+        FkBuff_t  * master_p;       /* Clone FKB to point to master FKB       */
+        atomic_long_t  users;            /* (private) # of references to FKB       */
+    };
+    union {                         /* Use _is_kptr_ to determine if ptr      */
+        union {
+            void          *ptr;
+            struct blog_t *blog_p;  /* Pointer to a blog                      */
+            uint8_t       *dirty_p; /* Pointer to packet payload dirty incache*/
+            uint32_t       flags;   /* Access all flags                       */
+        };
+        /*
+         * First nibble denotes a pointer or flag usage.
+         * Lowest two significant bits denote the type of pinter
+         * Remaining 22 bits may be used as flags
+         */
+        struct {
+            uint32_t   ptr_type : 8;/* Identifies whether pointer             */
+            uint32_t   unused   :21;/* Future use for flags                   */
+            uint32_t   in_skb   : 1;/* flag: FKB passed inside a SKB          */
+            uint32_t   other_ptr: 1;/* future use, to override another pointer*/
+            uint32_t   dptr_tag : 1;/* Pointer type is a dirty pointer        */
+        };
+    };
+    uint8_t       * data;           /* Pointer to packet data                 */
+
+    union {
+        /* here the bits 31-24 are valid only for native fkbs's
+         * these bits bits will be cleared when using fkbInSkb 
+         * Note that it is critical to have the Little Endian/Big endian 
+         * declaration since FKB will use length as bit field and SKB will use  
+         * length as a word  Need to maintain the same bit positions across MIPS 
+         * and ARM.
+         */
+        struct{
+            BE_DECL(
+                uint32_t  rx_csum_verified:1;
+                uint32_t  spdtst:1;
+                uint32_t  reserved:6;
+                uint32_t  len:24;              /* Packet length               */
+            )
+            LE_DECL(
+                uint32_t  len:24;
+                uint32_t  reserved:6;
+                uint32_t  spdtst:1;
+                uint32_t  rx_csum_verified:1;
+            )
+        };
+        uint32_t len_word;
+    };
+
+    union {
+        /* only the lower 32 bit in mark is used in 64 bit system,
+         * but we delcare it as unsigned long for the ease for fcache
+         * to handle it in different architecture, since it is part
+         * of union with a dst_entry pointer */
+        unsigned long mark;             /* Custom arg1, e.g. tag or mark field    */
+        void      *queue;          /* Single link list queue of FKB | SKB    */
+        void      *dst_entry;       /* rtcache entry for locally termiated pkts */
+        uint32_t       fc_ctxt; /* hybrid flow cache context              */
+    };
+    union {
+        uint32_t    priority;       /* Custom arg2, packet priority, tx info  */
+		/*TODO define wl as  just uint32_t */
+        wlFlowInf_t wl;             /* WLAN Flow Info */
+        uint32_t    flowid;           /* used for locally terminated pkts */
+    };
+
+    RecycleFuncP  recycle_hook;   /* Nbuff recycle handler   */
+    union {
+             /* recycle hook for Clone FKB is used in DHD pointing to extra info
+	      * BE CAREFULL when using this recyle_context for free etc....  
+	      */ 
+	    void *dhd_pkttag_info_p;		  
+	    unsigned long recycle_context;     /* Rx network device/channel or pool */
+        uint32_t    fpm_num;
+    };
+
+} ____cacheline_aligned;   /* 2 cache lines wide */
+
+#define FKB_CLEAR_LEN_WORD_FLAGS(len_word) (len_word &= 0x00FFFFFF)
+
+
+/*
+ *------------------------------------------------------------------------------
+ * An fkbuff may be referred to as a:
+ *  master - a pre-allocated rxBuffer, inplaced ahead of the headroom.
+ *  cloned - allocated from a free pool of fkbuff and points to a master.
+ *
+ *  in_skb - when a FKB is passed as a member of a SKB structure.
+ *------------------------------------------------------------------------------
+ */
+#define FKB_IN_SKB                  (1 << 2)    /* Bit#2 is in_skb */
+
+/* Return flags with the in_skb tag set */
+static inline uint32_t _set_in_skb_tag_(uint32_t flags)
+{
+    return (flags | FKB_IN_SKB);
+}
+
+/* Fetch the in_skb tag in flags */
+static inline uint32_t _get_in_skb_tag_(void *ptr, uint32_t flags)
+{
+    if (_is_kptr_(ptr))
+        return 0;
+    return (flags & FKB_IN_SKB);
+}
+
+/* Determine whether the in_skb tag is set in flags */
+static inline uint32_t _is_in_skb_tag_(void *ptr, uint32_t flags)
+{
+    return ( _get_in_skb_tag_(ptr, flags) ? 1 : 0 );
+}
+
+#define CHK_IQ_PRIO                  (1 << 3)    /* Bit#3 is check IQ Prio */
+
+/* Return flags with the in_skb_tag and chk_iq_prio set */
+static inline uint32_t _set_in_skb_n_chk_iq_prio_tag_(uint32_t flags)
+{
+    return (flags | FKB_IN_SKB | CHK_IQ_PRIO);
+}
+
+/* Return flags with the chk_iq_prio set */
+static inline uint32_t _set_chk_iq_prio_tag_(uint32_t flags)
+{
+    return (flags | CHK_IQ_PRIO);
+}
+
+/* Fetch the chk_iq_prio tag in flags */
+static inline uint32_t _get_chk_iq_prio_tag_(uint32_t flags)
+{
+    return (flags & CHK_IQ_PRIO);
+}
+
+/* Determine whether the chk_iq_prio tag is set in flags */
+static inline uint32_t _is_chk_iq_prio_tag_(uint32_t flags)
+{
+    return ( _get_chk_iq_prio_tag_(flags) ? 1 : 0 );
+}
+
+
+/*
+ *------------------------------------------------------------------------------
+ * APIs to convert between a real kernel pointer and a dirty pointer.
+ *------------------------------------------------------------------------------
+ */
+
+#define FKB_DPTR_TAG                (1 << 0)    /* Bit#0 is dptr_tag */
+
+/* Test whether a pointer is a dirty pointer type */
+static inline uint32_t is_dptr_tag_(uint8_t * ptr)
+{
+    return ( ( (uint32_t) ((uintptr_t)ptr & FKB_DPTR_TAG) ) ? 1 : 0);
+}
+
+/* Encode a real kernel pointer to a dirty pointer type */
+static inline uint8_t * _to_dptr_from_kptr_(uint8_t * kernel_ptr)
+{
+    if((uintptr_t)(kernel_ptr) & FKB_DPTR_TAG)
+        kernel_ptr++;
+    /* Tag a kernel pointer's dirty_ptr bit, to denote a FKB dirty pointer */
+    return ( (uint8_t*) ((uintptr_t)(kernel_ptr) | FKB_DPTR_TAG) );
+}
+
+/* Decode a dirty pointer type into a real kernel pointer */
+static inline uint8_t * _to_kptr_from_dptr_(uint8_t * dirty_ptr)
+{
+    FKB_AUDIT(
+        if ( dirty_ptr && !is_dptr_tag_(dirty_ptr) )
+            printk("FKB ASSERT %s !is_dptr_tag_(%lu)\n",
+                   __FUNCTION__, (uintptr_t)dirty_ptr); );
+
+    /* Fetch kernel pointer from encoded FKB dirty_ptr,
+       by clearing dirty_ptr bit */
+    return ( (uint8_t*) ((uintptr_t)(dirty_ptr) & (~FKB_DPTR_TAG)) );
+}
+
+#define FKB_OPTR_TAG                (1<<1)      /* Bit#1 other_ptr tag */
+
+#define FKB_BLOG_TAG_MASK           (FKB_DPTR_TAG | FKB_OPTR_TAG)
+
+/* Verify whether a FKB pointer is pointing to a Blog */
+#define _IS_BPTR_(fkb_ptr) \
+         ( _is_kptr_(fkb_ptr) && ! ((uintptr_t)(fkb_ptr) & FKB_BLOG_TAG_MASK) )
+
+
+/*
+ *------------------------------------------------------------------------------
+ *
+ *                  Types of FKB objects
+ * 
+ *  - A Master FKB object contains memory for the rx buffer, with a FkBuff_t
+ *    placed at the head of the buffer. A Master FKB object may serve to
+ *    replenish a network devices receive ring, when packet buffers are not
+ *    promptly recycled. A Master FKB may also be used for packet replication
+ *    where in one of the transmitted packet replicas may need a unique
+ *    modification distinct from other replicas. In such a case, the FKB must
+ *    be first "unshared" by a deep packet buffer copy into a Master Fkb.
+ *    If CONFIG_BCM_NBUFF_FKB_POOL is enabled then a Free Pool of Master 
+ *    FKB objects is maintained. Master FKB may be alocated and recycled from 
+ *    this Master FKB Pool.The Master FKB Pool may also be used for 
+ *    replinishing a network device driver's rx buffer ring.
+ *
+ *  - A Cloned FKB object does not contain memory for the rx buffer.
+ *    Used by fkb_clone, to create multiple references to a packet buffer.
+ *    Multiple references to a packet buffer may be used for packet replication.
+ *    A FKB allocated from the FKB Cloned Pool will have master_p pointing to
+ *    a Master FKB and the recycle_hook member set to NULL.
+ *
+ *------------------------------------------------------------------------------
+ */
+typedef enum {
+    FkbMaster_e = 0,
+    FkbCloned_e = 1,
+    FkbMaxType_e
+} FkbObject_t;
+
+/*
+ * Function   : _get_master_users_
+ * Description: Given a pointer to a Master FKB, fetch the users count
+ * Caution    : Does not check whether the FKB is a Master or not!
+ */
+static inline uint32_t _get_master_users_(FkBuff_t * fkbM_p)
+{
+    uint32_t users;
+    users = atomic_read(&fkbM_p->users);
+
+    FKB_AUDIT(
+        if ( users == 0 )
+            printk("FKB ASSERT cpu<%u> %s(%p) users == 0, recycle<%pS>\n",
+                   smp_processor_id(), __FUNCTION__,
+                   fkbM_p, fkbM_p->recycle_hook); );
+    return users;
+}
+
+/*
+ * Function   : _is_fkb_cloned_pool_
+ * Description: Test whether an "allocated" FKB is from the FKB Cloned Pool.
+ */
+static inline uint32_t _is_fkb_cloned_pool_(FkBuff_t * fkb_p)
+{
+    if ( _is_kptr_(fkb_p->master_p)
+         && (fkb_p->recycle_hook == (RecycleFuncP)NULL) )
+    {
+        FKB_AUDIT(
+            /* ASSERT if the FKB is actually linked in a FKB pool */
+            if ( _is_kptr_(fkb_p->master_p->list) )
+            {
+                printk("FKB ASSERT cpu<%u> %s :"
+                       " _is_kptr_((%p)->%p->%p)"
+                       " master<%p>.recycle<%pS>\n",
+                       smp_processor_id(), __FUNCTION__, fkb_p,
+                       fkb_p->master_p, fkb_p->master_p->list,
+                       fkb_p->master_p,
+                       fkb_p->master_p->recycle_hook);
+            }
+            /* ASSERT that Master FKB users count is greater than 0 */
+            if ( _get_master_users_(fkb_p->master_p) == 0 )
+            {
+                printk("FKB ASSERT cpu<%u> %s :"
+                       " _get_master_users_(%p->%p) == 0\n",
+                       smp_processor_id(), __FUNCTION__,
+                       fkb_p, fkb_p->master_p);
+                return 0;
+            } );
+
+        return 1;   /* Allocated FKB is from the FKB Cloned Pool */
+    }
+    else
+        return 0;
+}
+
+/*
+ * Function   : _get_fkb_users_
+ * Description: Given a pointer to a FKB (Master or Cloned), fetch users count
+ */
+static inline uint32_t _get_fkb_users_(FkBuff_t * fkb_p)
+{
+    if ( _is_kptr_(fkb_p->master_p) )       /* Cloned FKB */
+    {
+        FKB_AUDIT(
+            if ( !_is_fkb_cloned_pool_(fkb_p) ) /* double check Cloned FKB */
+            {
+                printk("FKB ASSERT cpu<%u> %s :"
+                       " !_is_fkb_cloned_pool_(%p)"
+                       " master<%p>.recycle<%pS>\n",
+                       smp_processor_id(), __FUNCTION__,
+                       fkb_p, fkb_p->master_p,
+                       fkb_p->master_p->recycle_hook);
+                return 0;
+            } );
+
+        return _get_master_users_(fkb_p->master_p);
+    }
+    else                                    /* Master FKB */
+        return _get_master_users_(fkb_p);
+}
+
+/*
+ * Function   : _get_fkb_master_ptr_
+ * Description: Fetch the pointer to the Master FKB.
+ */
+static inline FkBuff_t * _get_fkb_master_ptr_(FkBuff_t * fkb_p)
+{
+    if ( _is_kptr_(fkb_p->master_p) )       /* Cloned FKB */
+    {
+        FKB_AUDIT( 
+            if ( !_is_fkb_cloned_pool_(fkb_p) ) /* double check Cloned FKB */
+            {
+                printk("FKB ASSERT cpu<%u> %s "
+                       " !_is_fkb_cloned_pool_(%p)"
+                       " master<%p>.recycle<%pS>\n",
+                       smp_processor_id(), __FUNCTION__,
+                       fkb_p, fkb_p->master_p,
+                       fkb_p->master_p->recycle_hook);
+                return FKB_NULL;
+            } );
+
+        return fkb_p->master_p;
+    }
+    else                                    /* Master FKB */
+    {
+        FKB_AUDIT( 
+            if ( _get_master_users_(fkb_p) == 0 )  /* assert Master FKB users */
+            {
+                printk("FKB ASSERT cpu<%u> %s "
+                       " _get_master_users_(%p) == 0\n",
+                       smp_processor_id(), __FUNCTION__, fkb_p);
+                return FKB_NULL;
+            } );
+
+        return fkb_p;
+    }
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Placement of a FKB object in the Rx DMA buffer:
+ *
+ * RX DMA Buffer:   |----- FKB ----|--- reserve headroom ---|---...... 
+ *                  ^              ^                        ^
+ *                pFkb           pHead                    pData
+ *                pBuf
+ *------------------------------------------------------------------------------
+ */
+#define PFKBUFF_PHEAD_OFFSET        sizeof(FkBuff_t)
+#define PFKBUFF_TO_PHEAD(pFkb)      ((uint8_t*)((FkBuff_t*)(pFkb) + 1))
+#define PHEAD_TO_PFKBUFF(pHead)    \
+            (FkBuff_t *)((uint8_t*)(pHead)-PFKBUFF_PHEAD_OFFSET)
+
+#define PDATA_TO_PFKBUFF(pData,headroom)    \
+            (FkBuff_t *)((uint8_t*)(pData)-(headroom)-PFKBUFF_PHEAD_OFFSET)
+#define PFKBUFF_TO_PDATA(pFkb,headroom)     \
+            (uint8_t*)((uint8_t*)(pFkb) + PFKBUFF_PHEAD_OFFSET + (headroom))
+
+
+#define NBUFF_ALIGN_MASK_8   0x07
+pNBuff_t nbuff_align_data(pNBuff_t pNBuff, uint8_t **data_pp,
+                          uint32_t len, unsigned long alignMask);
+
+/*
+ *------------------------------------------------------------------------------
+ *  FKB Functional Interfaces
+ *------------------------------------------------------------------------------
+ */
+
+/*
+ * Function   : fkb_in_skb_test
+ * Description: Verifies that the layout of SKB member fields corresponding to
+ *              a FKB have the same layout. This allows a FKB to be passed via
+ *              a SKB.
+ */
+
+extern int fkb_in_skb_test( int fkb_in_skb_offset,
+                            int list_offset, int blog_p_offset,
+                            int data_offset, int len_offset, int mark_offset,
+                            int priority_offset, int recycle_hook_offset,
+                            int recycle_context_offset );
+
+/*
+ * Global FKB Subsystem Constructor
+ * fkb_construct() validates that the layout of fkbuff members in sk_buff
+ * is the same. An sk_buff contains an fkbuff and permits a quick translation
+ * to and from a fkbuff. It also preallocates the pools of FKBs.
+ */
+extern int fkb_construct(int fkb_in_skb_offset);
+
+/*
+ * Function   : fkb_stats
+ * Description: Report FKB Pool statistics, see CC_CONFIG_FKB_STATS
+ */
+extern void fkb_stats(void);
+
+/*
+ * Function   : fkb_alloc
+ * Description: Allocate a Cloned/Master FKB object from preallocated pool
+ */
+extern FkBuff_t * fkb_alloc( FkbObject_t object );
+
+/*
+ * Function   : fkb_free
+ * Description: Free a FKB object to its respective preallocated pool.
+ */
+extern void fkb_free(FkBuff_t * fkb_p);
+
+/*
+ * Function   : fkb_unshare
+ * Description: If a FKB is pointing to a buffer with multiple references
+ * to this buffer, then create a copy of the buffer and return a FKB with a
+ * single reference to this buffer.
+ */
+extern FkBuff_t * fkb_unshare(FkBuff_t * fkb_p);
+
+/*
+ * Function   : fkbM_borrow
+ * Description: Allocate a Master FKB object from the pre-allocated pool.
+ */
+extern FkBuff_t * fkbM_borrow(void);
+
+/*
+ * Function   : fkb_set_ref
+ * Description: Set reference count to an FKB.
+ */
+static inline void _fkb_set_ref(FkBuff_t * fkb_p, const int count)
+{
+    atomic_long_set(&fkb_p->users, count);
+}
+FKB_FN( fkb_set_ref,
+        void fkb_set_ref(FkBuff_t * fkb_p, const int count),
+        _fkb_set_ref(fkb_p, count) )
+
+/*
+ * Function   : fkb_inc_ref
+ * Description: Increment reference count to an FKB.
+ */
+static inline void _fkb_inc_ref(FkBuff_t * fkb_p)
+{
+    atomic_long_inc(&fkb_p->users);
+}
+FKB_FN( fkb_inc_ref,
+        void fkb_inc_ref(FkBuff_t * fkb_p),
+        _fkb_inc_ref(fkb_p) )
+
+/*
+ * Function   : fkb_dec_ref
+ * Description: Decrement reference count to an FKB.
+ */
+static inline void _fkb_dec_ref(FkBuff_t * fkb_p)
+{
+    atomic_long_dec(&fkb_p->users);
+    /* For debug, may want to assert that users does not become negative */
+}
+FKB_FN( fkb_dec_ref,
+        void fkb_dec_ref(FkBuff_t * fkb_p),
+        _fkb_dec_ref(fkb_p) )
+
+
+/*
+ * Function   : fkb_preinit
+ * Description: A network device driver may use this function to place a
+ * FKB object into rx buffers, when they are created. FKB objects preceeds
+ * the reserved headroom.
+ */
+static inline void fkb_preinit(uint8_t * pBuf, RecycleFuncP recycle_hook,
+                               unsigned long recycle_context)
+{
+    FkBuff_t *fkb_p = (FkBuff_t *)pBuf;
+    fkb_p->recycle_hook = recycle_hook;         /* never modified */
+    fkb_p->recycle_context = recycle_context;   /* never modified */
+
+    fkb_p->ptr = NULL;                  /* resets dirty_p, blog_p */
+    fkb_p->data = NULL;
+    fkb_p->len_word = 0;
+    fkb_p->mark = 0;
+    fkb_p->priority = 0;
+    fkb_set_ref(fkb_p, 0);
+}
+
+/*
+ * Function   : fkb_init
+ * Description: Initialize the FKB context for a received packet. Invoked by a
+ * network device on extract the packet from a buffer descriptor and associating
+ * a FKB context to the received packet.
+ */
+static inline FkBuff_t * _fkb_init(uint8_t * pBuf, uint32_t headroom,
+                                   uint8_t * pData, uint32_t len)
+{
+    FkBuff_t * fkb_p = PDATA_TO_PFKBUFF(pBuf, headroom);
+    fkb_dbg( 1, "fkb_p<%px> pBuf<%px> headroom<%u> pData<%px> len<%d>",
+              fkb_p, pBuf, (int)headroom, pData, len );
+
+#if defined(CC_FKB_HEADROOM_AUDIT)
+    if ( headroom < BCM_PKT_HEADROOM )
+        printk("NBUFF: Insufficient headroom <%u>, need <%u> %-10s\n",
+               headroom, BCM_PKT_HEADROOM, __FUNCTION__);
+#endif
+
+    fkb_p->data = pData;
+    fkb_p->len_word = 0;/*clear flags */
+    fkb_p->len  = len;
+    fkb_p->ptr  = (void*)NULL;   /* resets dirty_p, blog_p */
+    fkb_p->mark = 0;
+    fkb_p->priority = 0;
+    
+    fkb_set_ref( fkb_p, 1 );
+
+    return fkb_p;
+}
+FKB_FN( fkb_init,
+        FkBuff_t * fkb_init(uint8_t * pBuf, uint32_t headroom,
+                            uint8_t * pData, uint32_t len),
+        return _fkb_init(pBuf, headroom, pData, len) )
+
+/*
+ * Function   : fkb_qinit
+ * Description: Same as fkb_init, with the exception that a recycle queue
+ * context is associated with the FKB, each time the packet is receieved.
+ */
+static inline FkBuff_t * _fkb_qinit(uint8_t * pBuf, uint32_t headroom,
+                    uint8_t * pData, uint32_t len, unsigned long qcontext)
+{
+    FkBuff_t * fkb_p = PDATA_TO_PFKBUFF(pBuf, headroom);
+    fkb_dbg(1, "fkb_p<%p> qcontext<%lx>", fkb_p, qcontext );
+    fkb_p->recycle_context = qcontext;
+
+    return _fkb_init(pBuf, headroom, pData, len);
+}
+FKB_FN( fkb_qinit,
+        FkBuff_t * fkb_qinit(uint8_t * pBuf, uint32_t headroom,
+                             uint8_t * pData, uint32_t len, unsigned long qcontext),
+        return _fkb_qinit(pBuf, headroom, pData, len, qcontext) )
+
+/*
+ * Function   : fkb_release
+ * Description: Release any associated blog and set ref count to 0. A fkb
+ * may be released multiple times (not decrement reference count).
+ */
+static inline void _fkb_release(FkBuff_t * fkb_p)
+{
+    fkb_dbg(1, "fkb_p<%p> fkb_p->blog_p<%px>", fkb_p, fkb_p->blog_p );
+#if defined(CONFIG_BLOG)
+    if ( _IS_BPTR_( fkb_p->blog_p ) )
+        blog_put(fkb_p->blog_p);
+#endif
+    fkb_p->ptr = (void*)NULL;   /* reset dirty_p, blog_p */
+
+    fkb_set_ref( fkb_p, 0 );    /* fkb_release may be invoked multiple times */
+}
+FKB_FN( fkb_release,
+        void fkb_release(FkBuff_t * fkb_p),
+        _fkb_release(fkb_p) )
+
+/*
+ * Function   : fkb_headroom
+ * Description: Determine available headroom for the packet in the buffer.
+ */
+static inline int _fkb_headroom(const FkBuff_t *fkb_p)
+{
+    return (int)( (uintptr_t)(fkb_p->data) - (uintptr_t)(fkb_p+1) );
+}
+FKB_FN( fkb_headroom,
+        int fkb_headroom(const FkBuff_t *fkb_p),
+        return _fkb_headroom(fkb_p) )
+
+/*
+ * Function   : fkb_init_headroom
+ * Description: The available headroom the packet in the buffer at fkb_init time.
+ */
+static inline int _fkb_init_headroom(void)
+{
+    return BCM_PKT_HEADROOM;
+}
+FKB_FN( fkb_init_headroom,
+        int fkb_init_headroom(void),
+        return _fkb_init_headroom() )
+
+
+/*
+ * Function   : fkb_push
+ * Description: Prepare space for data at head of the packet buffer.
+ */
+static inline uint8_t * _fkb_push(FkBuff_t * fkb_p, uint32_t len)
+{
+    fkb_p->len  += len;
+    fkb_p->data -= len;
+    return fkb_p->data;
+}
+FKB_FN( fkb_push,
+        uint8_t * fkb_push(FkBuff_t * fkb_p, uint32_t len),
+        return _fkb_push(fkb_p, len) )
+
+/*
+ * Function   : fkb_pull
+ * Description: Delete data from the head of packet buffer.
+ */
+static inline uint8_t * _fkb_pull(FkBuff_t * fkb_p, uint32_t len)
+{
+    fkb_p->len  -= len;
+    fkb_p->data += len;
+    return fkb_p->data;
+}
+FKB_FN( fkb_pull,
+        uint8_t * fkb_pull(FkBuff_t * fkb_p, uint32_t len),
+        return _fkb_pull(fkb_p, len) )
+
+/*
+ * Function   : fkb_put
+ * Description: Prepare space for data at tail of the packet buffer.
+ */
+static inline uint8_t * _fkb_put(FkBuff_t * fkb_p, uint32_t len)
+{
+    uint8_t * tail_p = fkb_p->data + fkb_p->len; 
+    fkb_p->len  += len;
+    return tail_p;
+}
+FKB_FN( fkb_put,
+        uint8_t * fkb_put(FkBuff_t * fkb_p, uint32_t len),
+        return _fkb_put(fkb_p, len) )
+
+/*
+ * Function   : fkb_pad
+ * Description: Pad the packet by requested number of bytes.
+ */
+static inline uint32_t _fkb_pad(FkBuff_t * fkb_p, uint32_t padding)
+{
+    memset((uint8_t *)(fkb_p->data + fkb_p->len), 0, padding);
+    fkb_p->len  += padding;
+    return fkb_p->len;
+}
+FKB_FN( fkb_pad,
+        uint32_t fkb_pad(FkBuff_t * fkb_p, uint32_t padding),
+        return _fkb_pad(fkb_p, padding) )
+
+/*
+ * Function   : fkb_len
+ * Description: Determine the length of the packet.
+ */
+static inline uint32_t _fkb_len(FkBuff_t * fkb_p)
+{
+    return fkb_p->len;
+}
+FKB_FN( fkb_len,
+        uint32_t fkb_len(FkBuff_t * fkb_p),
+        return _fkb_len(fkb_p) )
+
+/*
+ * Function   : fkb_data
+ * Description: Fetch the start of the packet.
+ */
+static inline uint8_t * _fkb_data(FkBuff_t * fkb_p)
+{
+    return fkb_p->data;
+}
+FKB_FN( fkb_data,
+        uint8_t * fkb_data(FkBuff_t * fkb_p),
+        return _fkb_data(fkb_p) )
+
+#if defined(CONFIG_BLOG)
+/*
+ * Function   : fkb_blog
+ * Description: Fetch the associated blog.
+ */
+static inline struct blog_t * _fkb_blog(FkBuff_t * fkb_p)
+{
+    return fkb_p->blog_p;
+}
+FKB_FN( fkb_blog,
+        struct blog_t * fkb_blog(FkBuff_t * fkb_p),
+        return _fkb_blog(fkb_p) )
+#endif
+
+/*
+ * Function   : fkb_clone
+ * Description: Allocate a FKB from the Cloned Pool and make it reference the
+ * same packet. fkbInSkb case allocates a new master FKB and copy the data
+ * (basically a FKB copy).
+ *
+ */
+static inline FkBuff_t * _fkb_clone(FkBuff_t * fkb_p)
+{
+    FkBuff_t *fkbM_p;
+
+    FKB_AUDIT( 
+        if ( smp_processor_id() )
+            printk("FKB ASSERT %s not supported on CP 1\n", __FUNCTION__); );
+
+    /* Fetch a pointer to the Master FKB */
+    fkbM_p = _get_fkb_master_ptr_( fkb_p );
+
+    if ( !is_dptr_tag_(fkbM_p->dirty_p ) && _is_in_skb_tag_(fkbM_p->ptr, fkbM_p->flags) )
+    {
+        /* FKB Alloc and copy */
+        fkbM_p = fkb_alloc( FkbMaster_e );
+        if (fkbM_p == FKB_NULL)
+        {
+            fkb_dbg(1, "fkb_clone FKB fkb_alloc failure");
+            return FKB_NULL;
+        }
+        fkb_set_ref(fkbM_p, 1);
+
+        fkbM_p->data = PFKBUFF_TO_PDATA(fkbM_p, BCM_PKT_HEADROOM);
+
+        fkbM_p->len_word = fkb_p->len_word;
+        fkbM_p->mark = fkb_p->mark;
+        fkbM_p->priority = fkb_p->priority;
+        fkbM_p->dirty_p = _to_dptr_from_kptr_(fkbM_p->data + fkbM_p->len);
+
+        memcpy(fkbM_p->data, fkb_p->data, fkb_p->len);
+
+        fkb_dbg(1, "fkbM_p<%p> ---> fkb_p<%p>", fkbM_p, fkb_p );
+
+        return fkbM_p;
+    }
+    else
+    {
+        FkBuff_t *fkbC_p = fkb_alloc( FkbCloned_e );  /* Allocate FKB from Cloned pool */
+
+        if ( unlikely(fkbC_p != FKB_NULL) )
+        {
+            fkb_inc_ref( fkbM_p );
+            fkbC_p->master_p   = fkbM_p;
+            fkbC_p->ptr   = fkbM_p->ptr;
+
+            fkbC_p->data       = fkbM_p->data;
+            fkbC_p->len_word   = fkbM_p->len_word;
+            fkbC_p->mark       = fkbM_p->mark;
+            fkbC_p->priority   = fkbM_p->priority;
+        }
+
+        fkb_dbg(1, "fkbC_p<%p> ---> fkbM_p<%p>", fkbC_p, fkbM_p );
+
+        return fkbC_p;       /* May be null */
+    }
+}
+FKB_FN( fkb_clone,
+        FkBuff_t * fkb_clone(FkBuff_t * fkbM_p),
+        return _fkb_clone(fkbM_p) )
+
+extern void fkb_flush(FkBuff_t * fkb_p, uint8_t * data_p, int len, int cache_op);
+
+/*
+ *------------------------------------------------------------------------------
+ * Virtual accessors to common members of network kernel buffer
+ *------------------------------------------------------------------------------
+ */
+
+/* __BUILD_NBUFF_SET_ACCESSOR: generates function nbuff_set_MEMBER() */
+#define __BUILD_NBUFF_SET_ACCESSOR( TYPE, MEMBER )                             \
+static inline void nbuff_set_##MEMBER(pNBuff_t pNBuff, TYPE MEMBER) \
+{                                                                              \
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);                                       \
+    if ( IS_SKBUFF_PTR(pNBuff) )                                               \
+        ((struct sk_buff *)pBuf)->MEMBER = MEMBER;                             \
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */                         \
+    else                                                                       \
+        ((FkBuff_t *)pBuf)->MEMBER = MEMBER;                                   \
+}
+
+/* __BUILD_NBUFF_GET_ACCESSOR: generates function nbuff_get_MEMBER() */
+#define __BUILD_NBUFF_GET_ACCESSOR( TYPE, MEMBER )                             \
+static inline TYPE nbuff_get_##MEMBER(pNBuff_t pNBuff)                         \
+{                                                                              \
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);                                       \
+    if ( IS_SKBUFF_PTR(pNBuff) )                                               \
+        return (TYPE)(((struct sk_buff *)pBuf)->MEMBER);                       \
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */                         \
+    else                                                                       \
+        return (TYPE)(((FkBuff_t *)pBuf)->MEMBER);                             \
+}
+
+/*
+ * Common set/get accessor of base network buffer fields:
+ * nbuff_set_data(), nbuff_set_len(), nbuff_set_mark(), nbuff_set_priority()
+ * nbuff_get_data(), nbuff_get_len(), nbuff_get_mark(), nbuff_get_priority()
+ */
+__BUILD_NBUFF_SET_ACCESSOR(uint8_t *, data) 
+__BUILD_NBUFF_SET_ACCESSOR(uint32_t, len) 
+__BUILD_NBUFF_SET_ACCESSOR(uint32_t, mark)      /* Custom network buffer arg1 */
+__BUILD_NBUFF_SET_ACCESSOR(void *, queue)     /* Custom network buffer arg1 */
+__BUILD_NBUFF_SET_ACCESSOR(uint32_t, priority)  /* Custom network buffer arg2 */
+
+__BUILD_NBUFF_GET_ACCESSOR(uint8_t *, data)
+__BUILD_NBUFF_GET_ACCESSOR(uint32_t, len)
+__BUILD_NBUFF_GET_ACCESSOR(uint32_t, mark)      /* Custom network buffer arg1 */
+__BUILD_NBUFF_GET_ACCESSOR(void *, queue)     /* Custom network buffer arg1 */
+__BUILD_NBUFF_GET_ACCESSOR(uint32_t, priority)  /* Custom network buffer arg2 */
+
+/*
+ * Function   : nbuff_get_context
+ * Description: Extracts the data and len fields from a pNBuff_t.
+ */
+static inline void * nbuff_get_context(pNBuff_t pNBuff,
+                                     uint8_t ** data_p, uint32_t *len_p)
+{
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( pBuf == (void*) NULL )
+        return pBuf;
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        *data_p     = ((struct sk_buff *)pBuf)->data;
+        *len_p      = ((struct sk_buff *)pBuf)->len;
+    }
+    else
+    {
+        *data_p     = ((FkBuff_t *)pBuf)->data;
+        *len_p      = ((FkBuff_t *)pBuf)->len;
+    }
+    fkb_dbg(1, "pNBuff<%p> pBuf<%p> data_p<%p>",
+           pNBuff, pBuf, *data_p );
+    return pBuf;
+}
+
+/*
+ * Function   : nbuff_get_params
+ * Description: Extracts the data, len, mark and priority field from a network
+ * buffer.
+ */
+static inline void * nbuff_get_params(pNBuff_t pNBuff,
+                                     uint8_t ** data_p, uint32_t *len_p,
+                                     uint32_t * mark_p, uint32_t *priority_p)
+{
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( pBuf == (void*) NULL )
+        return pBuf;
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        *data_p     = ((struct sk_buff *)pBuf)->data;
+        *len_p      = ((struct sk_buff *)pBuf)->len;
+        *mark_p     = ((struct sk_buff *)pBuf)->mark;
+        *priority_p = ((struct sk_buff *)pBuf)->priority;
+    }
+    else
+    {
+        *data_p     = ((FkBuff_t *)pBuf)->data;
+        *len_p      = ((FkBuff_t *)pBuf)->len;
+        *mark_p     = ((FkBuff_t *)pBuf)->mark;
+        *priority_p = ((FkBuff_t *)pBuf)->priority;
+    }
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px> data_p<%px>",
+            pNBuff, pBuf, *data_p );
+    return pBuf;
+}
+    
+/* adds recycle flags/context to nbuff_get_params used in impl4 enet */
+/*
+ * Function   : nbuff_get_params_ext
+ * Description: Extracts the data, len, mark, priority and 
+ * recycle flags/context field from a network buffer.
+ */
+static inline void * nbuff_get_params_ext(pNBuff_t pNBuff, uint8_t **data_p, 
+                                          uint32_t *len_p, uint32_t *mark_p, 
+                                          uint32_t *priority_p, 
+                                          uint32_t *rflags_p)
+{
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( pBuf == (void*) NULL )
+        return pBuf;
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        *data_p     = ((struct sk_buff *)pBuf)->data;
+        *len_p      = ((struct sk_buff *)pBuf)->len;
+        *mark_p     = ((struct sk_buff *)pBuf)->mark;
+        *priority_p = ((struct sk_buff *)pBuf)->priority;
+#if defined(CONFIG_BLOG)
+        *rflags_p   = ((struct sk_buff *)pBuf)->recycle_flags;
+#endif
+    }
+    else
+    {
+        *data_p     = ((FkBuff_t *)pBuf)->data;
+        *len_p      = ((FkBuff_t *)pBuf)->len;
+        *mark_p     = ((FkBuff_t *)pBuf)->mark;
+        *priority_p = ((FkBuff_t *)pBuf)->priority;
+#if defined(CONFIG_BLOG)
+        *rflags_p   = ((FkBuff_t *)pBuf)->recycle_context;
+#endif
+    }
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px> data_p<%px>",
+            pNBuff, pBuf, *data_p );
+    return pBuf;
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Virtual common functional apis of a network kernel buffer
+ *------------------------------------------------------------------------------
+ */
+
+/*
+ * Function   : nbuff_push
+ * Description: Make space at the start of a network buffer.
+ * CAUTION    : In the case of a FKB, no check for headroom is done.
+ */
+static inline uint8_t * nbuff_push(pNBuff_t pNBuff, uint32_t len)
+{
+    uint8_t * data;
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( IS_SKBUFF_PTR(pNBuff) )
+        data = skb_push(((struct sk_buff *)pBuf), len);
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */
+    else
+        data = fkb_push((FkBuff_t*)pBuf, len);
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px> data<%px> len<%u>",
+            pNBuff, pBuf, data, len );
+    return data;
+}
+
+/*
+ * Function   : nbuff_pull
+ * Description: Delete data from start of a network buffer.
+ */
+static inline uint8_t * nbuff_pull(pNBuff_t pNBuff, uint32_t len)
+{
+    uint8_t * data;
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( IS_SKBUFF_PTR(pNBuff) )
+        data = skb_pull(((struct sk_buff *)pBuf), len);
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */
+    else
+        data = fkb_pull((FkBuff_t *)pBuf, len);
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px> data<%px> len<%u>",
+            pNBuff, pBuf, data, len );
+    return data;
+}
+
+/*
+ * Function   : nbuff_put
+ * Description: Make space at the tail of a network buffer.
+ * CAUTION: In the case of a FKB, no check for tailroom is done.
+ */
+static inline uint8_t * nbuff_put(pNBuff_t pNBuff, uint32_t len)
+{
+    uint8_t * tail;
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    if ( IS_SKBUFF_PTR(pNBuff) )
+        tail = skb_put(((struct sk_buff *)pBuf), len);
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */
+    else
+        tail = fkb_put((FkBuff_t *)pBuf, len);
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px> tail<%px> len<%u>",
+            pNBuff, pBuf, tail, len );
+    return tail;
+}
+
+#ifdef CONFIG_BCM_SKB_FREE_THREAD
+extern void dev_kfree_skb_thread(struct sk_buff *skb);
+#endif
+extern void nbuff_free_ex(pNBuff_t pNBuff, int in_thread);
+extern void nbuff_free(pNBuff_t pNBuff);
+
+/*
+ * Function   : nbuff_unshare
+ * Description: If there are more than one references to the data buffer
+ * associated with the network buffer, create a deep copy of the data buffer
+ * and return a network buffer context to it. The returned network buffer
+ * may be then used to modify the data packet without impacting the original
+ * network buffer and its data buffer.
+ *
+ * If the data packet had a single network buffer referencing it, then the
+ * original network buffer is returned.
+ */
+static inline pNBuff_t nbuff_unshare(pNBuff_t pNBuff)
+{
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px>", pNBuff, pBuf);
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        struct sk_buff *skb_p;
+        skb_p = skb_unshare( (struct sk_buff *)pBuf, GFP_ATOMIC);
+        pNBuff = SKBUFF_2_PNBUFF(skb_p);
+    }
+    else
+    {
+        FkBuff_t * fkb_p;
+        fkb_p = fkb_unshare( (FkBuff_t *)pBuf );
+        pNBuff = FKBUFF_2_PNBUFF(fkb_p);
+    }
+
+    fkb_dbg(2, "<<");
+    return pNBuff;
+}
+
+/*
+ * Function   : nbuff_invalidate_headroom
+ * Description: invalidate datacache lines of memory prefixing "data" pointer.
+ * Invalidation does not include the dcache line "data" is in. This dcache line
+ * must be flushed, not invalidated.
+ */
+static inline void nbuff_invalidate_headroom(pNBuff_t pNBuff, uint8_t * data)
+{
+
+    /* Invalidate functions used here will round up end pointer to cache line 
+     * boundry. That's the reason for L1_CACHE_BYTES substruction.
+     */
+    int32_t inv_len = 0;
+    fkb_dbg(1, "pNBuff<%p> data<%p>", pNBuff, data);
+
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        inv_len = skb_avail_headroom( PNBUFF_2_SKBUFF(pNBuff) ) - L1_CACHE_BYTES;
+        cache_invalidate_region(PNBUFF_2_SKBUFF(pNBuff)->head, data - L1_CACHE_BYTES);
+    }
+    else
+    {
+        FkBuff_t * fkb_p = (FkBuff_t *)PNBUFF_2_PBUF(pNBuff);
+
+        if ( _is_fkb_cloned_pool_(fkb_p) )
+            fkb_p = fkb_p->master_p;
+
+        inv_len =  data - PFKBUFF_TO_PHEAD(fkb_p) - L1_CACHE_BYTES;
+        fkb_flush(fkb_p, PFKBUFF_TO_PHEAD(fkb_p), inv_len, FKB_CACHE_INV); 
+    }
+    fkb_dbg(1, " len<%d>", inv_len);
+    fkb_dbg(2, "<<");
+}
+
+extern void nbuff_flush(pNBuff_t pNBuff, uint8_t * data, int len);
+extern void nbuff_flushfree(pNBuff_t pNBuff);
+
+/*
+ * Function   : nbuff_xlate
+ * Description: Convert a FKB to a SKB. The SKB is data filled with the
+ * data, len, mark, priority, and recycle hook and context. 
+ *
+ * Other SKB fields for SKB API manipulation are also initialized.
+ * SKB fields for network stack manipulation are NOT initialized.
+ *
+ * This function is typically used only in a network device drivers' hard
+ * start xmit function handler. A hard start xmit function handler may receive
+ * a network buffer of a FKB type and may not wish to rework the implementation
+ * to use nbuff APIs. In such an event, a nbuff may be translated to a skbuff.
+ */
+struct sk_buff * fkb_xlate(FkBuff_t * fkb_p);
+static inline struct sk_buff * nbuff_xlate( pNBuff_t pNBuff )
+{
+    void * pBuf = PNBUFF_2_PBUF(pNBuff);
+    fkb_dbg(1, "pNBuff<%px> pBuf<%px>", pNBuff, pBuf);
+
+    if ( IS_SKBUFF_PTR(pNBuff) )
+        return (struct sk_buff *)pBuf;
+    /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */
+    else
+        return fkb_xlate( (FkBuff_t *)pBuf );
+}
+
+
+/* Miscellaneous helper routines */
+static inline void u16cpy( void * dst_p, const void * src_p, uint32_t bytes )
+{
+    uint16_t * dst16_p = (uint16_t*)dst_p;
+    uint16_t * src16_p = (uint16_t*)src_p;
+    do { // assuming: (bytes % sizeof(uint16_t) == 0 !!!
+        *dst16_p++ = *src16_p++;
+    } while ( bytes -= sizeof(uint16_t) );
+}
+
+static inline void u16datacpy( void * dst_p, const void * src_p, uint32_t bytes )
+{
+    uint16_t * dst16_p = (uint16_t*)dst_p;
+    uint16_t * src16_p = (uint16_t*)src_p;
+    do { // assuming: (bytes % sizeof(uint16_t) == 0 !!!
+        *dst16_p++ = htons (*src16_p++);
+    } while ( bytes -= sizeof(uint16_t) );
+}
+
+static inline int u16cmp( void * dst_p, const void * src_p,
+                          uint32_t bytes )
+{
+    uint16_t * dst16_p = (uint16_t*)dst_p;
+    uint16_t * src16_p = (uint16_t*)src_p;
+    do { // assuming: (bytes % sizeof(uint16_t) == 0 !!!
+        if ( *dst16_p++ != *src16_p++ )
+            return -1;
+    } while ( bytes -= sizeof(uint16_t) );
+
+    return 0;
+}
+
+static inline int nbuff_pad(pNBuff_t pNBuff, int padLen)
+{
+    if ( IS_SKBUFF_PTR(pNBuff) )
+    {
+        int ret = skb_put_padto((struct sk_buff *)pNBuff, padLen + ((struct sk_buff *)pNBuff)->len);
+        if (ret)
+            printk(KERN_ERR "nbuff_pad() skb_put_padto err=%d!!\n", ret);
+        return ret;
+    }
+    else
+    {
+        fkb_pad(PNBUFF_2_FKBUFF(pNBuff), padLen);
+    }
+    return 0;
+}
+
+#ifdef DUMP_DATA
+/* dumpHexData dump out the hex base binary data */
+static inline void dumpHexData1(uint8_t *pHead, uint32_t len)
+{
+    uint32_t i;
+    uint8_t *c = pHead;
+    for (i = 0; i < len; ++i) {
+        if (i % 16 == 0)
+            printk("\n");
+        printk("0x%02X, ", *c++);
+    }
+    printk("\n");
+}
+
+static inline void dump_pkt(const char * fname, uint8_t * pBuf, uint32_t len)
+{
+    //int dump_len = ( len < 64) ? len : 64;
+    int dump_len = len ;
+    printk("%s: data<0x%lu len<%u>", fname, (uintptr_t)pBuf, len);
+    dumpHexData1(pBuf, dump_len);
+    cache_flush_len((void*)pBuf, dump_len);
+}
+#define DUMP_PKT(pBuf,len)      dump_pkt(__FUNCTION__, (pBuf), (len))
+#else   /* !defined(DUMP_DATA) */
+#define DUMP_PKT(pBuf,len)      do {} while(0)
+#endif
+
+#endif  /* defined(__NBUFF_H_INCLUDED__) */
diff --git a/include/linux/nbuff_types.h b/include/linux/nbuff_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..672f79c6189b21e94ac72e0ff4f6cd55f8890994
--- /dev/null
+++ b/include/linux/nbuff_types.h
@@ -0,0 +1,68 @@
+#ifndef __NBUFF_TYPES_H_INCLUDED__
+#define __NBUFF_TYPES_H_INCLUDED__
+
+/*
+<:copyright-BRCM:2013:DUAL/GPL:standard
+
+   Copyright (c) 2013 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+/*
+ *******************************************************************************
+ *
+ * File Name  : nbuff_types.h
+ * Description: Simple nbuff type defines.
+ *
+ ******************************************************************************* */
+
+#define MUST_BE_ZERO                0
+
+/* virtual network buffer pointer to SKB|FPB|TGB|FKB  */
+typedef void * pNBuff_t;
+#define PNBUFF_NULL                 ((pNBuff_t)NULL)
+
+typedef enum NBuffPtrType
+{
+    SKBUFF_PTR = MUST_BE_ZERO,      /* Default Linux networking socket buffer */
+    FPBUFF_PTR,                     /* Experimental BRCM IuDMA freepool buffer*/
+    TGBUFF_PTR,                     /* LAB Traffic generated network buffer   */
+    FKBUFF_PTR,                     /* Lightweight fast kernel network buffer */
+    /* Do not add new ptr types */
+} NBuffPtrType_t;
+
+                                    /* 2lsbits in pointer encode NbuffType_t  */
+#define NBUFF_TYPE_MASK             0x3ul
+#define NBUFF_PTR_MASK              (~NBUFF_TYPE_MASK)
+#define NBUFF_PTR_TYPE(pNBuff)      ((uintptr_t)(pNBuff) & NBUFF_TYPE_MASK)
+
+
+#define IS_SKBUFF_PTR(pNBuff)       ( NBUFF_PTR_TYPE(pNBuff) == SKBUFF_PTR )
+#define IS_FPBUFF_PTR(pNBuff)       ( NBUFF_PTR_TYPE(pNBuff) == FPBUFF_PTR )
+#define IS_TGBUFF_PTR(pNBuff)       ( NBUFF_PTR_TYPE(pNBuff) == TGBUFF_PTR )
+#define IS_FKBUFF_PTR(pNBuff)       ( NBUFF_PTR_TYPE(pNBuff) == FKBUFF_PTR )
+
+
+#endif  /* defined(__NBUFF_TYPES_H_INCLUDED__) */
diff --git a/include/linux/netfilter/bcm_nfnetlink_conntrack.h b/include/linux/netfilter/bcm_nfnetlink_conntrack.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1051478648a78adbedfef0112f4a39c46fbd071
--- /dev/null
+++ b/include/linux/netfilter/bcm_nfnetlink_conntrack.h
@@ -0,0 +1,9 @@
+#ifndef _BCM_NFNETLINK_CONNTRACK_H
+#define _BCM_NFNETLINK_CONNTRACK_H
+
+extern int bcm_ctnetlink_size(const struct nf_conn *ct);
+extern int bcm_ctnetlink_dump(struct sk_buff *skb, const struct nf_conn *ct);
+extern int bcm_ctnetlink_change(struct nf_conn *ct,
+				const struct nlattr * const cda[]);
+
+#endif /* _BCM_NFNETLINK_CONNTRACK_H */
diff --git a/include/linux/netfilter/nf_conntrack_ipsec.h b/include/linux/netfilter/nf_conntrack_ipsec.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a709a8fb94afbf9af69f423d7e5735c12130bc5
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_ipsec.h
@@ -0,0 +1,43 @@
+/* IPSEC constants and structs */
+#ifndef _NF_CONNTRACK_IPSEC_H
+#define _NF_CONNTRACK_IPSEC_H
+
+#include <linux/netfilter/nf_conntrack_common.h>
+
+/* conntrack private data */
+struct nf_ct_ipsec_master 
+{
+   __be32 initcookie;  /* initcookie of ISAKMP */
+   __be32 lan_ip;        /* LAN IP */
+};
+
+struct nf_nat_ipsec 
+{
+   __be32 lan_ip;   /* LAN IP */
+};
+
+#ifdef __KERNEL__
+
+#define IPSEC_PORT   500
+#define MAX_VPN_CONNECTION 8  
+
+struct isakmp_pkt_hdr 
+{
+   __be32 initcookie;
+};
+
+
+/* crap needed for nf_conntrack_compat.h */
+struct nf_conn;
+struct nf_conntrack_expect;
+
+extern int
+(*nf_nat_ipsec_hook_outbound)(struct sk_buff *skb,
+                           struct nf_conn *ct, enum ip_conntrack_info ctinfo);
+
+extern int
+(*nf_nat_ipsec_hook_inbound)(struct sk_buff *skb, struct nf_conn *ct,
+                             enum ip_conntrack_info ctinfo, __be32 lan_ip);
+
+#endif /* __KERNEL__ */
+#endif /* _NF_CONNTRACK_IPSEC_H */
diff --git a/include/linux/netfilter/nf_conntrack_proto_esp.h b/include/linux/netfilter/nf_conntrack_proto_esp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2717a52cc504f7f266b28ce6df3b826fb2ca9905
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_proto_esp.h
@@ -0,0 +1,23 @@
+#if defined(CONFIG_BCM_KF_PROTO_ESP)
+#ifndef _CONNTRACK_PROTO_ESP_H
+#define _CONNTRACK_PROTO_ESP_H
+#include <asm/byteorder.h>
+
+/* ESP PROTOCOL HEADER */
+
+struct esphdr {
+	__u32	spi;
+};
+
+struct nf_ct_esp {
+	unsigned int stream_timeout;
+	unsigned int timeout;
+};
+
+#ifdef __KERNEL__
+#include <net/netfilter/nf_conntrack_tuple.h>
+
+#endif /* __KERNEL__ */
+#endif /* _CONNTRACK_PROTO_ESP_H */
+#endif
+
diff --git a/include/linux/netfilter/nf_conntrack_rtsp.h b/include/linux/netfilter/nf_conntrack_rtsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..e087a5141f776e5d3d7bf81bd19323d6217e381c
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_rtsp.h
@@ -0,0 +1,91 @@
+/*
+* <:copyright-BRCM:2012:DUAL/GPL:standard
+* 
+*    Copyright (c) 2012 Broadcom 
+*    All Rights Reserved
+* 
+* 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.
+* 
+* Not withstanding 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.
+* 
+:>
+*/
+
+#ifndef _NF_CONNTRACK_RTSP_H
+#define _NF_CONNTRACK_RTSP_H
+
+#ifdef __KERNEL__
+
+/* This structure exists only once per master */
+struct nf_ct_rtsp_master {
+	/* The client has sent PAUSE message and not replied */
+	int paused;
+};
+
+/* Single data channel */
+extern int (*nat_rtsp_channel_hook) (struct sk_buff *skb,
+				     unsigned int protoff,
+				     struct nf_conn *ct,
+				     enum ip_conntrack_info ctinfo,
+				     unsigned int matchoff,
+				     unsigned int matchlen,
+				     struct nf_conntrack_expect *exp,
+				     int *delta);
+
+/* A pair of data channels (RTP/RTCP) */
+extern int (*nat_rtsp_channel2_hook) (struct sk_buff *skb,
+				      unsigned int protoff,
+				      struct nf_conn *ct,
+				      enum ip_conntrack_info ctinfo,
+				      unsigned int matchoff,
+				      unsigned int matchlen,
+				      struct nf_conntrack_expect *rtp_exp,
+				      struct nf_conntrack_expect *rtcp_exp,
+				      char dash, int *delta);
+
+/* Modify parameters like client_port in Transport for single data channel */
+extern int (*nat_rtsp_modify_port_hook) (struct sk_buff *skb,
+				         unsigned int protoff,
+					 struct nf_conn *ct,
+			      	  	 enum ip_conntrack_info ctinfo,
+			      	  	 unsigned int matchoff,
+					 unsigned int matchlen,
+			      	  	 __be16 rtpport, int *delta);
+
+/* Modify parameters like client_port in Transport for multiple data channels*/
+extern int (*nat_rtsp_modify_port2_hook) (struct sk_buff *skb,
+				          unsigned int protoff,
+					  struct nf_conn *ct,
+			       	   	  enum ip_conntrack_info ctinfo,
+			       	   	  unsigned int matchoff,
+					  unsigned int matchlen,
+			       	   	  __be16 rtpport, __be16 rtcpport,
+				   	  char dash, int *delta);
+
+/* Modify parameters like destination in Transport */
+extern int (*nat_rtsp_modify_addr_hook) (struct sk_buff *skb,
+				         unsigned int protoff,
+					 struct nf_conn *ct,
+				 	 enum ip_conntrack_info ctinfo,
+					 int matchoff, int matchlen,
+					 int *delta);
+#endif /* __KERNEL__ */
+
+#endif /* _NF_CONNTRACK_RTSP_H */
+
diff --git a/include/linux/tracker.h b/include/linux/tracker.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4cad1bca0878227366ba4ceb9785ece63f036c0
--- /dev/null
+++ b/include/linux/tracker.h
@@ -0,0 +1,84 @@
+/*
+*    Copyright (c) 2020 Broadcom
+*    All Rights Reserved
+*
+<:label-BRCM:2020:DUAL/GPL:standard
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+#ifndef TRACKER_H
+#define TRACKER_H
+
+/* The tracker allows to track arbitrary pointers across the kernel lifetime.
+ *
+ * Expected usage is to sprinkle track_printf's in the interesting points of
+ * ptr usage.
+ *
+ * The resulting strings are accessible in the shell by catting /proc/tracker.
+ *
+ * When investigating specific badness tracker_print and tracker_find are useful
+ * to dump or work with this information from inside of the kernel.
+ */
+
+/* Initialize tracker. Should be called once */
+void track_init(void);
+
+/* Dumps information regarding ptr to dmesg */
+void tracker_print(void *ptr);
+
+/* Looks for pointer ptr_any. If found, tracker_find calls cb callback for each recorded state.
+ * In addition to state the callback gets arbitrary ctx passed by the caller.
+ *
+ * This function is useful to analyse the pointer states during runtime. Here is example
+ * diff which helped us track freeing non-allocated pointer in linux kernel:
+ *
+ * +static void seen_alloc(void *ctx, const char *st) {
+ * +	int *alloced = ctx;
+ * +
+ * +	if (strncmp(st, "header_alloc", strlen("header_alloc")) == 0)
+ * +		*alloced = 1;
+ * +}
+ * +
+ *  static void drop_sysctl_table(struct ctl_table_header *header)
+ *  {
+ *  	struct ctl_dir *parent = header->parent;
+ * +	int alloced = 0;
+ *  
+ *  	if (--header->nreg)
+ *  		return;
+ *  
+ * +	tracker_find(header, seen_alloc, &alloced);
+ * +	if (!alloced) {
+ * +		printk("boriss: non alloced header %px\n", header);
+ * +		WARN_ON(1);
+ * +	}
+ * 
+ */
+void tracker_find(void *ptr_any, void (*cb)(void *ctx, const char *st), void *ctx);
+
+/* printf into new state string attached to the pointer ptr. The resulting string will
+ * be dumped by tracker_print and passed to the callback in tracker_find.
+ */
+void track_printf(void *ptr, const char *fmt, ...);
+
+#endif /* TRACKER_H */
diff --git a/include/linux/vlanctl_bind.h b/include/linux/vlanctl_bind.h
new file mode 100755
index 0000000000000000000000000000000000000000..20a1ad2197a92e1031249659e27efd2236439b65
--- /dev/null
+++ b/include/linux/vlanctl_bind.h
@@ -0,0 +1,123 @@
+/*
+*    Copyright (c) 2003-2014 Broadcom Corporation
+*    All Rights Reserved
+*
+<:label-BRCM:2014:DUAL/GPL:standard 
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+
+#ifndef _VLANCTL_BIND_
+#define _VLANCTL_BIND_
+
+typedef enum {
+        VLANCTL_BIND_CLIENT_UNKNOWN,
+#if defined(CONFIG_BCM_RDPA) || defined(CONFIG_BCM_RDPA_MODULE)
+        VLANCTL_BIND_CLIENT_RUNNER,
+#endif /* RDPA */
+        VLANCTL_BIND_CLIENT_MAX
+} vlanctl_bind_client_t;
+
+
+/*
+ * vlanctl_bind defines three(!) hooks:
+ *  NotifHook: When blog_notify is invoked, the bound hook is invoked. Based on
+ *           event type the bound Blog client may perform a custom action.
+ *  SC Hook: If this hook is defined, blog_activate() will pass a blog with
+ *           necessary information for statical configuration.
+ *  SD Hook: If this hook is defined, blog_deactivate() will pass a pointer
+ *           to a network object with BlogActivateKey information. The
+ *           respective flow entry will be deleted.
+ */
+typedef union {
+    struct {
+        uint8_t         unused      : 5;
+        uint8_t         SN_HOOK     : 1;
+        uint8_t         SC_HOOK     : 1;
+        uint8_t         SD_HOOK     : 1;
+    } bmap;
+    uint8_t             hook_info;
+} vlanctl_bind_t;
+
+typedef struct {
+    struct net_device *vlan_dev;
+    unsigned int vid;
+    int enable;
+} vlanctl_vlan_t;
+
+typedef struct {
+    uint8_t mac[6];
+    int enable;
+} vlanctl_route_mac_t;
+
+typedef struct {
+    struct net_device *aggregate_vlan_dev;
+    struct net_device *deaggregate_vlan_dev;
+} vlanctl_vlan_aggregate_t;
+
+typedef enum {
+        VLANCTL_BIND_NOTIFY_TPID,       /* set interface tpid */
+        VLANCTL_BIND_NOTIFY_VLAN,       /* set vlan object */
+        VLANCTL_BIND_NOTIFY_ROUTE_MAC,  /* route mac create and delete */
+        VLANCTL_BIND_NOTIFY_VLAN_AGGREGATE,       /* set vlan aggregation */        
+        VLANCTL_BIND_DROP_PRECEDENCE_SET,       /* rdpa_mw_drop_precedence_set */
+} vlanctl_bind_Notify_t;
+
+#if defined(CONFIG_BLOG)
+
+typedef uint32_t (* vlanctl_bind_ScHook_t)(Blog_t * blog_p, BlogTraffic_t traffic);
+
+typedef Blog_t * (* vlanctl_bind_SdHook_t)(uint32_t key, BlogTraffic_t traffic);
+
+typedef void     (* vlanctl_bind_SnHook_t)(vlanctl_bind_Notify_t event, void *ptr);
+
+void vlanctl_bind_config(vlanctl_bind_ScHook_t vlanctl_bind_sc, 
+	                     vlanctl_bind_SdHook_t vlanctl_bind_sd,  
+	                     vlanctl_bind_SnHook_t vlanctl_bind_sn,  
+	                     vlanctl_bind_client_t client, 
+                         vlanctl_bind_t bind);
+
+
+int vlanctl_bind_activate(vlanctl_bind_client_t client);
+
+int	vlanctl_notify(vlanctl_bind_Notify_t event, void *ptr, vlanctl_bind_client_t client);
+
+/*
+ *------------------------------------------------------------------------------
+ *  vlanctl_activate(): static configuration function of blog application
+ *             pass a filled blog to the hook for configuration
+ *------------------------------------------------------------------------------
+ */
+extern uint32_t vlanctl_activate( Blog_t * blog_p,  vlanctl_bind_client_t client );
+
+/*
+ *------------------------------------------------------------------------------
+ *  vlanctl_deactivate(): static deconfiguration function of blog application
+ *------------------------------------------------------------------------------
+ */
+extern Blog_t * vlanctl_deactivate( uint32_t key,  vlanctl_bind_client_t client );
+
+#endif /* CONFIG_BLOG */
+
+#endif /* ! _VLANCTL_BIND_ */
diff --git a/include/net/bcm_addrconf.h b/include/net/bcm_addrconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..a70385f1d4f88d22893409952b8030e74f6cc08f
--- /dev/null
+++ b/include/net/bcm_addrconf.h
@@ -0,0 +1,64 @@
+/*
+*    Copyright (c) 2003-2019 Broadcom
+*    All Rights Reserved
+*
+<:label-BRCM:2019:DUAL/GPL:standard
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+#ifndef _BCM_ADDRCONF_H
+#define	_BCM_ADDRCONF_H
+
+void ipv6_del_addr(struct inet6_ifaddr *ifp);
+int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
+
+static inline int isULA(const struct in6_addr *addr)
+{
+	__be32 st;
+
+	st = addr->s6_addr32[0];
+
+	/* RFC 4193 */
+	if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
+		return	1;
+	else
+		return	0;
+}
+
+static inline int isSpecialAddr(const struct in6_addr *addr)
+{
+	__be32 st;
+
+	st = addr->s6_addr32[0];
+
+	/* RFC 5156 */
+	if (((st & htonl(0xFFFFFFFF)) == htonl(0x20010db8)) ||
+		((st & htonl(0xFFFFFFF0)) == htonl(0x20010010)))
+		return	1;
+	else
+		return	0;
+}
+
+int addrconf_update_lladdr(struct net_device *dev);
+
+#endif	/* _BCM_ADDRCONF_H */
diff --git a/include/net/bcm_icmp.h b/include/net/bcm_icmp.h
new file mode 100644
index 0000000000000000000000000000000000000000..a32760a92490d38b32b2c5eba9169fbca6920f78
--- /dev/null
+++ b/include/net/bcm_icmp.h
@@ -0,0 +1,64 @@
+/*
+*    Copyright (c) 2003-2019 Broadcom
+*    All Rights Reserved
+*
+<:label-BRCM:2019:DUAL/GPL:standard
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+#ifndef _BCM_ICMP_H
+#define	_BCM_ICMP_H
+
+struct icmp_bxm {
+	struct sk_buff *skb;
+	int offset;
+	int data_len;
+
+	struct {
+		struct icmphdr icmph;
+		__be32	       times[3];
+	} data;
+	int head_len;
+	struct ip_options_data replyopts;
+};
+
+struct icmp_control {
+	bool (*handler)(struct sk_buff *skb);
+	short   error;
+};
+
+extern const struct icmp_control icmp_pointers[];
+
+void icmp_push_reply(struct icmp_bxm *icmp_param,
+		 struct flowi4 *fl4,
+		 struct ipcm_cookie *ipc, struct rtable **rt);
+struct rtable *icmp_route_lookup(struct net *net,
+		 struct flowi4 *fl4,
+		 struct sk_buff *skb_in,
+		 const struct iphdr *iph,
+		 __be32 saddr, u8 tos, u32 mark,
+		 int type, int code,
+		 struct icmp_bxm *param);
+void send_icmp_frag(struct sk_buff *skb_in, int type, int code, __be32 info);
+
+#endif	/* _BCM_ICMP_H */
diff --git a/include/uapi/linux/bcm_atmdev.h b/include/uapi/linux/bcm_atmdev.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3febf166757817c343d44df38ae82b1d2234ba2
--- /dev/null
+++ b/include/uapi/linux/bcm_atmdev.h
@@ -0,0 +1,41 @@
+#ifndef __UAPI_BCM_ATMDEV_H__
+#define __UAPI_BCM_ATMDEV_H__
+/*
+<:copyright-BRCM:2019:DUAL/GPL:standard 
+
+   Copyright (c) 2019 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/ 
+
+//#define ATM_EXTBACKENDIF        _IOW('a',ATMIOC_SPECIAL+6,atm_backend_t)
+//#define ATM_SETEXTFILT          _IOW('a',ATMIOC_SPECIAL+7,atm_backend_t)
+
+#define ATM_BACKEND_RT2684             3  /* Routed RFC1483/2684 */
+#define ATM_BACKEND_BR2684_BCM         4  /* Bridged RFC1483/2684 uses Broadcom ATMAPI*/
+#define ATM_BACKEND_PPP_BCM            5  /* PPPoA uses Broadcom bcmxtmrt driver */
+#define ATM_BACKEND_PPP_BCM_DISCONN    6  /* PPPoA LCP disconnect */
+#define ATM_BACKEND_PPP_BCM_CLOSE_DEV  7  /* PPPoA close device */
+
+#endif  //__UAPI_BCM_ATMDEV_H__
diff --git a/include/uapi/linux/bcm_colors.h b/include/uapi/linux/bcm_colors.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8f913e505f905dc7c157dc1aab45fad12210456
--- /dev/null
+++ b/include/uapi/linux/bcm_colors.h
@@ -0,0 +1,93 @@
+/* 
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ * 
+ *    Copyright (c) 2016 Broadcom 
+ *    All Rights Reserved
+ * 
+ * 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.
+ * 
+ * Not withstanding 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.
+ * 
+ * :>
+ */
+
+/*----------------------------------------------------------------------*
+ * NOTE: FOR USERSPACE USERS:
+ *----------------------------------------------------------------------*
+ *ALL USERSPACE DEVELOPERS MUST INCLUDE THIS FILE IN THEIR APPLICATIONS.
+ *
+ * EXAMPLE:
+ *     #include <bcm_local_kernel_include/linux/bcm_colors.h>  
+ *----------------------------------------------------------------------*/
+
+/*
+ *--------------------------------------------------------------------------
+ * Color encodings for console printing:
+ *
+ * This feature is controlled from top level make menuconfig, under
+ * Debug Selection>Enable Colorized Prints
+ *
+ * You may select a color specific to your subsystem by:
+ *  #define CLRsys CLRg
+ *
+ * Usage:  PRINT(CLRr "format" CLRNL);
+ *--------------------------------------------------------------------------
+ */
+
+#ifndef __UAPI_BCM_COLORS_H__
+#define __UAPI_BCM_COLORS_H__
+
+#ifdef CONFIG_BCM_COLORIZE_PRINTS
+#define BCMCOLOR(clr_code)     clr_code
+#else
+#define BCMCOLOR(clr_code)
+#endif
+
+/* White background */
+#define CLRr             BCMCOLOR("\e[0;31m")       /* red              */
+#define CLRg             BCMCOLOR("\e[0;32m")       /* green            */
+#define CLRy             BCMCOLOR("\e[0;33m")       /* yellow           */
+#define CLRb             BCMCOLOR("\e[0;34m")       /* blue             */
+#define CLRm             BCMCOLOR("\e[0;35m")       /* magenta          */
+#define CLRc             BCMCOLOR("\e[0;36m")       /* cyan             */
+
+/* blacK "inverted" background */
+#define CLRrk            BCMCOLOR("\e[0;31;40m")    /* red     on blacK */
+#define CLRgk            BCMCOLOR("\e[0;32;40m")    /* green   on blacK */
+#define CLRyk            BCMCOLOR("\e[0;33;40m")    /* yellow  on blacK */
+#define CLRmk            BCMCOLOR("\e[0;35;40m")    /* magenta on blacK */
+#define CLRck            BCMCOLOR("\e[0;36;40m")    /* cyan    on blacK */
+#define CLRwk            BCMCOLOR("\e[0;37;40m")    /* whilte  on blacK */
+
+/* Colored background */
+#define CLRcb            BCMCOLOR("\e[0;36;44m")    /* cyan    on blue  */
+#define CLRyr            BCMCOLOR("\e[0;33;41m")    /* yellow  on red   */
+#define CLRym            BCMCOLOR("\e[0;33;45m")    /* yellow  on magen */
+
+/* Generic foreground colors */
+#define CLRhigh          CLRm                    /* Highlight color  */
+#define CLRbold          CLRcb                   /* Bold      color  */
+#define CLRbold2         CLRym                   /* Bold2     color  */
+#define CLRerr           CLRyr                   /* Error     color  */
+#define CLRnorm          BCMCOLOR("\e[0m")       /* Normal    color  */
+#define CLRnl            CLRnorm "\n"            /* Normal + newline */
+
+/* Each subsystem may define CLRsys */
+
+#endif /* __BCM_COLORS_H__ */
diff --git a/include/uapi/linux/bcm_if_ether.h b/include/uapi/linux/bcm_if_ether.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbba398bee434be0df70dc4cb42d80939d8f951a
--- /dev/null
+++ b/include/uapi/linux/bcm_if_ether.h
@@ -0,0 +1,37 @@
+/*
+<:copyright-BRCM:2019:DUAL/GPL:standard 
+
+   Copyright (c) 2019 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/ 
+
+#ifndef _LINUX_BCM_IF_ETHER_H
+#define _LINUX_BCM_IF_ETHER_H
+
+#define ETH_P_8021AG	0x8902	/* 802.1ag Connectivity Fault Mgmt */
+#define	ETH_P_8023AH	0x8809	/* 802.3ah Ethernet OAM */
+
+
+#endif
diff --git a/include/uapi/linux/bcm_maclimit.h b/include/uapi/linux/bcm_maclimit.h
new file mode 100644
index 0000000000000000000000000000000000000000..dfe0a63e840f380f257889cba81c1d9c78d80a43
--- /dev/null
+++ b/include/uapi/linux/bcm_maclimit.h
@@ -0,0 +1,41 @@
+#ifndef __BCM_MACLIMIT_H_INCLUDED__
+#define __BCM_MACLIMIT_H_INCLUDED__
+/*
+<:copyright-BRCM:2020:DUAL/GPL:standard
+
+   Copyright (c) 2020 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+struct mac_limit
+{
+    unsigned int enable;           //dev mac limit enabled
+    unsigned int max;              //dev and lower-devs max allow
+    unsigned int max_zero_drop;    //max zero value is drop or not
+    unsigned int drop_count;       //exceed max drop count
+    unsigned int min;              //dev mac learning min commit
+    unsigned int reserve;          //reserved for lower-devs' min
+    unsigned int learning_count;   //dev and lower-devs learning count
+};
+#endif
\ No newline at end of file
diff --git a/include/uapi/linux/bcm_netlink.h b/include/uapi/linux/bcm_netlink.h
new file mode 100644
index 0000000000000000000000000000000000000000..6edb055b020ceef57db1703958c2cfd503368668
--- /dev/null
+++ b/include/uapi/linux/bcm_netlink.h
@@ -0,0 +1,45 @@
+#ifndef __BCM_NETLINK_H_INCLUDED__
+#define __BCM_NETLINK_H_INCLUDED__
+/*
+<:copyright-BRCM:2019:DUAL/GPL:standard 
+
+   Copyright (c) 2019 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+#define NETLINK_DPI		27	/* dpicore driver */
+#define NETLINK_DPI_QOS		28	/* DPI QoS */
+#define NETLINK_IGSC		29	/* for WIFI multicast igs sdb listing */
+#define NETLINK_BCM_MCAST	30	/* for multicast */
+#define NETLINK_WLCSM		31	/* for brcm wireless cfg[nvram]/statics/management extention */
+
+/* Note that MAX netlink message ids is 32. Defined by MAX_LINKS
+ * macro in kernel/linux-<ver>/include/uapi/linux/netlink.h.
+ * Max netlink message ids have been reached and any new
+ * netlink message requirements must look at using NETLINK_GENERIC
+ * with a sub-type
+ */
+
+#endif /* __BCM_NETLINK_H_INCLUDED__ */
diff --git a/include/uapi/linux/bcm_realtime.h b/include/uapi/linux/bcm_realtime.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d462bce7aa64699f3bc7f56ff97bb754094b0fc
--- /dev/null
+++ b/include/uapi/linux/bcm_realtime.h
@@ -0,0 +1,77 @@
+/*
+<:copyright-BRCM:2011:DUAL/GPL:standard
+
+   Copyright (c) 2011 Broadcom 
+   All Rights Reserved
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+#ifndef _BCM_REALTIME_H_
+#define _BCM_REALTIME_H_
+
+/*
+ * This file defines the real time priority levels used by the various
+ * threads in the system.  It is important that all threads coordinate
+ * their priority levels so that the desired effect is achieved.
+ * These priorities are also related cgroups, so check the cgroups
+ * groupings and cpu allocations (if cgroups is enabled).
+ */
+
+/** highest priority threads in the system.
+ *
+ * Threads at this priority require the absolute minium latency.  However,
+ * they should only run very briefly (<2ms per run).
+ * These threads should also run at sched policy FIFO.
+ */
+#define BCM_RTPRIO_HIGH               75
+
+
+/** priority for the voip DSP.
+ *
+ * Note this is not for all voip threads, just the DSP thread.
+ * The other voice threads should be run at the other priorities that are
+ * defined.
+ */
+#define BCM_RTPRIO_VOIPDSP            35
+
+
+/** priority for all data forwarding.
+ *
+ * This is for data and video streaming.  Not clear if we need to split out
+ * sub-categories here such as video, versus web data, versus voice.
+ * Probably need to use cgroups if a system needs to handle many types of
+ * streams.
+ * Threads running at this priority should use sched policy Round-Robin.
+ */
+#define BCM_RTPRIO_DATA                 5
+
+/** priority for all tasks that handle control messages related to data path.
+ *
+ * ex: bpm tasl handling allocation/free of data buffers.
+ * Threads running at this priority should use sched policy Round-Robin.
+ */
+#define BCM_RTPRIO_DATA_CONTROL         10
+
+#endif /* _BCM_REALTIME_H_ */
+
diff --git a/include/uapi/linux/netfilter/nf_conntrack_pt.h b/include/uapi/linux/netfilter/nf_conntrack_pt.h
new file mode 100644
index 0000000000000000000000000000000000000000..108cf9825a5677b99bab1c9721b121466fe28d9a
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_pt.h
@@ -0,0 +1,9 @@
+#ifndef _NF_CONNTRACK_PT_H
+#define _NF_CONNTRACK_PT_H
+/* PT tracking. */
+#define PT_MAX_ENTRIES	100
+#define PT_MAX_PORTS	1000
+#define PT_MAX_EXPECTED	255
+#define PT_TIMEOUT	180
+
+#endif /* _NF_CONNTRACK_PT_H */
diff --git a/include/uapi/linux/netfilter/xt_blog.h b/include/uapi/linux/netfilter/xt_blog.h
new file mode 100755
index 0000000000000000000000000000000000000000..b7914fd3c64ff1145670c24c986c9b45d798d4e1
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_blog.h
@@ -0,0 +1,11 @@
+#ifndef _XT_BLOG_H
+#define _XT_BLOG_H
+
+#include <linux/types.h>
+
+struct xt_blog {
+	__u8	tcp_pure_ack;
+	__u8	invert;
+};
+
+#endif /*_XT_BLOG_H*/
diff --git a/include/uapi/linux/netfilter/xt_flowlabel.h b/include/uapi/linux/netfilter/xt_flowlabel.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3df198dcd684fdbdc8a6851ec35c67c46eb1f67
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_flowlabel.h
@@ -0,0 +1,52 @@
+/*
+*    Copyright (c) 2003-2019 Broadcom
+*    All Rights Reserved
+*
+<:label-BRCM:2019:DUAL/GPL:standard
+
+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.
+
+Not withstanding 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.
+
+:>
+*/
+
+
+/* IP tables module for matching the value of the IPv6 flowlabel field
+ *
+ * BRCM, Feb, 1. 2019.
+ */
+
+
+#ifndef _XT_FLOWLABEL_H
+#define _XT_FLOWLABEL_H
+
+#include <linux/types.h>
+
+#define XT_FLOWLABEL_MAX	cpu_to_be32(0x000FFFFF)
+
+
+/* match info */
+struct xt_flowlabel_info {
+	__be32 flowlabel;
+	__u8 invert;
+};
+
+
+#endif /* _XT_FLOWLABEL_H */
diff --git a/include/uapi/linux/netfilter/xt_mac_extend.h b/include/uapi/linux/netfilter/xt_mac_extend.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fbbc87b27c2f4cc07574a53a606e054dd8740bc
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_mac_extend.h
@@ -0,0 +1,15 @@
+#ifndef _XT_MAC_EXTEND_H
+#define _XT_MAC_EXTEND_H
+
+/* extend from xt_mac.h for MAC address extend match operations,
+ * i.e, MAC/mask. 
+ * BRCM, Jan, 31. 2019.
+ */
+
+
+struct xt_mac_info_extend {
+    unsigned char srcaddr[ETH_ALEN];
+    unsigned char msk[ETH_ALEN];
+    int invert;
+};
+#endif /*_XT_MAC_EXTEND_H*/
diff --git a/include/uapi/linux/netfilter_bridge/ebt_blog.h b/include/uapi/linux/netfilter_bridge/ebt_blog.h
new file mode 100755
index 0000000000000000000000000000000000000000..181f17c3ce575a03d16dfb8abec7be8ec692c797
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_blog.h
@@ -0,0 +1,12 @@
+#ifndef __LINUX_BRIDGE_EBT_BLOG_H
+#define __LINUX_BRIDGE_EBT_BLOG_H
+
+#include <linux/types.h>
+
+struct ebt_blog_info
+{
+	__u8	tcp_pure_ack;
+	__u8	invert;
+};
+
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h b/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e5099c7c2a58e43dd5c3b37db1e93b60b910f3d
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h
@@ -0,0 +1,22 @@
+#ifndef __LINUX_BRIDGE_EBT_FTOS_T_H
+#define __LINUX_BRIDGE_EBT_FTOS_T_H
+
+struct ebt_ftos_t_info
+{
+    int           ftos_set;
+	unsigned char ftos;
+	// EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_FTOS_TARGET "ftos"
+
+#define FTOS_TARGET       0x01
+#define FTOS_SETFTOS      0x02
+#define FTOS_WMMFTOS      0x04
+#define FTOS_8021QFTOS    0x08
+
+#define DSCP_MASK_SHIFT   5
+#define PRIO_LOC_NFMARK   0
+#define PRIO_LOC_NFMASK   7
+
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h b/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h
new file mode 100644
index 0000000000000000000000000000000000000000..c18cd4cd1641613fcf950d1bc2e7320f73fa3ddc
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h
@@ -0,0 +1,32 @@
+/*
+ *  ebt_ip6
+ *
+ *	Authors:
+ * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
+ * Manohar Castelino <manohar.r.castelino@intel.com>
+ *
+ *  Jan 11, 2008
+ *
+ *  Extend by Broadcom at Jan 31, 2019
+ */
+#ifndef __LINUX_BRIDGE_EBT_IP6_EXTEND_H
+#define __LINUX_BRIDGE_EBT_IP6_EXTEND_H
+
+#include <linux/types.h>
+
+#define EBT_IP6_TCLASS_EXTEND 0x01
+#define EBT_IP6_FLOWLABEL_EXTEND 0x02
+
+#define EBT_IP6_MASK_EXTEND (EBT_IP6_TCLASS_EXTEND | EBT_IP6_FLOWLABEL_EXTEND)
+#define EBT_IP6_MATCH_EXTEND "ip6-extend"
+
+/* the same values are used for the invflags */
+struct ebt_ip6_extend_info {
+	__u8  flow_lbl[3];
+	__u8  tclass[2];
+	__u8  tclassmsk;
+	__u8  bitmask;
+	__u8  invflags;
+};
+
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h b/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2bb057172bc53d84802ff2b60d6d52f3a0aa2bb
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h
@@ -0,0 +1,37 @@
+/*
+ *  ebt_ip
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ *  Changes:
+ *    added ip-sport and ip-dport
+ *    Innominate Security Technologies AG <mhopf@innominate.com>
+ *    September, 2002
+ *
+ *  Extend by Broadcom at Jan 31, 2019
+ */
+#ifndef __LINUX_BRIDGE_EBT_IP_EXTEND_H
+#define __LINUX_BRIDGE_EBT_IP_EXTEND_H
+
+#include <linux/types.h>
+
+
+#define EBT_IP_TOS_EXTEND	0x01
+#define EBT_IP_DSCP_EXTEND	0x02
+
+#define EBT_IP_MASK_EXTEND (EBT_IP_TOS_EXTEND | EBT_IP_DSCP_EXTEND)
+#define EBT_IP_MATCH_EXTEND "ip-extend"
+
+/* the same values are used for the invflags */
+struct ebt_ip_extend_info {
+	__u8  tos[2];
+	__u8  tosmask;
+	__u8  dscp;
+	__u8  bitmask;
+	__u8  invflags;
+};
+
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_qos_map.h b/include/uapi/linux/netfilter_bridge/ebt_qos_map.h
new file mode 100644
index 0000000000000000000000000000000000000000..d45d7ff31d08cdf1c23478a45b908bbef2475e9a
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_qos_map.h
@@ -0,0 +1,9 @@
+#ifndef __LINUX_QOS_MAP_H
+#define __LINUX_QOS_MAP_H
+
+struct ebt_qos_map_info
+{
+	int dscp2pbit; 
+	int dscp2q;
+};
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_reject.h b/include/uapi/linux/netfilter_bridge/ebt_reject.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b55769ef4836f5116c029f482dff1c344128646
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_reject.h
@@ -0,0 +1,14 @@
+#if defined(CONFIG_BCM_KF_NETFILTER)
+#ifndef __LINUX_BRIDGE_EBT_REJECT_H
+#define __LINUX_BRIDGE_EBT_REJECT_H
+
+enum ebt_reject_with {
+	EBT_ICMP6_POLICY_FAIL
+};
+
+struct ebt_reject_info {
+	int	with;	/* reject type */
+};
+
+#endif
+#endif
diff --git a/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h b/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h
new file mode 100644
index 0000000000000000000000000000000000000000..13fdff40284a805d73c3d850b4c975cdd5e35c35
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h
@@ -0,0 +1,45 @@
+#ifndef __LINUX_BRIDGE_EBT_SKBVLAN_H
+#define __LINUX_BRIDGE_EBT_SKBVLAN_H
+
+#include <linux/types.h>
+
+#define EBT_SKBVLAN_ID	0x0001
+#define EBT_SKBVLAN_PRIO	0x0002
+#define EBT_SKBVLAN_ENCAP	0x0004
+#define EBT_SKBVLAN_VLAN_TAG_0	0x0008
+#define EBT_SKBVLAN_VLAN_TAG_1   0x0010
+#define EBT_SKBVLAN_VLAN_TAG_2	0x0020
+#define EBT_SKBVLAN_VLAN_TAG_3	0x0040
+#define EBT_SKBVLAN_VLAN_TPID_0	0x0080
+#define EBT_SKBVLAN_VLAN_TPID_1	0x0100
+#define EBT_SKBVLAN_MASK (EBT_SKBVLAN_ID | EBT_SKBVLAN_PRIO | EBT_SKBVLAN_ENCAP | \
+		EBT_SKBVLAN_VLAN_TAG_0 | EBT_SKBVLAN_VLAN_TAG_1 | EBT_SKBVLAN_VLAN_TAG_2 | \
+		EBT_SKBVLAN_VLAN_TAG_3 |EBT_SKBVLAN_VLAN_TPID_0 | EBT_SKBVLAN_VLAN_TPID_1)
+
+
+
+#define EBT_SKBVLAN_MATCH "skbvlan"
+
+struct ebt_skbvlan_m_info {
+	__u16 id;		/* VLAN ID {1-4095} */
+	__u8 prio;		/* VLAN User Priority {0-7} */
+	__be16 encap;		/* VLAN Encapsulated frame code {0-65535} */
+	__u16 bitmask;		/* Args bitmask bit 1=1 - ID arg,
+				   bit 2=1 User-Priority arg, bit 3=1 encap*/
+	__u16 invflags;		/* Inverse bitmask  bit 1=1 - inversed ID arg, 
+				   bit 2=1 - inversed Pirority arg */
+	__be32 vlantag0[2];
+	__be32 vlanmask0;
+	__be32 vlantag1[2];
+	__be32 vlanmask1;
+	__be32 vlantag2[2];
+	__be32 vlanmask2;
+	__be32 vlantag3[2];
+	__be32 vlanmask3;
+	__be16 vlantpid0;
+	__be16 vlantpid1;
+};
+
+
+#endif /* __LINUX_BRIDGE_EBT_SKBVLAN_H */
+
diff --git a/include/uapi/linux/netfilter_bridge/ebt_time.h b/include/uapi/linux/netfilter_bridge/ebt_time.h
new file mode 100644
index 0000000000000000000000000000000000000000..f47b531d7b9b8322d2fa71527c37950a054ec23c
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_time.h
@@ -0,0 +1,14 @@
+#ifndef __LINUX_BRIDGE_EBT_TIME_H
+#define __LINUX_BRIDGE_EBT_TIME_H
+
+
+struct ebt_time_info {
+	u_int8_t  days_match;   /* 1 bit per day. -SMTWTFS                      */
+	u_int16_t time_start;   /* 0 < time_start < 23*60+59 = 1439             */
+	u_int16_t time_stop;    /* 0:0 < time_stat < 23:59                      */
+	u_int8_t  kerneltime;   /* ignore skb time (and use kerneltime) or not. */
+};
+
+#define EBT_TIME_MATCH "time"
+
+#endif /* __LINUX_BRIDGE_EBT_TIME_H */
diff --git a/include/uapi/linux/netfilter_bridge/ebt_u32.h b/include/uapi/linux/netfilter_bridge/ebt_u32.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cd1c043b80455d440e390e280d33ca3f70266fa
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_u32.h
@@ -0,0 +1,55 @@
+/*
+ *  ebt_u32
+ *
+ *	Authors:
+ *  extend by Broadcom at Jan 24, 2019
+ *
+ *
+ */
+
+#ifndef __LINUX_BRIDGE_EBT_U32_H
+#define __LINUX_BRIDGE_EBT_U32_H
+
+#include <linux/types.h>
+
+enum ebt_u32_ops {
+	EBT_U32_AND,
+	EBT_U32_LEFTSH,
+	EBT_U32_RIGHTSH,
+	EBT_U32_AT,
+};
+
+struct ebt_u32_location_element {
+	__u32 number;
+	__u8 nextop;
+};
+
+struct ebt_u32_value_element {
+	__u32 min;
+	__u32 max;
+};
+
+/*
+ * Any way to allow for an arbitrary number of elements?
+ * For now, I settle with a limit of 10 each.
+ */
+#define EBT_U32_MAXSIZE 10
+
+#define EBT_U32_MATCH "u32"
+
+
+struct ebt_u32_test {
+	struct ebt_u32_location_element location[EBT_U32_MAXSIZE+1];
+	struct ebt_u32_value_element value[EBT_U32_MAXSIZE+1];
+	__u8 nnums;
+	__u8 nvalues;
+};
+
+struct ebt_u32_info {
+	struct ebt_u32_test tests[EBT_U32_MAXSIZE+1];
+	__u8 ntests;
+	__u8 invert;
+};
+
+#endif
+
diff --git a/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h b/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd803cc10aaeaa3277bd0579d4f6c8dee61fd610
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h
@@ -0,0 +1,13 @@
+#ifndef __EBT_VTAG_T_H__
+#define __EBT_VTAG_T_H__
+
+
+struct ebt_vtag_t_info
+{
+	int vtag; 
+	/* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */
+	int target;
+};
+
+#endif //__EBT_VTAG_T_H__
+
diff --git a/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h b/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h
new file mode 100644
index 0000000000000000000000000000000000000000..629f39c58a65950b51b61d849e9555d86fff9a2f
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h
@@ -0,0 +1,27 @@
+#ifndef __LINUX_BRIDGE_EBT_MARK_T_H
+#define __LINUX_BRIDGE_EBT_MARK_T_H
+
+#define WMM_MARK_DSCP		1
+#define WMM_MARK_8021D		2
+
+#define WMM_MARK_DSCP_STR	"dscp"
+#define WMM_MARK_8021D_STR	"vlan"
+
+#define PRIO_LOC_NFMARK		0
+#define PRIO_LOC_NFMASK		7	
+
+#define WMM_DSCP_MASK_SHIFT	5
+#define WMM_MARK_VALUE_NONE	-1
+
+
+struct ebt_wmm_mark_t_info
+{
+	int mark; 
+	int markpos;
+	int markset;
+	/* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */
+	int target;
+};
+#define EBT_WMM_MARK_TARGET "wmm-mark"
+
+#endif