get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/41990/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 41990,
    "url": "https://patches.dpdk.org/api/patches/41990/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/c1496bb428f4602aad873edf2a24191a123d1e81.1530295732.git.rahul.lakkireddy@chelsio.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<c1496bb428f4602aad873edf2a24191a123d1e81.1530295732.git.rahul.lakkireddy@chelsio.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/c1496bb428f4602aad873edf2a24191a123d1e81.1530295732.git.rahul.lakkireddy@chelsio.com",
    "date": "2018-06-29T18:12:18",
    "name": "[3/9] net/cxgbe: add Compressed Local IP region",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5fc8822646d439a9ff4d119555129fe0b4058c96",
    "submitter": {
        "id": 241,
        "url": "https://patches.dpdk.org/api/people/241/?format=api",
        "name": "Rahul Lakkireddy",
        "email": "rahul.lakkireddy@chelsio.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/c1496bb428f4602aad873edf2a24191a123d1e81.1530295732.git.rahul.lakkireddy@chelsio.com/mbox/",
    "series": [
        {
            "id": 331,
            "url": "https://patches.dpdk.org/api/series/331/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=331",
            "date": "2018-06-29T18:12:15",
            "name": "net/cxgbe: add support for offloading flows to HASH region",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/331/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/41990/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/41990/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id C4A8B1B91D;\n\tFri, 29 Jun 2018 20:13:42 +0200 (CEST)",
            "from stargate.chelsio.com (stargate.chelsio.com [12.32.117.8])\n\tby dpdk.org (Postfix) with ESMTP id B03181B91D\n\tfor <dev@dpdk.org>; Fri, 29 Jun 2018 20:13:40 +0200 (CEST)",
            "from localhost (scalar.blr.asicdesigners.com [10.193.185.94])\n\tby stargate.chelsio.com (8.13.8/8.13.8) with ESMTP id w5TIDZ95028620; \n\tFri, 29 Jun 2018 11:13:36 -0700"
        ],
        "From": "Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>",
        "To": "dev@dpdk.org",
        "Cc": "shaguna@chelsio.com, indranil@chelsio.com, nirranjan@chelsio.com",
        "Date": "Fri, 29 Jun 2018 23:42:18 +0530",
        "Message-Id": "<c1496bb428f4602aad873edf2a24191a123d1e81.1530295732.git.rahul.lakkireddy@chelsio.com>",
        "X-Mailer": "git-send-email 2.5.3",
        "In-Reply-To": [
            "<cover.1530295732.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1530295732.git.rahul.lakkireddy@chelsio.com>"
        ],
        "References": [
            "<cover.1530295732.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1530295732.git.rahul.lakkireddy@chelsio.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH 3/9] net/cxgbe: add Compressed Local IP region",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Shagun Agrawal <shaguna@chelsio.com>\n\nCLIP region holds destination IPv6 addresses to be matched for\ncorresponding flows. Query firmware for CLIP resources and allocate\ntable to manage them. Also update LE-TCAM to use CLIP to reduce\nnumber of slots needed to offload IPv6 flows.\n\nSigned-off-by: Shagun Agrawal <shaguna@chelsio.com>\nSigned-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>\n---\n drivers/net/cxgbe/Makefile              |   1 +\n drivers/net/cxgbe/base/adapter.h        |  32 ++++++\n drivers/net/cxgbe/base/t4fw_interface.h |  19 ++++\n drivers/net/cxgbe/clip_tbl.c            | 195 ++++++++++++++++++++++++++++++++\n drivers/net/cxgbe/clip_tbl.h            |  31 +++++\n drivers/net/cxgbe/cxgbe_filter.c        |  99 ++++++++++++----\n drivers/net/cxgbe/cxgbe_filter.h        |   1 +\n drivers/net/cxgbe/cxgbe_main.c          |  19 ++++\n 8 files changed, 377 insertions(+), 20 deletions(-)\n create mode 100644 drivers/net/cxgbe/clip_tbl.c\n create mode 100644 drivers/net/cxgbe/clip_tbl.h",
    "diff": "diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile\nindex edc5d8188..5d66c4b3a 100644\n--- a/drivers/net/cxgbe/Makefile\n+++ b/drivers/net/cxgbe/Makefile\n@@ -52,6 +52,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += sge.c\n SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe_filter.c\n SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += cxgbe_flow.c\n SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t4_hw.c\n+SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += clip_tbl.c\n SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t4vf_hw.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h\nindex de46ecfe3..3ed3252e8 100644\n--- a/drivers/net/cxgbe/base/adapter.h\n+++ b/drivers/net/cxgbe/base/adapter.h\n@@ -11,6 +11,7 @@\n #include <rte_bus_pci.h>\n #include <rte_mbuf.h>\n #include <rte_io.h>\n+#include <rte_rwlock.h>\n #include <rte_ethdev.h>\n \n #include \"cxgbe_compat.h\"\n@@ -321,9 +322,40 @@ struct adapter {\n \tint use_unpacked_mode; /* unpacked rx mode state */\n \trte_spinlock_t win0_lock;\n \n+\tunsigned int clipt_start; /* CLIP table start */\n+\tunsigned int clipt_end;   /* CLIP table end */\n+\tstruct clip_tbl *clipt;   /* CLIP table */\n+\n \tstruct tid_info tids;     /* Info used to access TID related tables */\n };\n \n+/**\n+ * t4_os_rwlock_init - initialize rwlock\n+ * @lock: the rwlock\n+ */\n+static inline void t4_os_rwlock_init(rte_rwlock_t *lock)\n+{\n+\trte_rwlock_init(lock);\n+}\n+\n+/**\n+ * t4_os_write_lock - get a write lock\n+ * @lock: the rwlock\n+ */\n+static inline void t4_os_write_lock(rte_rwlock_t *lock)\n+{\n+\trte_rwlock_write_lock(lock);\n+}\n+\n+/**\n+ * t4_os_write_unlock - unlock a write lock\n+ * @lock: the rwlock\n+ */\n+static inline void t4_os_write_unlock(rte_rwlock_t *lock)\n+{\n+\trte_rwlock_write_unlock(lock);\n+}\n+\n /**\n  * ethdev2pinfo - return the port_info structure associated with a rte_eth_dev\n  * @dev: the rte_eth_dev\ndiff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h\nindex 842aa1263..2433bf20c 100644\n--- a/drivers/net/cxgbe/base/t4fw_interface.h\n+++ b/drivers/net/cxgbe/base/t4fw_interface.h\n@@ -333,6 +333,7 @@ enum fw_cmd_opcodes {\n \tFW_RSS_IND_TBL_CMD             = 0x20,\n \tFW_RSS_GLB_CONFIG_CMD\t       = 0x22,\n \tFW_RSS_VI_CONFIG_CMD           = 0x23,\n+\tFW_CLIP_CMD                    = 0x28,\n \tFW_DEBUG_CMD                   = 0x81,\n };\n \n@@ -648,6 +649,8 @@ enum fw_params_param_dev {\n  * physical and virtual function parameters\n  */\n enum fw_params_param_pfvf {\n+\tFW_PARAMS_PARAM_PFVF_CLIP_START = 0x03,\n+\tFW_PARAMS_PARAM_PFVF_CLIP_END = 0x04,\n \tFW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,\n \tFW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,\n \tFW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,\n@@ -2167,6 +2170,22 @@ struct fw_rss_vi_config_cmd {\n \t(((x) >> S_FW_RSS_VI_CONFIG_CMD_UDPEN) & M_FW_RSS_VI_CONFIG_CMD_UDPEN)\n #define F_FW_RSS_VI_CONFIG_CMD_UDPEN\tV_FW_RSS_VI_CONFIG_CMD_UDPEN(1U)\n \n+struct fw_clip_cmd {\n+\t__be32 op_to_write;\n+\t__be32 alloc_to_len16;\n+\t__be64 ip_hi;\n+\t__be64 ip_lo;\n+\t__be32 r4[2];\n+};\n+\n+#define S_FW_CLIP_CMD_ALLOC\t\t31\n+#define V_FW_CLIP_CMD_ALLOC(x)\t\t((x) << S_FW_CLIP_CMD_ALLOC)\n+#define F_FW_CLIP_CMD_ALLOC\t\tV_FW_CLIP_CMD_ALLOC(1U)\n+\n+#define S_FW_CLIP_CMD_FREE\t\t30\n+#define V_FW_CLIP_CMD_FREE(x)\t\t((x) << S_FW_CLIP_CMD_FREE)\n+#define F_FW_CLIP_CMD_FREE\t\tV_FW_CLIP_CMD_FREE(1U)\n+\n /******************************************************************************\n  *   D E B U G   C O M M A N D s\n  ******************************************************/\ndiff --git a/drivers/net/cxgbe/clip_tbl.c b/drivers/net/cxgbe/clip_tbl.c\nnew file mode 100644\nindex 000000000..fa5281cd4\n--- /dev/null\n+++ b/drivers/net/cxgbe/clip_tbl.c\n@@ -0,0 +1,195 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Chelsio Communications.\n+ * All rights reserved.\n+ */\n+\n+#include \"common.h\"\n+#include \"clip_tbl.h\"\n+\n+/**\n+ * Allocate clip entry in HW with associated IPV4/IPv6 address\n+ */\n+static int clip6_get_mbox(const struct rte_eth_dev *dev, const u32 *lip)\n+{\n+\tstruct adapter *adap = ethdev2adap(dev);\n+\tstruct fw_clip_cmd c;\n+\tu64 hi = ((u64)lip[1]) << 32 | lip[0];\n+\tu64 lo = ((u64)lip[3]) << 32 | lip[2];\n+\n+\tmemset(&c, 0, sizeof(c));\n+\tc.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CLIP_CMD) |\n+\t\t\t\t    F_FW_CMD_REQUEST | F_FW_CMD_WRITE);\n+\tc.alloc_to_len16 = cpu_to_be32(F_FW_CLIP_CMD_ALLOC | FW_LEN16(c));\n+\tc.ip_hi = hi;\n+\tc.ip_lo = lo;\n+\treturn t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false);\n+}\n+\n+/**\n+ * Delete clip entry in HW having the associated IPV4/IPV6 address\n+ */\n+static int clip6_release_mbox(const struct rte_eth_dev *dev, const u32 *lip)\n+{\n+\tstruct adapter *adap = ethdev2adap(dev);\n+\tstruct fw_clip_cmd c;\n+\tu64 hi = ((u64)lip[1]) << 32 | lip[0];\n+\tu64 lo = ((u64)lip[3]) << 32 | lip[2];\n+\n+\tmemset(&c, 0, sizeof(c));\n+\tc.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CLIP_CMD) |\n+\t\t\t\t    F_FW_CMD_REQUEST | F_FW_CMD_READ);\n+\tc.alloc_to_len16 = cpu_to_be32(F_FW_CLIP_CMD_FREE | FW_LEN16(c));\n+\tc.ip_hi = hi;\n+\tc.ip_lo = lo;\n+\treturn t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false);\n+}\n+\n+/**\n+ * cxgbe_clip_release - Release associated CLIP entry\n+ * @ce: clip entry to release\n+ *\n+ * Releases ref count and frees up a clip entry from CLIP table\n+ */\n+void cxgbe_clip_release(struct rte_eth_dev *dev, struct clip_entry *ce)\n+{\n+\tint ret;\n+\n+\tt4_os_lock(&ce->lock);\n+\tif (rte_atomic32_dec_and_test(&ce->refcnt)) {\n+\t\tret = clip6_release_mbox(dev, ce->addr);\n+\t\tif (ret)\n+\t\t\tdev_debug(adap, \"CLIP FW DEL CMD failed: %d\", ret);\n+\t}\n+\tt4_os_unlock(&ce->lock);\n+}\n+\n+/**\n+ * find_or_alloc_clipe - Find/Allocate a free CLIP entry\n+ * @c: CLIP table\n+ * @lip: IPV4/IPV6 address to compare/add\n+ * Returns pointer to the IPV4/IPV6 entry found/created\n+ *\n+ * Finds/Allocates an CLIP entry to be used for a filter rule.\n+ */\n+static struct clip_entry *find_or_alloc_clipe(struct clip_tbl *c,\n+\t\t\t\t\t      const u32 *lip)\n+{\n+\tstruct clip_entry *end, *e;\n+\tstruct clip_entry *first_free = NULL;\n+\tunsigned int clipt_size = c->clipt_size;\n+\n+\tfor (e = &c->cl_list[0], end = &c->cl_list[clipt_size]; e != end; ++e) {\n+\t\tif (rte_atomic32_read(&e->refcnt) == 0) {\n+\t\t\tif (!first_free)\n+\t\t\t\tfirst_free = e;\n+\t\t} else {\n+\t\t\tif (memcmp(lip, e->addr, sizeof(e->addr)) == 0)\n+\t\t\t\tgoto exists;\n+\t\t}\n+\t}\n+\n+\tif (first_free) {\n+\t\te = first_free;\n+\t\tgoto exists;\n+\t}\n+\n+\treturn NULL;\n+\n+exists:\n+\treturn e;\n+}\n+\n+static struct clip_entry *t4_clip_alloc(struct rte_eth_dev *dev,\n+\t\t\t\t\tu32 *lip, u8 v6)\n+{\n+\tstruct adapter *adap = ethdev2adap(dev);\n+\tstruct clip_tbl *ctbl = adap->clipt;\n+\tstruct clip_entry *ce;\n+\tint ret;\n+\n+\tif (!ctbl)\n+\t\treturn NULL;\n+\n+\tt4_os_write_lock(&ctbl->lock);\n+\tce = find_or_alloc_clipe(ctbl, lip);\n+\tif (ce) {\n+\t\tt4_os_lock(&ce->lock);\n+\t\tif (!rte_atomic32_read(&ce->refcnt)) {\n+\t\t\trte_memcpy(ce->addr, lip, sizeof(ce->addr));\n+\t\t\tif (v6) {\n+\t\t\t\tce->type = FILTER_TYPE_IPV6;\n+\t\t\t\trte_atomic32_set(&ce->refcnt, 1);\n+\t\t\t\tret = clip6_get_mbox(dev, lip);\n+\t\t\t\tif (ret) {\n+\t\t\t\t\tdev_debug(adap,\n+\t\t\t\t\t\t  \"CLIP FW ADD CMD failed: %d\",\n+\t\t\t\t\t\t  ret);\n+\t\t\t\t\tce = NULL;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tce->type = FILTER_TYPE_IPV4;\n+\t\t\t}\n+\t\t} else {\n+\t\t\trte_atomic32_inc(&ce->refcnt);\n+\t\t}\n+\t\tt4_os_unlock(&ce->lock);\n+\t}\n+\tt4_os_write_unlock(&ctbl->lock);\n+\n+\treturn ce;\n+}\n+\n+/**\n+ * cxgbe_clip_alloc - Allocate a IPV6 CLIP entry\n+ * @dev: rte_eth_dev pointer\n+ * @lip: IPV6 address to add\n+ * Returns pointer to the CLIP entry created\n+ *\n+ * Allocates a IPV6 CLIP entry to be used for a filter rule.\n+ */\n+struct clip_entry *cxgbe_clip_alloc(struct rte_eth_dev *dev, u32 *lip)\n+{\n+\treturn t4_clip_alloc(dev, lip, FILTER_TYPE_IPV6);\n+}\n+\n+/**\n+ * Initialize CLIP Table\n+ */\n+struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start,\n+\t\t\t\t  unsigned int clipt_end)\n+{\n+\tunsigned int clipt_size;\n+\tstruct clip_tbl *ctbl;\n+\tunsigned int i;\n+\n+\tif (clipt_start >= clipt_end)\n+\t\treturn NULL;\n+\n+\tclipt_size = clipt_end - clipt_start + 1;\n+\n+\tctbl = t4_os_alloc(sizeof(*ctbl) +\n+\t\t\t   clipt_size * sizeof(struct clip_entry));\n+\tif (!ctbl)\n+\t\treturn NULL;\n+\n+\tctbl->clipt_start = clipt_start;\n+\tctbl->clipt_size = clipt_size;\n+\n+\tt4_os_rwlock_init(&ctbl->lock);\n+\n+\tfor (i = 0; i < ctbl->clipt_size; i++) {\n+\t\tt4_os_lock_init(&ctbl->cl_list[i].lock);\n+\t\trte_atomic32_set(&ctbl->cl_list[i].refcnt, 0);\n+\t}\n+\n+\treturn ctbl;\n+}\n+\n+/**\n+ * Cleanup CLIP Table\n+ */\n+void t4_cleanup_clip_tbl(struct adapter *adap)\n+{\n+\tif (adap->clipt)\n+\t\tt4_os_free(adap->clipt);\n+}\ndiff --git a/drivers/net/cxgbe/clip_tbl.h b/drivers/net/cxgbe/clip_tbl.h\nnew file mode 100644\nindex 000000000..737ccc691\n--- /dev/null\n+++ b/drivers/net/cxgbe/clip_tbl.h\n@@ -0,0 +1,31 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Chelsio Communications.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _CXGBE_CLIP_H_\n+#define _CXGBE_CLIP_H_\n+\n+/*\n+ * State for the corresponding entry of the HW CLIP table.\n+ */\n+struct clip_entry {\n+\tenum filter_type type;       /* entry type */\n+\tu32 addr[4];                 /* IPV4 or IPV6 address */\n+\trte_spinlock_t lock;         /* entry lock */\n+\trte_atomic32_t refcnt;       /* entry reference count */\n+};\n+\n+struct clip_tbl {\n+\tunsigned int clipt_start;     /* start index of CLIP table */\n+\tunsigned int clipt_size;      /* size of CLIP table */\n+\trte_rwlock_t lock;            /* table rw lock */\n+\tstruct clip_entry cl_list[0]; /* MUST BE LAST */\n+};\n+\n+struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start,\n+\t\t\t\t  unsigned int clipt_end);\n+void t4_cleanup_clip_tbl(struct adapter *adap);\n+struct clip_entry *cxgbe_clip_alloc(struct rte_eth_dev *dev, u32 *lip);\n+void cxgbe_clip_release(struct rte_eth_dev *dev, struct clip_entry *ce);\n+#endif /* _CXGBE_CLIP_H_ */\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c\nindex a5d20d164..bb2ebaa62 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.c\n+++ b/drivers/net/cxgbe/cxgbe_filter.c\n@@ -6,6 +6,7 @@\n #include \"common.h\"\n #include \"t4_regs.h\"\n #include \"cxgbe_filter.h\"\n+#include \"clip_tbl.h\"\n \n /**\n  * Initialize Hash Filters\n@@ -164,6 +165,9 @@ int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)\n  */\n void clear_filter(struct filter_entry *f)\n {\n+\tif (f->clipt)\n+\t\tcxgbe_clip_release(f->dev, f->clipt);\n+\n \t/*\n \t * The zeroing of the filter rule below clears the filter valid,\n \t * pending, locked flags etc. so it's all we need for\n@@ -349,11 +353,14 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \tstruct port_info *pi = (struct port_info *)(dev->data->dev_private);\n \tstruct adapter *adapter = pi->adapter;\n \tstruct filter_entry *f;\n+\tunsigned int chip_ver;\n \tint ret;\n \n \tif (filter_id >= adapter->tids.nftids)\n \t\treturn -ERANGE;\n \n+\tchip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);\n+\n \tret = is_filter_set(&adapter->tids, filter_id, fs->type);\n \tif (!ret) {\n \t\tdev_warn(adap, \"%s: could not find filter entry: %u\\n\",\n@@ -361,6 +368,17 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \t\treturn -EINVAL;\n \t}\n \n+\t/*\n+\t * Ensure filter id is aligned on the 2 slot boundary for T6,\n+\t * and 4 slot boundary for cards below T6.\n+\t */\n+\tif (fs->type) {\n+\t\tif (chip_ver < CHELSIO_T6)\n+\t\t\tfilter_id &= ~(0x3);\n+\t\telse\n+\t\t\tfilter_id &= ~(0x1);\n+\t}\n+\n \tf = &adapter->tids.ftid_tab[filter_id];\n \tret = writable_filter(f);\n \tif (ret)\n@@ -403,11 +421,15 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \tstruct adapter *adapter = pi->adapter;\n \tunsigned int fidx, iq, fid_bit = 0;\n \tstruct filter_entry *f;\n+\tunsigned int chip_ver;\n+\tuint8_t bitoff[16] = {0};\n \tint ret;\n \n \tif (filter_id >= adapter->tids.nftids)\n \t\treturn -ERANGE;\n \n+\tchip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);\n+\n \tret = validate_filter(adapter, fs);\n \tif (ret)\n \t\treturn ret;\n@@ -426,38 +448,61 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \tiq = get_filter_steerq(dev, fs);\n \n \t/*\n-\t * IPv6 filters occupy four slots and must be aligned on\n-\t * four-slot boundaries.  IPv4 filters only occupy a single\n-\t * slot and have no alignment requirements but writing a new\n-\t * IPv4 filter into the middle of an existing IPv6 filter\n-\t * requires clearing the old IPv6 filter.\n+\t * IPv6 filters occupy four slots and must be aligned on four-slot\n+\t * boundaries for T5. On T6, IPv6 filters occupy two-slots and\n+\t * must be aligned on two-slot boundaries.\n+\t *\n+\t * IPv4 filters only occupy a single slot and have no alignment\n+\t * requirements but writing a new IPv4 filter into the middle\n+\t * of an existing IPv6 filter requires clearing the old IPv6\n+\t * filter.\n \t */\n \tif (fs->type == FILTER_TYPE_IPV4) { /* IPv4 */\n \t\t/*\n-\t\t * If our IPv4 filter isn't being written to a\n-\t\t * multiple of four filter index and there's an IPv6\n-\t\t * filter at the multiple of 4 base slot, then we need\n+\t\t * For T6, If our IPv4 filter isn't being written to a\n+\t\t * multiple of two filter index and there's an IPv6\n+\t\t * filter at the multiple of 2 base slot, then we need\n \t\t * to delete that IPv6 filter ...\n+\t\t * For adapters below T6, IPv6 filter occupies 4 entries.\n \t\t */\n-\t\tfidx = filter_id & ~0x3;\n+\t\tif (chip_ver < CHELSIO_T6)\n+\t\t\tfidx = filter_id & ~0x3;\n+\t\telse\n+\t\t\tfidx = filter_id & ~0x1;\n+\n \t\tif (fidx != filter_id && adapter->tids.ftid_tab[fidx].fs.type) {\n \t\t\tf = &adapter->tids.ftid_tab[fidx];\n \t\t\tif (f->valid)\n \t\t\t\treturn -EBUSY;\n \t\t}\n \t} else { /* IPv6 */\n-\t\t/*\n-\t\t * Ensure that the IPv6 filter is aligned on a\n-\t\t * multiple of 4 boundary.\n-\t\t */\n-\t\tif (filter_id & 0x3)\n-\t\t\treturn -EINVAL;\n+\t\tunsigned int max_filter_id;\n+\n+\t\tif (chip_ver < CHELSIO_T6) {\n+\t\t\t/*\n+\t\t\t * Ensure that the IPv6 filter is aligned on a\n+\t\t\t * multiple of 4 boundary.\n+\t\t\t */\n+\t\t\tif (filter_id & 0x3)\n+\t\t\t\treturn -EINVAL;\n+\n+\t\t\tmax_filter_id = filter_id + 4;\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * For T6, CLIP being enabled, IPv6 filter would occupy\n+\t\t\t * 2 entries.\n+\t\t\t */\n+\t\t\tif (filter_id & 0x1)\n+\t\t\t\treturn -EINVAL;\n+\n+\t\t\tmax_filter_id = filter_id + 2;\n+\t\t}\n \n \t\t/*\n \t\t * Check all except the base overlapping IPv4 filter\n \t\t * slots.\n \t\t */\n-\t\tfor (fidx = filter_id + 1; fidx < filter_id + 4; fidx++) {\n+\t\tfor (fidx = filter_id + 1; fidx < max_filter_id; fidx++) {\n \t\t\tf = &adapter->tids.ftid_tab[fidx];\n \t\t\tif (f->valid)\n \t\t\t\treturn -EBUSY;\n@@ -491,6 +536,16 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \t\treturn ret;\n \t}\n \n+\t/*\n+\t * Allocate a clip table entry only if we have non-zero IPv6 address\n+\t */\n+\tif (chip_ver > CHELSIO_T5 && fs->type &&\n+\t    memcmp(fs->val.lip, bitoff, sizeof(bitoff))) {\n+\t\tf->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);\n+\t\tif (!f->clipt)\n+\t\t\tgoto free_tid;\n+\t}\n+\n \t/*\n \t * Convert the filter specification into our internal format.\n \t * We copy the PF/VF specification into the Outer VLAN field\n@@ -510,13 +565,17 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \tret = set_filter_wr(dev, filter_id);\n \tif (ret) {\n \t\tfid_bit = f->tid - adapter->tids.ftid_base;\n-\t\tcxgbe_clear_ftid(&adapter->tids, fid_bit,\n-\t\t\t\t fs->type ? FILTER_TYPE_IPV6 :\n-\t\t\t\t\t    FILTER_TYPE_IPV4);\n-\t\tclear_filter(f);\n+\t\tgoto free_tid;\n \t}\n \n \treturn ret;\n+\n+free_tid:\n+\tcxgbe_clear_ftid(&adapter->tids, fid_bit,\n+\t\t\t fs->type ? FILTER_TYPE_IPV6 :\n+\t\t\t\t    FILTER_TYPE_IPV4);\n+\tclear_filter(f);\n+\treturn ret;\n }\n \n /**\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h\nindex 27421a475..ce115f69f 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.h\n+++ b/drivers/net/cxgbe/cxgbe_filter.h\n@@ -141,6 +141,7 @@ struct filter_entry {\n \tu32 locked:1;               /* filter is administratively locked */\n \tu32 pending:1;              /* filter action is pending FW reply */\n \tstruct filter_ctx *ctx;     /* caller's completion hook */\n+\tstruct clip_entry *clipt;   /* CLIP Table entry for IPv6 */\n \tstruct rte_eth_dev *dev;    /* Port's rte eth device */\n \tvoid *private;              /* For use by apps using filter_entry */\n \ndiff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c\nindex c692939db..2050fe4db 100644\n--- a/drivers/net/cxgbe/cxgbe_main.c\n+++ b/drivers/net/cxgbe/cxgbe_main.c\n@@ -37,6 +37,7 @@\n #include \"t4_regs.h\"\n #include \"t4_msg.h\"\n #include \"cxgbe.h\"\n+#include \"clip_tbl.h\"\n \n /**\n  * Allocate a chunk of memory. The allocated memory is cleared.\n@@ -995,6 +996,14 @@ static int adap_init0(struct adapter *adap)\n \tadap->tids.ftid_base = val[0];\n \tadap->tids.nftids = val[1] - val[0] + 1;\n \n+\tparams[0] = FW_PARAM_PFVF(CLIP_START);\n+\tparams[1] = FW_PARAM_PFVF(CLIP_END);\n+\tret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2, params, val);\n+\tif (ret < 0)\n+\t\tgoto bye;\n+\tadap->clipt_start = val[0];\n+\tadap->clipt_end = val[1];\n+\n \t/*\n \t * Get device capabilities so we can determine what resources we need\n \t * to manage.\n@@ -1509,6 +1518,7 @@ void cxgbe_close(struct adapter *adapter)\n \t\tif (is_pf4(adapter))\n \t\t\tt4_intr_disable(adapter);\n \t\ttid_free(&adapter->tids);\n+\t\tt4_cleanup_clip_tbl(adapter);\n \t\tt4_sge_tx_monitor_stop(adapter);\n \t\tt4_free_sge_resources(adapter);\n \t\tfor_each_port(adapter, i) {\n@@ -1672,6 +1682,15 @@ int cxgbe_probe(struct adapter *adapter)\n \tprint_adapter_info(adapter);\n \tprint_port_info(adapter);\n \n+\tadapter->clipt = t4_init_clip_tbl(adapter->clipt_start,\n+\t\t\t\t\t  adapter->clipt_end);\n+\tif (!adapter->clipt) {\n+\t\t/* We tolerate a lack of clip_table, giving up some\n+\t\t * functionality\n+\t\t */\n+\t\tdev_warn(adapter, \"could not allocate CLIP. Continuing\\n\");\n+\t}\n+\n \tif (tid_init(&adapter->tids) < 0) {\n \t\t/* Disable filtering support */\n \t\tdev_warn(adapter, \"could not allocate TID table, \"\n",
    "prefixes": [
        "3/9"
    ]
}