get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41993,
    "url": "http://patches.dpdk.org/api/patches/41993/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1e3313333b23056d25704a7be31b34a410f85d59.1530295732.git.rahul.lakkireddy@chelsio.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<1e3313333b23056d25704a7be31b34a410f85d59.1530295732.git.rahul.lakkireddy@chelsio.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1e3313333b23056d25704a7be31b34a410f85d59.1530295732.git.rahul.lakkireddy@chelsio.com",
    "date": "2018-06-29T18:12:20",
    "name": "[5/9] net/cxgbe: add support to delete flows in HASH region",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "4f827228afc4a7d4b095f1521f040456b666c0b0",
    "submitter": {
        "id": 241,
        "url": "http://patches.dpdk.org/api/people/241/?format=api",
        "name": "Rahul Lakkireddy",
        "email": "rahul.lakkireddy@chelsio.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1e3313333b23056d25704a7be31b34a410f85d59.1530295732.git.rahul.lakkireddy@chelsio.com/mbox/",
    "series": [
        {
            "id": 331,
            "url": "http://patches.dpdk.org/api/series/331/?format=api",
            "web_url": "http://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": "http://patches.dpdk.org/series/331/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41993/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/41993/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 9C9F51BAB6;\n\tFri, 29 Jun 2018 20:13:53 +0200 (CEST)",
            "from stargate.chelsio.com (stargate.chelsio.com [12.32.117.8])\n\tby dpdk.org (Postfix) with ESMTP id 93D501B90C\n\tfor <dev@dpdk.org>; Fri, 29 Jun 2018 20:13:50 +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 w5TIDeYR028626; \n\tFri, 29 Jun 2018 11:13:40 -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:20 +0530",
        "Message-Id": "<1e3313333b23056d25704a7be31b34a410f85d59.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 5/9] net/cxgbe: add support to delete flows in\n\tHASH 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\nAdd interface to delete offloaded flows in HASH region. Use the\nhash index saved during insertion to delete the corresponding flow.\n\nSigned-off-by: Shagun Agrawal <shaguna@chelsio.com>\nSigned-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>\n---\n drivers/net/cxgbe/base/t4_msg.h         |  72 ++++++++++++\n drivers/net/cxgbe/base/t4_tcb.h         |  15 +++\n drivers/net/cxgbe/base/t4fw_interface.h |   6 +\n drivers/net/cxgbe/cxgbe_filter.c        | 193 ++++++++++++++++++++++++++++++++\n drivers/net/cxgbe/cxgbe_filter.h        |   2 +\n drivers/net/cxgbe/cxgbe_main.c          |  48 ++++++++\n drivers/net/cxgbe/cxgbe_ofld.h          |  15 +++\n 7 files changed, 351 insertions(+)\n create mode 100644 drivers/net/cxgbe/base/t4_tcb.h",
    "diff": "diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h\nindex 4112ff212..7f4c98fb6 100644\n--- a/drivers/net/cxgbe/base/t4_msg.h\n+++ b/drivers/net/cxgbe/base/t4_msg.h\n@@ -8,7 +8,12 @@\n \n enum {\n \tCPL_ACT_OPEN_REQ      = 0x3,\n+\tCPL_SET_TCB_FIELD     = 0x5,\n+\tCPL_ABORT_REQ         = 0xA,\n+\tCPL_ABORT_RPL         = 0xB,\n+\tCPL_TID_RELEASE       = 0x1A,\n \tCPL_ACT_OPEN_RPL      = 0x25,\n+\tCPL_ABORT_RPL_RSS     = 0x2D,\n \tCPL_SET_TCB_RPL       = 0x3A,\n \tCPL_ACT_OPEN_REQ6     = 0x83,\n \tCPL_SGE_EGR_UPDATE    = 0xA5,\n@@ -27,6 +32,11 @@ enum {\n \tULP_MODE_NONE          = 0,\n };\n \n+enum {\n+\tCPL_ABORT_SEND_RST = 0,\n+\tCPL_ABORT_NO_RST,\n+};\n+\n enum {                     /* TX_PKT_XT checksum types */\n \tTX_CSUM_TCPIP  = 8,\n \tTX_CSUM_UDPIP  = 9,\n@@ -189,6 +199,29 @@ struct cpl_act_open_rpl {\n #define M_AOPEN_ATID    0xFFFFFF\n #define G_AOPEN_ATID(x) (((x) >> S_AOPEN_ATID) & M_AOPEN_ATID)\n \n+struct cpl_set_tcb_field {\n+\tWR_HDR;\n+\tunion opcode_tid ot;\n+\t__be16 reply_ctrl;\n+\t__be16 word_cookie;\n+\t__be64 mask;\n+\t__be64 val;\n+};\n+\n+/* cpl_set_tcb_field.word_cookie fields */\n+#define S_WORD    0\n+#define V_WORD(x) ((x) << S_WORD)\n+\n+/* cpl_get_tcb.reply_ctrl fields */\n+#define S_QUEUENO    0\n+#define V_QUEUENO(x) ((x) << S_QUEUENO)\n+\n+#define S_REPLY_CHAN    14\n+#define V_REPLY_CHAN(x) ((x) << S_REPLY_CHAN)\n+\n+#define S_NO_REPLY    15\n+#define V_NO_REPLY(x) ((x) << S_NO_REPLY)\n+\n struct cpl_set_tcb_rpl {\n \tRSS_HDR\n \tunion opcode_tid ot;\n@@ -198,6 +231,39 @@ struct cpl_set_tcb_rpl {\n \t__be64 oldval;\n };\n \n+/* cpl_abort_req status command code\n+ */\n+struct cpl_abort_req {\n+\tWR_HDR;\n+\tunion opcode_tid ot;\n+\t__be32 rsvd0;\n+\t__u8  rsvd1;\n+\t__u8  cmd;\n+\t__u8  rsvd2[6];\n+};\n+\n+struct cpl_abort_rpl_rss {\n+\tRSS_HDR\n+\tunion opcode_tid ot;\n+\t__u8  rsvd[3];\n+\t__u8  status;\n+};\n+\n+struct cpl_abort_rpl {\n+\tWR_HDR;\n+\tunion opcode_tid ot;\n+\t__be32 rsvd0;\n+\t__u8  rsvd1;\n+\t__u8  cmd;\n+\t__u8  rsvd2[6];\n+};\n+\n+struct cpl_tid_release {\n+\tWR_HDR;\n+\tunion opcode_tid ot;\n+\t__be32 rsvd;\n+};\n+\n struct cpl_tx_data {\n \tunion opcode_tid ot;\n \t__be32 len;\n@@ -403,7 +469,13 @@ struct cpl_fw6_msg {\n \t__be64 data[4];\n };\n \n+/* ULP_TX opcodes */\n+enum {\n+\tULP_TX_PKT = 4\n+};\n+\n enum {\n+\tULP_TX_SC_NOOP = 0x80,\n \tULP_TX_SC_IMM  = 0x81,\n \tULP_TX_SC_DSGL = 0x82,\n \tULP_TX_SC_ISGL = 0x83\ndiff --git a/drivers/net/cxgbe/base/t4_tcb.h b/drivers/net/cxgbe/base/t4_tcb.h\nnew file mode 100644\nindex 000000000..6d7f5e8c1\n--- /dev/null\n+++ b/drivers/net/cxgbe/base/t4_tcb.h\n@@ -0,0 +1,15 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Chelsio Communications.\n+ * All rights reserved.\n+ */\n+\n+#ifndef _T4_TCB_DEFS_H\n+#define _T4_TCB_DEFS_H\n+\n+/* 105:96 */\n+#define W_TCB_RSS_INFO    3\n+#define S_TCB_RSS_INFO    0\n+#define M_TCB_RSS_INFO    0x3ffULL\n+#define V_TCB_RSS_INFO(x) ((x) << S_TCB_RSS_INFO)\n+\n+#endif /* _T4_TCB_DEFS_H */\ndiff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h\nindex 19bcfc124..7b2f2d37f 100644\n--- a/drivers/net/cxgbe/base/t4fw_interface.h\n+++ b/drivers/net/cxgbe/base/t4fw_interface.h\n@@ -55,6 +55,7 @@ enum fw_memtype {\n \n enum fw_wr_opcodes {\n \tFW_FILTER_WR\t\t= 0x02,\n+\tFW_ULPTX_WR\t\t= 0x04,\n \tFW_TP_WR\t\t= 0x05,\n \tFW_ETH_TX_PKT_WR\t= 0x08,\n \tFW_ETH_TX_PKTS_WR\t= 0x09,\n@@ -78,6 +79,11 @@ struct fw_wr_hdr {\n #define V_FW_WR_OP(x)\t\t((x) << S_FW_WR_OP)\n #define G_FW_WR_OP(x)\t\t(((x) >> S_FW_WR_OP) & M_FW_WR_OP)\n \n+/* atomic flag (hi) - firmware encapsulates CPLs in CPL_BARRIER\n+ */\n+#define S_FW_WR_ATOMIC\t\t23\n+#define V_FW_WR_ATOMIC(x)\t((x) << S_FW_WR_ATOMIC)\n+\n /* work request immediate data length (hi)\n  */\n #define S_FW_WR_IMMDLEN\t0\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c\nindex bac7aa291..7759b8acf 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.c\n+++ b/drivers/net/cxgbe/cxgbe_filter.c\n@@ -4,6 +4,7 @@\n  */\n #include <rte_net.h>\n #include \"common.h\"\n+#include \"t4_tcb.h\"\n #include \"t4_regs.h\"\n #include \"cxgbe_filter.h\"\n #include \"clip_tbl.h\"\n@@ -116,6 +117,34 @@ int writable_filter(struct filter_entry *f)\n \treturn 0;\n }\n \n+/**\n+ * Build a CPL_SET_TCB_FIELD message as payload of a ULP_TX_PKT command.\n+ */\n+static inline void mk_set_tcb_field_ulp(struct filter_entry *f,\n+\t\t\t\t\tstruct cpl_set_tcb_field *req,\n+\t\t\t\t\tunsigned int word,\n+\t\t\t\t\tu64 mask, u64 val, u8 cookie,\n+\t\t\t\t\tint no_reply)\n+{\n+\tstruct ulp_txpkt *txpkt = (struct ulp_txpkt *)req;\n+\tstruct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);\n+\n+\ttxpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |\n+\t\t\t\t      V_ULP_TXPKT_DEST(0));\n+\ttxpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*req), 16));\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));\n+\tsc->len = cpu_to_be32(sizeof(*req) - sizeof(struct work_request_hdr));\n+\tOPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_SET_TCB_FIELD, f->tid));\n+\treq->reply_ctrl = cpu_to_be16(V_NO_REPLY(no_reply) | V_REPLY_CHAN(0) |\n+\t\t\t\t      V_QUEUENO(0));\n+\treq->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(cookie));\n+\treq->mask = cpu_to_be64(mask);\n+\treq->val = cpu_to_be64(val);\n+\tsc = (struct ulptx_idata *)(req + 1);\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));\n+\tsc->len = cpu_to_be32(0);\n+}\n+\n /**\n  * Check if entry already filled.\n  */\n@@ -185,6 +214,132 @@ static u64 hash_filter_ntuple(const struct filter_entry *f)\n \treturn ntuple;\n }\n \n+/**\n+ * Build a CPL_ABORT_REQ message as payload of a ULP_TX_PKT command.\n+ */\n+static void mk_abort_req_ulp(struct cpl_abort_req *abort_req,\n+\t\t\t     unsigned int tid)\n+{\n+\tstruct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_req;\n+\tstruct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);\n+\n+\ttxpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |\n+\t\t\t\t      V_ULP_TXPKT_DEST(0));\n+\ttxpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_req), 16));\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));\n+\tsc->len = cpu_to_be32(sizeof(*abort_req) -\n+\t\t\t      sizeof(struct work_request_hdr));\n+\tOPCODE_TID(abort_req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, tid));\n+\tabort_req->rsvd0 = cpu_to_be32(0);\n+\tabort_req->rsvd1 = 0;\n+\tabort_req->cmd = CPL_ABORT_NO_RST;\n+\tsc = (struct ulptx_idata *)(abort_req + 1);\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));\n+\tsc->len = cpu_to_be32(0);\n+}\n+\n+/**\n+ * Build a CPL_ABORT_RPL message as payload of a ULP_TX_PKT command.\n+ */\n+static void mk_abort_rpl_ulp(struct cpl_abort_rpl *abort_rpl,\n+\t\t\t     unsigned int tid)\n+{\n+\tstruct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_rpl;\n+\tstruct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);\n+\n+\ttxpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |\n+\t\t\t\t      V_ULP_TXPKT_DEST(0));\n+\ttxpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_rpl), 16));\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));\n+\tsc->len = cpu_to_be32(sizeof(*abort_rpl) -\n+\t\t\t      sizeof(struct work_request_hdr));\n+\tOPCODE_TID(abort_rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, tid));\n+\tabort_rpl->rsvd0 = cpu_to_be32(0);\n+\tabort_rpl->rsvd1 = 0;\n+\tabort_rpl->cmd = CPL_ABORT_NO_RST;\n+\tsc = (struct ulptx_idata *)(abort_rpl + 1);\n+\tsc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));\n+\tsc->len = cpu_to_be32(0);\n+}\n+\n+/**\n+ * Delete the specified hash filter.\n+ */\n+static int cxgbe_del_hash_filter(struct rte_eth_dev *dev,\n+\t\t\t\t unsigned int filter_id,\n+\t\t\t\t struct filter_ctx *ctx)\n+{\n+\tstruct adapter *adapter = ethdev2adap(dev);\n+\tstruct tid_info *t = &adapter->tids;\n+\tstruct filter_entry *f;\n+\tstruct sge_ctrl_txq *ctrlq;\n+\tunsigned int port_id = ethdev2pinfo(dev)->port_id;\n+\tint ret;\n+\n+\tif (filter_id > adapter->tids.ntids)\n+\t\treturn -E2BIG;\n+\n+\tf = lookup_tid(t, filter_id);\n+\tif (!f) {\n+\t\tdev_err(adapter, \"%s: no filter entry for filter_id = %d\\n\",\n+\t\t\t__func__, filter_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = writable_filter(f);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (f->valid) {\n+\t\tunsigned int wrlen;\n+\t\tstruct rte_mbuf *mbuf;\n+\t\tstruct work_request_hdr *wr;\n+\t\tstruct ulptx_idata *aligner;\n+\t\tstruct cpl_set_tcb_field *req;\n+\t\tstruct cpl_abort_req *abort_req;\n+\t\tstruct cpl_abort_rpl *abort_rpl;\n+\n+\t\tf->ctx = ctx;\n+\t\tf->pending = 1;\n+\n+\t\twrlen = cxgbe_roundup(sizeof(*wr) +\n+\t\t\t\t      (sizeof(*req) + sizeof(*aligner)) +\n+\t\t\t\t      sizeof(*abort_req) + sizeof(*abort_rpl),\n+\t\t\t\t      16);\n+\n+\t\tctrlq = &adapter->sge.ctrlq[port_id];\n+\t\tmbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);\n+\t\tif (!mbuf) {\n+\t\t\tdev_err(adapter, \"%s: could not allocate skb ..\\n\",\n+\t\t\t\t__func__);\n+\t\t\tgoto out_err;\n+\t\t}\n+\n+\t\tmbuf->data_len = wrlen;\n+\t\tmbuf->pkt_len = mbuf->data_len;\n+\n+\t\treq = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *);\n+\t\tINIT_ULPTX_WR(req, wrlen, 0, 0);\n+\t\twr = (struct work_request_hdr *)req;\n+\t\twr++;\n+\t\treq = (struct cpl_set_tcb_field *)wr;\n+\t\tmk_set_tcb_field_ulp(f, req, W_TCB_RSS_INFO,\n+\t\t\t\tV_TCB_RSS_INFO(M_TCB_RSS_INFO),\n+\t\t\t\tV_TCB_RSS_INFO(adapter->sge.fw_evtq.abs_id),\n+\t\t\t\t0, 1);\n+\t\taligner = (struct ulptx_idata *)(req + 1);\n+\t\tabort_req = (struct cpl_abort_req *)(aligner + 1);\n+\t\tmk_abort_req_ulp(abort_req, f->tid);\n+\t\tabort_rpl = (struct cpl_abort_rpl *)(abort_req + 1);\n+\t\tmk_abort_rpl_ulp(abort_rpl, f->tid);\n+\t\tt4_mgmt_tx(ctrlq, mbuf);\n+\t}\n+\treturn 0;\n+\n+out_err:\n+\treturn -ENOMEM;\n+}\n+\n /**\n  * Build a ACT_OPEN_REQ6 message for setting IPv6 hash filter.\n  */\n@@ -560,6 +715,9 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n \tunsigned int chip_ver;\n \tint ret;\n \n+\tif (is_hashfilter(adapter) && fs->cap)\n+\t\treturn cxgbe_del_hash_filter(dev, filter_id, ctx);\n+\n \tif (filter_id >= adapter->tids.nftids)\n \t\treturn -ERANGE;\n \n@@ -967,3 +1125,38 @@ int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,\n \t}\n \treturn 0;\n }\n+\n+/**\n+ * Handle a Hash filter delete reply.\n+ */\n+void hash_del_filter_rpl(struct adapter *adap,\n+\t\t\t const struct cpl_abort_rpl_rss *rpl)\n+{\n+\tstruct tid_info *t = &adap->tids;\n+\tstruct filter_entry *f;\n+\tstruct filter_ctx *ctx = NULL;\n+\tunsigned int tid = GET_TID(rpl);\n+\n+\tf = lookup_tid(t, tid);\n+\tif (!f) {\n+\t\tdev_warn(adap, \"%s: could not find filter entry: %u\\n\",\n+\t\t\t __func__, tid);\n+\t\treturn;\n+\t}\n+\n+\tctx = f->ctx;\n+\tf->ctx = NULL;\n+\n+\tf->valid = 0;\n+\n+\tif (f->clipt)\n+\t\tcxgbe_clip_release(f->dev, f->clipt);\n+\n+\tcxgbe_remove_tid(t, 0, tid, 0);\n+\tt4_os_free(f);\n+\n+\tif (ctx) {\n+\t\tctx->result = 0;\n+\t\tt4_complete(&ctx->completion);\n+\t}\n+}\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h\nindex 7c469c895..c51efea7d 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.h\n+++ b/drivers/net/cxgbe/cxgbe_filter.h\n@@ -224,6 +224,8 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,\n int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);\n int init_hash_filter(struct adapter *adap);\n void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl);\n+void hash_del_filter_rpl(struct adapter *adap,\n+\t\t\t const struct cpl_abort_rpl_rss *rpl);\n int validate_filter(struct adapter *adap, struct ch_filter_specification *fs);\n int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,\n \t\t\t   u64 *c, bool get_byte);\ndiff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c\nindex c550dd5be..08b2a42d1 100644\n--- a/drivers/net/cxgbe/cxgbe_main.c\n+++ b/drivers/net/cxgbe/cxgbe_main.c\n@@ -87,6 +87,10 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,\n \t\tconst struct cpl_fw6_msg *msg = (const void *)rsp;\n \n \t\tt4_handle_fw_rpl(q->adapter, msg->data);\n+\t} else if (opcode == CPL_ABORT_RPL_RSS) {\n+\t\tconst struct cpl_abort_rpl_rss *p = (const void *)rsp;\n+\n+\t\thash_del_filter_rpl(q->adapter, p);\n \t} else if (opcode == CPL_SET_TCB_RPL) {\n \t\tconst struct cpl_set_tcb_rpl *p = (const void *)rsp;\n \n@@ -301,6 +305,50 @@ void cxgbe_free_atid(struct tid_info *t, unsigned int atid)\n \tt4_os_unlock(&t->atid_lock);\n }\n \n+/**\n+ * Populate a TID_RELEASE WR.  Caller must properly size the skb.\n+ */\n+static void mk_tid_release(struct rte_mbuf *mbuf, unsigned int tid)\n+{\n+\tstruct cpl_tid_release *req;\n+\n+\treq = rte_pktmbuf_mtod(mbuf, struct cpl_tid_release *);\n+\tINIT_TP_WR_MIT_CPL(req, CPL_TID_RELEASE, tid);\n+}\n+\n+/**\n+ * Release a TID and inform HW.  If we are unable to allocate the release\n+ * message we defer to a work queue.\n+ */\n+void cxgbe_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid,\n+\t\t      unsigned short family)\n+{\n+\tstruct rte_mbuf *mbuf;\n+\tstruct adapter *adap = container_of(t, struct adapter, tids);\n+\n+\tWARN_ON(tid >= t->ntids);\n+\n+\tif (t->tid_tab[tid]) {\n+\t\tt->tid_tab[tid] = NULL;\n+\t\trte_atomic32_dec(&t->conns_in_use);\n+\t\tif (t->hash_base && tid >= t->hash_base) {\n+\t\t\tif (family == FILTER_TYPE_IPV4)\n+\t\t\t\trte_atomic32_dec(&t->hash_tids_in_use);\n+\t\t} else {\n+\t\t\tif (family == FILTER_TYPE_IPV4)\n+\t\t\t\trte_atomic32_dec(&t->tids_in_use);\n+\t\t}\n+\t}\n+\n+\tmbuf = rte_pktmbuf_alloc((&adap->sge.ctrlq[chan])->mb_pool);\n+\tif (mbuf) {\n+\t\tmbuf->data_len = sizeof(struct cpl_tid_release);\n+\t\tmbuf->pkt_len = mbuf->data_len;\n+\t\tmk_tid_release(mbuf, tid);\n+\t\tt4_mgmt_tx(&adap->sge.ctrlq[chan], mbuf);\n+\t}\n+}\n+\n /**\n  * Insert a TID.\n  */\ndiff --git a/drivers/net/cxgbe/cxgbe_ofld.h b/drivers/net/cxgbe/cxgbe_ofld.h\nindex 798e39828..50931ed04 100644\n--- a/drivers/net/cxgbe/cxgbe_ofld.h\n+++ b/drivers/net/cxgbe/cxgbe_ofld.h\n@@ -19,6 +19,19 @@\n \t(w)->wr.wr_lo = cpu_to_be64(0); \\\n } while (0)\n \n+#define INIT_TP_WR_MIT_CPL(w, cpl, tid) do { \\\n+\tINIT_TP_WR(w, tid); \\\n+\tOPCODE_TID(w) = cpu_to_be32(MK_OPCODE_TID(cpl, tid)); \\\n+} while (0)\n+\n+#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \\\n+\t(w)->wr.wr_hi = cpu_to_be32(V_FW_WR_OP(FW_ULPTX_WR) | \\\n+\t\t\t\t    V_FW_WR_ATOMIC(atomic)); \\\n+\t(w)->wr.wr_mid = cpu_to_be32(V_FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \\\n+\t\t\t\t     V_FW_WR_FLOWID(tid)); \\\n+\t(w)->wr.wr_lo = cpu_to_be64(0); \\\n+} while (0)\n+\n /*\n  * Max # of ATIDs.  The absolute HW max is 16K but we keep it lower.\n  */\n@@ -68,6 +81,8 @@ static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)\n \n int cxgbe_alloc_atid(struct tid_info *t, void *data);\n void cxgbe_free_atid(struct tid_info *t, unsigned int atid);\n+void cxgbe_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid,\n+\t\t      unsigned short family);\n void cxgbe_insert_tid(struct tid_info *t, void *data, unsigned int tid,\n \t\t      unsigned short family);\n \n",
    "prefixes": [
        "5/9"
    ]
}