Update base to get info about supported filtering features.

Add TID table that holds filter state and add filter specification
that provide a skeleton to add LE-TCAM (Maskfull) and Hash (Maskless)
T5 filtering capabilities.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy at chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras at chelsio.com>
---
 drivers/net/cxgbe/Makefile              |   1 +
 drivers/net/cxgbe/base/adapter.h        |   7 +
 drivers/net/cxgbe/base/t4fw_interface.h |  10 ++
 drivers/net/cxgbe/cxgbe_filter.h        | 231 ++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe_main.c          | 138 +++++++++++++++++++
 drivers/net/cxgbe/cxgbe_ofld.h          |  86 ++++++++++++
 6 files changed, 473 insertions(+)
 create mode 100644 drivers/net/cxgbe/cxgbe_filter.h
 create mode 100644 drivers/net/cxgbe/cxgbe_ofld.h

diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 0711976..895c767 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -83,5 +83,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t4_hw.c
 DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_eal lib/librte_ether
 DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_mempool lib/librte_mbuf
 DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_net lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_sched

 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index a5225c0..51896b1 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -40,6 +40,7 @@

 #include "cxgbe_compat.h"
 #include "t4_regs_values.h"
+#include "cxgbe_ofld.h"

 enum {
        MAX_ETH_QSETS = 64,           /* # of Ethernet Tx/Rx queue sets */
@@ -319,6 +320,12 @@ struct adapter {
        unsigned int pf;       /* associated physical function id */

        int use_unpacked_mode; /* unpacked rx mode state */
+
+       unsigned int clipt_start; /* CLIP table start */
+       unsigned int clipt_end;   /* CLIP table end */
+       unsigned int l2t_start;   /* Layer 2 table start */
+       unsigned int l2t_end;     /* Layer 2 table end */
+       struct tid_info tids;     /* Info used to access TID related tables */
 };

 #define CXGBE_PCI_REG(reg) (*((volatile uint32_t *)(reg)))
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h 
b/drivers/net/cxgbe/base/t4fw_interface.h
index 74f19fe..8286ca1 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -394,6 +394,10 @@ enum fw_params_mnem {
 enum fw_params_param_dev {
        FW_PARAMS_PARAM_DEV_CCLK        = 0x00, /* chip core clock in khz */
        FW_PARAMS_PARAM_DEV_PORTVEC     = 0x01, /* the port vector */
+       FW_PARAMS_PARAM_DEV_NTID        = 0x02, /* reads the number of TIDs
+                                                * allocated by the device's
+                                                * Lookup Engine
+                                                */
        FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
 };

@@ -401,6 +405,12 @@ enum fw_params_param_dev {
  * physical and virtual function parameters
  */
 enum fw_params_param_pfvf {
+       FW_PARAMS_PARAM_PFVF_CLIP_START = 0x03,
+       FW_PARAMS_PARAM_PFVF_CLIP_END = 0x04,
+       FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,
+       FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,
+       FW_PARAMS_PARAM_PFVF_L2T_START = 0x13,
+       FW_PARAMS_PARAM_PFVF_L2T_END = 0x14,
        FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31
 };

diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
new file mode 100644
index 0000000..a746d13
--- /dev/null
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -0,0 +1,231 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015-2016 Chelsio Communications.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Chelsio Communications nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CXGBE_FILTER_H_
+#define _CXGBE_FILTER_H_
+
+/*
+ * Defined bit width of user definable filter tuples
+ */
+#define ETHTYPE_BITWIDTH 16
+#define FRAG_BITWIDTH 1
+#define MACIDX_BITWIDTH 9
+#define FCOE_BITWIDTH 1
+#define IPORT_BITWIDTH 3
+#define MATCHTYPE_BITWIDTH 3
+#define PROTO_BITWIDTH 8
+#define TOS_BITWIDTH 8
+#define PF_BITWIDTH 8
+#define VF_BITWIDTH 8
+#define IVLAN_BITWIDTH 16
+#define OVLAN_BITWIDTH 16
+
+/*
+ * Filter matching rules.  These consist of a set of ingress packet field
+ * (value, mask) tuples.  The associated ingress packet field matches the
+ * tuple when ((field & mask) == value).  (Thus a wildcard "don't care" field
+ * rule can be constructed by specifying a tuple of (0, 0).)  A filter rule
+ * matches an ingress packet when all of the individual individual field
+ * matching rules are true.
+ *
+ * Partial field masks are always valid, however, while it may be easy to
+ * understand their meanings for some fields (e.g. IP address to match a
+ * subnet), for others making sensible partial masks is less intuitive (e.g.
+ * MPS match type) ...
+ */
+struct ch_filter_tuple {
+       /*
+        * Compressed header matching field rules.  The TP_VLAN_PRI_MAP
+        * register selects which of these fields will participate in the
+        * filter match rules -- up to a maximum of 36 bits.  Because
+        * TP_VLAN_PRI_MAP is a global register, all filters must use the same
+        * set of fields.
+        */
+       uint32_t ethtype:ETHTYPE_BITWIDTH;      /* Ethernet type */
+       uint32_t frag:FRAG_BITWIDTH;            /* IP fragmentation header */
+       uint32_t ivlan_vld:1;                   /* inner VLAN valid */
+       uint32_t ovlan_vld:1;                   /* outer VLAN valid */
+       uint32_t pfvf_vld:1;                    /* PF/VF valid */
+       uint32_t macidx:MACIDX_BITWIDTH;        /* exact match MAC index */
+       uint32_t fcoe:FCOE_BITWIDTH;            /* FCoE packet */
+       uint32_t iport:IPORT_BITWIDTH;          /* ingress port */
+       uint32_t matchtype:MATCHTYPE_BITWIDTH;  /* MPS match type */
+       uint32_t proto:PROTO_BITWIDTH;          /* protocol type */
+       uint32_t tos:TOS_BITWIDTH;              /* TOS/Traffic Type */
+       uint32_t pf:PF_BITWIDTH;                /* PCI-E PF ID */
+       uint32_t vf:VF_BITWIDTH;                /* PCI-E VF ID */
+       uint32_t ivlan:IVLAN_BITWIDTH;          /* inner VLAN */
+       uint32_t ovlan:OVLAN_BITWIDTH;          /* outer VLAN */
+
+       /*
+        * Uncompressed header matching field rules.  These are always
+        * available for field rules.
+        */
+       uint8_t lip[16];        /* local IP address (IPv4 in [3:0]) */
+       uint8_t fip[16];        /* foreign IP address (IPv4 in [3:0]) */
+       uint16_t lport;         /* local port */
+       uint16_t fport;         /* foreign port */
+
+       /* reservations for future additions */
+       uint8_t rsvd[12];
+};
+
+/*
+ * Filter specification
+ */
+struct ch_filter_specification {
+       /* Administrative fields for filter. */
+       uint32_t hitcnts:1;     /* count filter hits in TCB */
+       uint32_t prio:1;        /* filter has priority over active/server */
+
+       /*
+        * Fundamental filter typing.  This is the one element of filter
+        * matching that doesn't exist as a (value, mask) tuple.
+        */
+       uint32_t type:1;        /* 0 => IPv4, 1 => IPv6 */
+       uint32_t cap:1;         /* 0 => LE-TCAM, 1 => Hash */
+
+       /*
+        * Packet dispatch information.  Ingress packets which match the
+        * filter rules will be dropped, passed to the host or switched back
+        * out as egress packets.
+        */
+       uint32_t action:2;      /* drop, pass, switch */
+
+       uint32_t rpttid:1;      /* report TID in RSS hash field */
+
+       uint32_t dirsteer:1;    /* 0 => RSS, 1 => steer to iq */
+       uint32_t iq:10;         /* ingress queue */
+
+       uint32_t maskhash:1;    /* dirsteer=0: store RSS hash in TCB */
+       uint32_t dirsteerhash:1;/* dirsteer=1: 0 => TCB contains RSS hash */
+                               /*             1 => TCB contains IQ ID */
+
+       /*
+        * Switch proxy/rewrite fields.  An ingress packet which matches a
+        * filter with "switch" set will be looped back out as an egress
+        * packet -- potentially with some Ethernet header rewriting.
+        */
+       uint32_t eport:2;       /* egress port to switch packet out */
+       uint32_t newdmac:1;     /* rewrite destination MAC address */
+       uint32_t newsmac:1;     /* rewrite source MAC address */
+       uint32_t swapmac:1;     /* swap SMAC/DMAC for loopback packet */
+       uint32_t newvlan:2;     /* rewrite VLAN Tag */
+       uint32_t nat_mode:3;    /* specify NAT operation mode */
+       uint32_t nat_flag_chk:1;/* check TCP flags before NAT'ing */
+       uint32_t nat_seq_chk;   /* sequence value to use for NAT check*/
+       uint8_t dmac[ETHER_ADDR_LEN];   /* new destination MAC address */
+       uint8_t smac[ETHER_ADDR_LEN];   /* new source MAC address */
+       uint16_t vlan;          /* VLAN Tag to insert */
+
+       uint8_t nat_lip[16];    /* local IP to use after NAT'ing */
+       uint8_t nat_fip[16];    /* foreign IP to use after NAT'ing */
+       uint16_t nat_lport;     /* local port to use after NAT'ing */
+       uint16_t nat_fport;     /* foreign port to use after NAT'ing */
+
+       /* reservation for future additions */
+       uint8_t rsvd[6];
+
+       /* Filter rule value/mask pairs. */
+       struct ch_filter_tuple val;
+       struct ch_filter_tuple mask;
+};
+
+enum {
+       FILTER_PASS = 0,        /* default */
+       FILTER_DROP,
+       FILTER_SWITCH
+};
+
+enum {
+       VLAN_NOCHANGE = 0,      /* default */
+       VLAN_REMOVE,
+       VLAN_INSERT,
+       VLAN_REWRITE
+};
+
+enum {
+       NAT_MODE_NONE = 0,      /* No NAT performed */
+       NAT_MODE_DIP,           /* NAT on Dst IP */
+       NAT_MODE_DIP_DP,        /* NAT on Dst IP, Dst Port */
+       NAT_MODE_DIP_DP_SIP,    /* NAT on Dst IP, Dst Port and Src IP */
+       NAT_MODE_DIP_DP_SP,     /* NAT on Dst IP, Dst Port and Src Port */
+       NAT_MODE_SIP_SP,        /* NAT on Src IP and Src Port */
+       NAT_MODE_DIP_SIP_SP,    /* NAT on Dst IP, Src IP and Src Port */
+       NAT_MODE_ALL            /* NAT on entire 4-tuple */
+};
+
+enum filter_type {
+       FILTER_TYPE_IPV4 = 0,
+       FILTER_TYPE_IPV6,
+};
+
+struct t4_completion {
+       unsigned int done;       /* completion done (0 - No, 1 - Yes) */
+       rte_spinlock_t lock;     /* completion lock */
+};
+
+/*
+ * Filter operation context to allow callers of cxgbe_set_filter() and
+ * cxgbe_del_filter() to wait for an asynchronous completion.
+ */
+struct filter_ctx {
+       struct t4_completion completion; /* completion rendezvous */
+       int result;                      /* result of operation */
+       u32 tid;                         /* to store tid of hash filter */
+};
+
+/*
+ * Host shadow copy of ingress filter entry.  This is in host native format
+ * and doesn't match the ordering or bit order, etc. of the hardware or the
+ * firmware command.
+ */
+struct filter_entry {
+       /*
+        * Administrative fields for filter.
+        */
+       u32 valid:1;                /* filter allocated and valid */
+       u32 locked:1;               /* filter is administratively locked */
+       u32 pending:1;              /* filter action is pending FW reply */
+       struct filter_ctx *ctx;     /* caller's completion hook */
+       struct rte_eth_dev *dev;    /* Port's rte eth device */
+
+       /* This will store the actual tid */
+       u32 tid;
+
+       /*
+        * The filter itself.
+        */
+       struct ch_filter_specification fs;
+};
+#endif /* _CXGBE_FILTER_H_ */
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index aff23d0..b116a40 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -67,6 +67,22 @@
 #include "t4_msg.h"
 #include "cxgbe.h"

+/**
+ * Allocate a chunk of memory. The allocated memory is cleared.
+ */
+void *t4_alloc_mem(size_t size)
+{
+       return rte_zmalloc(NULL, size, 0);
+}
+
+/**
+ * Free memory allocated through t4_alloc_mem().
+ */
+void t4_free_mem(void *addr)
+{
+       rte_free(addr);
+}
+
 /*
  * Response queue handler for the FW event queue.
  */
@@ -198,6 +214,78 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, 
unsigned int us,
        return 0;
 }

+/**
+ * Free TID tables.
+ */
+static void tid_free(struct tid_info *t)
+{
+       if (t->tid_tab) {
+               if (t->ftid_bmap)
+                       rte_bitmap_free(t->ftid_bmap);
+
+               if (t->ftid_bmap_array)
+                       t4_os_free(t->ftid_bmap_array);
+
+               t4_os_free(t->tid_tab);
+       }
+
+       memset(t, 0, sizeof(struct tid_info));
+}
+
+/**
+ * Allocate and initialize the TID tables.  Returns 0 on success.
+ */
+static int tid_init(struct tid_info *t)
+{
+       size_t size;
+       unsigned int ftid_bmap_size;
+       unsigned int natids = t->natids;
+       unsigned int max_ftids = t->nftids;
+
+       ftid_bmap_size = rte_bitmap_get_memory_footprint(t->nftids);
+       size = t->ntids * sizeof(*t->tid_tab) +
+              natids * sizeof(*t->atid_tab) +
+              max_ftids * sizeof(*t->ftid_tab);
+
+       t->tid_tab = t4_os_alloc(size);
+       if (!t->tid_tab)
+               return -ENOMEM;
+
+       t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
+       t->ftid_tab = (struct filter_entry *)&t->atid_tab[natids];
+       t->ftid_bmap_array = t4_os_alloc(ftid_bmap_size);
+       if (!t->ftid_bmap_array) {
+               tid_free(t);
+               return -ENOMEM;
+       }
+
+       t4_os_lock_init(&t->atid_lock);
+       t4_os_lock_init(&t->ftid_lock);
+
+       t->afree = NULL;
+       t->atids_in_use = 0;
+       rte_atomic32_init(&t->tids_in_use);
+       rte_atomic32_set(&t->tids_in_use, 0);
+       rte_atomic32_init(&t->conns_in_use);
+       rte_atomic32_set(&t->conns_in_use, 0);
+
+       /* Setup the free list for atid_tab and clear the stid bitmap. */
+       if (natids) {
+               while (--natids)
+                       t->atid_tab[natids - 1].next = &t->atid_tab[natids];
+               t->afree = t->atid_tab;
+       }
+
+       t->ftid_bmap = rte_bitmap_init(t->nftids, t->ftid_bmap_array,
+                                      ftid_bmap_size);
+       if (!t->ftid_bmap) {
+               tid_free(t);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static inline bool is_x_1g_port(const struct link_config *lc)
 {
        return ((lc->supported & FW_PORT_CAP_SPEED_1G) != 0);
@@ -598,6 +686,7 @@ bye:

 static int adap_init0(struct adapter *adap)
 {
+       struct fw_caps_config_cmd caps_cmd;
        int ret = 0;
        u32 v, port_vec;
        enum dev_state state;
@@ -729,6 +818,48 @@ static int adap_init0(struct adapter *adap)
         V_FW_PARAMS_PARAM_Y(0) | \
         V_FW_PARAMS_PARAM_Z(0))

+       params[0] = FW_PARAM_PFVF(L2T_START);
+       params[1] = FW_PARAM_PFVF(L2T_END);
+       params[2] = FW_PARAM_PFVF(FILTER_START);
+       params[3] = FW_PARAM_PFVF(FILTER_END);
+       ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 4, params, val);
+       if (ret < 0)
+               goto bye;
+       adap->l2t_start = val[0];
+       adap->l2t_end = val[1];
+       adap->tids.ftid_base = val[2];
+       adap->tids.nftids = val[3] - val[2] + 1;
+
+       params[0] = FW_PARAM_PFVF(CLIP_START);
+       params[1] = FW_PARAM_PFVF(CLIP_END);
+       ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2, params, val);
+       if (ret < 0)
+               goto bye;
+       adap->clipt_start = val[0];
+       adap->clipt_end = val[1];
+
+       /*
+        * Get device capabilities so we can determine what resources we need
+        * to manage.
+        */
+       memset(&caps_cmd, 0, sizeof(caps_cmd));
+       caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+                                    F_FW_CMD_REQUEST | F_FW_CMD_READ);
+       caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
+       ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
+                        &caps_cmd);
+       if (ret < 0)
+               goto bye;
+
+       /* query tid-related parameters */
+       params[0] = FW_PARAM_DEV(NTID);
+       ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
+                             params, val);
+       if (ret < 0)
+               goto bye;
+       adap->tids.ntids = val[0];
+       adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
+
        /* If we're running on newer firmware, let it know that we're
         * prepared to deal with encapsulated CPL messages.  Older
         * firmware won't understand this and we'll just get
@@ -1049,6 +1180,7 @@ void cxgbe_close(struct adapter *adapter)
        int i;

        if (adapter->flags & FULL_INIT_DONE) {
+               tid_free(&adapter->tids);
                t4_intr_disable(adapter);
                t4_sge_tx_monitor_stop(adapter);
                t4_free_sge_resources(adapter);
@@ -1191,6 +1323,12 @@ allocate_mac:

        print_port_info(adapter);

+       if (tid_init(&adapter->tids) < 0) {
+               /* Disable filtering support */
+               dev_warn(adapter, "could not allocate TID table, "
+                        "filter support disabled. Continuing\n");
+       }
+
        err = init_rss(adapter);
        if (err)
                goto out_free;
diff --git a/drivers/net/cxgbe/cxgbe_ofld.h b/drivers/net/cxgbe/cxgbe_ofld.h
new file mode 100644
index 0000000..3bcb648
--- /dev/null
+++ b/drivers/net/cxgbe/cxgbe_ofld.h
@@ -0,0 +1,86 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015-2016 Chelsio Communications.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Chelsio Communications nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CXGBE_OFLD_H_
+#define _CXGBE_OFLD_H_
+
+#include <rte_bitmap.h>
+
+#include "cxgbe_filter.h"
+
+/*
+ * Max # of ATIDs.  The absolute HW max is 16K but we keep it lower.
+ */
+#define MAX_ATIDS 8192U
+
+union aopen_entry {
+       void *data;
+       union aopen_entry *next;
+};
+
+/*
+ * Holds the size, base address, free list start, etc of the TID, filter TID
+ * and active-open TID tables.  The tables themselves are allocated 
dynamically.
+ */
+struct tid_info {
+       void **tid_tab;
+       unsigned int ntids;
+
+       unsigned int hash_base;
+
+       union aopen_entry *atid_tab;
+       unsigned int natids;
+
+       struct filter_entry *ftid_tab;  /* Normal filters */
+       struct rte_bitmap *ftid_bmap;
+       uint8_t *ftid_bmap_array;
+       unsigned int nftids;
+       unsigned int ftid_base;
+
+       /*
+        * The following members are accessed R/W so we put them in their own
+        * cache line.
+        */
+       rte_spinlock_t atid_lock __rte_cache_aligned;
+       union aopen_entry *afree;
+       unsigned int atids_in_use;
+
+       /* TIDs in the TCAM */
+       rte_atomic32_t tids_in_use;
+       /* TIDs in the HASH */
+       rte_atomic32_t hash_tids_in_use;
+
+       rte_atomic32_t conns_in_use;
+       rte_spinlock_t ftid_lock;
+};
+#endif /* _CXGBE_OFLD_H_ */
-- 
2.5.3

Reply via email to