get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 816731,
    "url": "http://patchwork.ozlabs.org/api/patches/816731/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/dc5f8e6419ad3439b14f39306245d98537be3306.1505977744.git.rahul.lakkireddy@chelsio.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<dc5f8e6419ad3439b14f39306245d98537be3306.1505977744.git.rahul.lakkireddy@chelsio.com>",
    "list_archive_url": null,
    "date": "2017-09-21T07:33:35",
    "name": "[net-next,2/4] cxgb4: add basic tc flower offload support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5472f556bf684775a8477ef30b4c4b878d8bb8d5",
    "submitter": {
        "id": 69728,
        "url": "http://patchwork.ozlabs.org/api/people/69728/?format=api",
        "name": "Rahul Lakkireddy",
        "email": "rahul.lakkireddy@chelsio.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/dc5f8e6419ad3439b14f39306245d98537be3306.1505977744.git.rahul.lakkireddy@chelsio.com/mbox/",
    "series": [
        {
            "id": 4320,
            "url": "http://patchwork.ozlabs.org/api/series/4320/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=4320",
            "date": "2017-09-21T07:33:33",
            "name": "cxgb4: add support to offload tc flower",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/4320/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/816731/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/816731/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xyT084C48z9sNw\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 21 Sep 2017 17:34:48 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751915AbdIUHer (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 21 Sep 2017 03:34:47 -0400",
            "from stargate.chelsio.com ([12.32.117.8]:41578 \"EHLO\n\tstargate.chelsio.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751906AbdIUHep (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Thu, 21 Sep 2017 03:34:45 -0400",
            "from localhost (scalar.blr.asicdesigners.com [10.193.185.94])\n\tby stargate.chelsio.com (8.13.8/8.13.8) with ESMTP id v8L7YYlm005041; \n\tThu, 21 Sep 2017 00:34:34 -0700"
        ],
        "From": "Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>",
        "To": "netdev@vger.kernel.org",
        "Cc": "davem@davemloft.net, kumaras@chelsio.com, ganeshgr@chelsio.com,\n\tnirranjan@chelsio.com, indranil@chelsio.com,\n\tRahul Lakkireddy <rahul.lakkireddy@chelsio.com>",
        "Subject": "[PATCH net-next 2/4] cxgb4: add basic tc flower offload support",
        "Date": "Thu, 21 Sep 2017 13:03:35 +0530",
        "Message-Id": "<dc5f8e6419ad3439b14f39306245d98537be3306.1505977744.git.rahul.lakkireddy@chelsio.com>",
        "X-Mailer": "git-send-email 2.5.3",
        "In-Reply-To": [
            "<cover.1505977744.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1505977744.git.rahul.lakkireddy@chelsio.com>"
        ],
        "References": [
            "<cover.1505977744.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1505977744.git.rahul.lakkireddy@chelsio.com>"
        ],
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "From: Kumar Sanghvi <kumaras@chelsio.com>\n\nAdd support to add/remove flows for offload.  Following match\nand action are supported for offloading a flow:\n\nMatch: ether-protocol, IPv4/IPv6 addresses, L4 ports (TCP/UDP)\nAction: drop, redirect to another port on the device.\n\nThe qualifying flows can have accompanying mask information.\n\nSigned-off-by: Kumar Sanghvi <kumaras@chelsio.com>\nSigned-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>\nSigned-off-by: Ganesh Goudar <ganeshgr@chelsio.com>\n---\n drivers/net/ethernet/chelsio/cxgb4/cxgb4.h         |   3 +\n drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c  |  26 ++\n drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c    |   2 +\n .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c   | 285 ++++++++++++++++++++-\n .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h   |  17 ++\n drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h     |   1 +\n 6 files changed, 332 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h\nindex ea72d2d2e1b4..26eac599ab2c 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h\n@@ -904,6 +904,9 @@ struct adapter {\n \t/* TC u32 offload */\n \tstruct cxgb4_tc_u32_table *tc_u32;\n \tstruct chcr_stats_debug chcr_stats;\n+\n+\t/* TC flower offload */\n+\tDECLARE_HASHTABLE(flower_anymatch_tbl, 9);\n };\n \n /* Support for \"sched-class\" command to allow a TX Scheduling Class to be\ndiff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c\nindex 45b5853ca2f1..07a4619e2164 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c\n@@ -148,6 +148,32 @@ static int get_filter_steerq(struct net_device *dev,\n \treturn iq;\n }\n \n+int cxgb4_get_free_ftid(struct net_device *dev, int family)\n+{\n+\tstruct adapter *adap = netdev2adap(dev);\n+\tstruct tid_info *t = &adap->tids;\n+\tint ftid;\n+\n+\tspin_lock_bh(&t->ftid_lock);\n+\tif (family == PF_INET) {\n+\t\tftid = find_first_zero_bit(t->ftid_bmap, t->nftids);\n+\t\tif (ftid >= t->nftids)\n+\t\t\tftid = -1;\n+\t} else {\n+\t\tftid = bitmap_find_free_region(t->ftid_bmap, t->nftids, 2);\n+\t\tif (ftid < 0) {\n+\t\t\tftid = -1;\n+\t\t\tgoto out_unlock;\n+\t\t}\n+\n+\t\t/* this is only a lookup, keep the found region unallocated */\n+\t\tbitmap_release_region(t->ftid_bmap, ftid, 2);\n+\t}\n+out_unlock:\n+\tspin_unlock_bh(&t->ftid_lock);\n+\treturn ftid;\n+}\n+\n static int cxgb4_set_ftid(struct tid_info *t, int fidx, int family)\n {\n \tspin_lock_bh(&t->ftid_lock);\ndiff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c\nindex 8923affbdaf8..3ba4e1ff8486 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c\n@@ -5105,6 +5105,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)\n \t\tif (!adapter->tc_u32)\n \t\t\tdev_warn(&pdev->dev,\n \t\t\t\t \"could not offload tc u32, continuing\\n\");\n+\n+\t\tcxgb4_init_tc_flower(adapter);\n \t}\n \n \tif (is_offload(adapter)) {\ndiff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c\nindex 16dff71e4d02..1af01101faaf 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c\n@@ -38,16 +38,292 @@\n #include \"cxgb4.h\"\n #include \"cxgb4_tc_flower.h\"\n \n+static struct ch_tc_flower_entry *allocate_flower_entry(void)\n+{\n+\tstruct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL);\n+\treturn new;\n+}\n+\n+/* Must be called with either RTNL or rcu_read_lock */\n+static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,\n+\t\t\t\t\t\t   unsigned long flower_cookie)\n+{\n+\tstruct ch_tc_flower_entry *flower_entry;\n+\n+\thash_for_each_possible_rcu(adap->flower_anymatch_tbl, flower_entry,\n+\t\t\t\t   link, flower_cookie)\n+\t\tif (flower_entry->tc_flower_cookie == flower_cookie)\n+\t\t\treturn flower_entry;\n+\treturn NULL;\n+}\n+\n+static void cxgb4_process_flow_match(struct net_device *dev,\n+\t\t\t\t     struct tc_cls_flower_offload *cls,\n+\t\t\t\t     struct ch_filter_specification *fs)\n+{\n+\tu16 addr_type = 0;\n+\n+\tif (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {\n+\t\tstruct flow_dissector_key_control *key =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_CONTROL,\n+\t\t\t\t\t\t  cls->key);\n+\n+\t\taddr_type = key->addr_type;\n+\t}\n+\n+\tif (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_BASIC)) {\n+\t\tstruct flow_dissector_key_basic *key =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_BASIC,\n+\t\t\t\t\t\t  cls->key);\n+\t\tstruct flow_dissector_key_basic *mask =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_BASIC,\n+\t\t\t\t\t\t  cls->mask);\n+\t\tu16 ethtype_key = ntohs(key->n_proto);\n+\t\tu16 ethtype_mask = ntohs(mask->n_proto);\n+\n+\t\tif (ethtype_key == ETH_P_ALL) {\n+\t\t\tethtype_key = 0;\n+\t\t\tethtype_mask = 0;\n+\t\t}\n+\n+\t\tfs->val.ethtype = ethtype_key;\n+\t\tfs->mask.ethtype = ethtype_mask;\n+\t\tfs->val.proto = key->ip_proto;\n+\t\tfs->mask.proto = mask->ip_proto;\n+\t}\n+\n+\tif (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {\n+\t\tstruct flow_dissector_key_ipv4_addrs *key =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_IPV4_ADDRS,\n+\t\t\t\t\t\t  cls->key);\n+\t\tstruct flow_dissector_key_ipv4_addrs *mask =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_IPV4_ADDRS,\n+\t\t\t\t\t\t  cls->mask);\n+\t\tfs->type = 0;\n+\t\tmemcpy(&fs->val.lip[0], &key->dst, sizeof(key->dst));\n+\t\tmemcpy(&fs->val.fip[0], &key->src, sizeof(key->src));\n+\t\tmemcpy(&fs->mask.lip[0], &mask->dst, sizeof(mask->dst));\n+\t\tmemcpy(&fs->mask.fip[0], &mask->src, sizeof(mask->src));\n+\t}\n+\n+\tif (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {\n+\t\tstruct flow_dissector_key_ipv6_addrs *key =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_IPV6_ADDRS,\n+\t\t\t\t\t\t  cls->key);\n+\t\tstruct flow_dissector_key_ipv6_addrs *mask =\n+\t\t\tskb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t  FLOW_DISSECTOR_KEY_IPV6_ADDRS,\n+\t\t\t\t\t\t  cls->mask);\n+\n+\t\tfs->type = 1;\n+\t\tmemcpy(&fs->val.lip[0], key->dst.s6_addr, sizeof(key->dst));\n+\t\tmemcpy(&fs->val.fip[0], key->src.s6_addr, sizeof(key->src));\n+\t\tmemcpy(&fs->mask.lip[0], mask->dst.s6_addr, sizeof(mask->dst));\n+\t\tmemcpy(&fs->mask.fip[0], mask->src.s6_addr, sizeof(mask->src));\n+\t}\n+\n+\tif (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_PORTS)) {\n+\t\tstruct flow_dissector_key_ports *key, *mask;\n+\n+\t\tkey = skb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\tFLOW_DISSECTOR_KEY_PORTS,\n+\t\t\t\t\t\tcls->key);\n+\t\tmask = skb_flow_dissector_target(cls->dissector,\n+\t\t\t\t\t\t FLOW_DISSECTOR_KEY_PORTS,\n+\t\t\t\t\t\t cls->mask);\n+\t\tfs->val.lport = cpu_to_be16(key->dst);\n+\t\tfs->mask.lport = cpu_to_be16(mask->dst);\n+\t\tfs->val.fport = cpu_to_be16(key->src);\n+\t\tfs->mask.fport = cpu_to_be16(mask->src);\n+\t}\n+\n+\t/* Match only packets coming from the ingress port where this\n+\t * filter will be created.\n+\t */\n+\tfs->val.iport = netdev2pinfo(dev)->port_id;\n+\tfs->mask.iport = ~0;\n+}\n+\n+static int cxgb4_validate_flow_match(struct net_device *dev,\n+\t\t\t\t     struct tc_cls_flower_offload *cls)\n+{\n+\tif (cls->dissector->used_keys &\n+\t    ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |\n+\t      BIT(FLOW_DISSECTOR_KEY_BASIC) |\n+\t      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |\n+\t      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |\n+\t      BIT(FLOW_DISSECTOR_KEY_PORTS))) {\n+\t\tnetdev_warn(dev, \"Unsupported key used: 0x%x\\n\",\n+\t\t\t    cls->dissector->used_keys);\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\treturn 0;\n+}\n+\n+static void cxgb4_process_flow_actions(struct net_device *in,\n+\t\t\t\t       struct tc_cls_flower_offload *cls,\n+\t\t\t\t       struct ch_filter_specification *fs)\n+{\n+\tconst struct tc_action *a;\n+\tLIST_HEAD(actions);\n+\n+\ttcf_exts_to_list(cls->exts, &actions);\n+\tlist_for_each_entry(a, &actions, list) {\n+\t\tif (is_tcf_gact_shot(a)) {\n+\t\t\tfs->action = FILTER_DROP;\n+\t\t} else if (is_tcf_mirred_egress_redirect(a)) {\n+\t\t\tint ifindex = tcf_mirred_ifindex(a);\n+\t\t\tstruct net_device *out = __dev_get_by_index(dev_net(in),\n+\t\t\t\t\t\t\t\t    ifindex);\n+\t\t\tstruct port_info *pi = netdev_priv(out);\n+\n+\t\t\tfs->action = FILTER_SWITCH;\n+\t\t\tfs->eport = pi->port_id;\n+\t\t}\n+\t}\n+}\n+\n+static int cxgb4_validate_flow_actions(struct net_device *dev,\n+\t\t\t\t       struct tc_cls_flower_offload *cls)\n+{\n+\tconst struct tc_action *a;\n+\tLIST_HEAD(actions);\n+\n+\ttcf_exts_to_list(cls->exts, &actions);\n+\tlist_for_each_entry(a, &actions, list) {\n+\t\tif (is_tcf_gact_shot(a)) {\n+\t\t\t/* Do nothing */\n+\t\t} else if (is_tcf_mirred_egress_redirect(a)) {\n+\t\t\tstruct adapter *adap = netdev2adap(dev);\n+\t\t\tstruct net_device *n_dev;\n+\t\t\tunsigned int i, ifindex;\n+\t\t\tbool found = false;\n+\n+\t\t\tifindex = tcf_mirred_ifindex(a);\n+\t\t\tfor_each_port(adap, i) {\n+\t\t\t\tn_dev = adap->port[i];\n+\t\t\t\tif (ifindex == n_dev->ifindex) {\n+\t\t\t\t\tfound = true;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\t/* If interface doesn't belong to our hw, then\n+\t\t\t * the provided output port is not valid\n+\t\t\t */\n+\t\t\tif (!found) {\n+\t\t\t\tnetdev_err(dev, \"%s: Out port invalid\\n\",\n+\t\t\t\t\t   __func__);\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tnetdev_err(dev, \"%s: Unsupported action\\n\", __func__);\n+\t\t\treturn -EOPNOTSUPP;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n int cxgb4_tc_flower_replace(struct net_device *dev,\n \t\t\t    struct tc_cls_flower_offload *cls)\n {\n-\treturn -EOPNOTSUPP;\n+\tstruct adapter *adap = netdev2adap(dev);\n+\tstruct ch_tc_flower_entry *ch_flower;\n+\tstruct ch_filter_specification *fs;\n+\tstruct filter_ctx ctx;\n+\tint fidx;\n+\tint ret;\n+\n+\tif (cxgb4_validate_flow_actions(dev, cls))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (cxgb4_validate_flow_match(dev, cls))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tch_flower = allocate_flower_entry();\n+\tif (!ch_flower) {\n+\t\tnetdev_err(dev, \"%s: ch_flower alloc failed.\\n\", __func__);\n+\t\tret = -ENOMEM;\n+\t\tgoto err;\n+\t}\n+\n+\tfs = &ch_flower->fs;\n+\tfs->hitcnts = 1;\n+\tcxgb4_process_flow_actions(dev, cls, fs);\n+\tcxgb4_process_flow_match(dev, cls, fs);\n+\n+\tfidx = cxgb4_get_free_ftid(dev, fs->type ? PF_INET6 : PF_INET);\n+\tif (fidx < 0) {\n+\t\tnetdev_err(dev, \"%s: No fidx for offload.\\n\", __func__);\n+\t\tret = -ENOMEM;\n+\t\tgoto free_entry;\n+\t}\n+\n+\tinit_completion(&ctx.completion);\n+\tret = __cxgb4_set_filter(dev, fidx, fs, &ctx);\n+\tif (ret) {\n+\t\tnetdev_err(dev, \"%s: filter creation err %d\\n\",\n+\t\t\t   __func__, ret);\n+\t\tgoto free_entry;\n+\t}\n+\n+\t/* Wait for reply */\n+\tret = wait_for_completion_timeout(&ctx.completion, 10 * HZ);\n+\tif (!ret) {\n+\t\tret = -ETIMEDOUT;\n+\t\tgoto free_entry;\n+\t}\n+\n+\tret = ctx.result;\n+\t/* Check if hw returned error for filter creation */\n+\tif (ret) {\n+\t\tnetdev_err(dev, \"%s: filter creation err %d\\n\",\n+\t\t\t   __func__, ret);\n+\t\tgoto free_entry;\n+\t}\n+\n+\tINIT_HLIST_NODE(&ch_flower->link);\n+\tch_flower->tc_flower_cookie = cls->cookie;\n+\tch_flower->filter_id = ctx.tid;\n+\thash_add_rcu(adap->flower_anymatch_tbl, &ch_flower->link, cls->cookie);\n+\n+\treturn ret;\n+\n+free_entry:\n+\tkfree(ch_flower);\n+err:\n+\treturn ret;\n }\n \n int cxgb4_tc_flower_destroy(struct net_device *dev,\n \t\t\t    struct tc_cls_flower_offload *cls)\n {\n-\treturn -EOPNOTSUPP;\n+\tstruct adapter *adap = netdev2adap(dev);\n+\tstruct ch_tc_flower_entry *ch_flower;\n+\tint ret;\n+\n+\tch_flower = ch_flower_lookup(adap, cls->cookie);\n+\tif (!ch_flower) {\n+\t\tret = -ENOENT;\n+\t\tgoto err;\n+\t}\n+\n+\tret = cxgb4_del_filter(dev, ch_flower->filter_id);\n+\tif (ret)\n+\t\tgoto err;\n+\n+\thash_del_rcu(&ch_flower->link);\n+\tkfree_rcu(ch_flower, rcu);\n+\treturn ret;\n+\n+err:\n+\treturn ret;\n }\n \n int cxgb4_tc_flower_stats(struct net_device *dev,\n@@ -55,3 +331,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,\n {\n \treturn -EOPNOTSUPP;\n }\n+\n+void cxgb4_init_tc_flower(struct adapter *adap)\n+{\n+\thash_init(adap->flower_anymatch_tbl);\n+}\ndiff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h\nindex b321fc205b5a..6145a9e056eb 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h\n@@ -37,10 +37,27 @@\n \n #include <net/pkt_cls.h>\n \n+struct ch_tc_flower_stats {\n+\tu64 packet_count;\n+\tu64 byte_count;\n+\tu64 last_used;\n+};\n+\n+struct ch_tc_flower_entry {\n+\tstruct ch_filter_specification fs;\n+\tstruct ch_tc_flower_stats stats;\n+\tunsigned long tc_flower_cookie;\n+\tstruct hlist_node link;\n+\tstruct rcu_head rcu;\n+\tu32 filter_id;\n+};\n+\n int cxgb4_tc_flower_replace(struct net_device *dev,\n \t\t\t    struct tc_cls_flower_offload *cls);\n int cxgb4_tc_flower_destroy(struct net_device *dev,\n \t\t\t    struct tc_cls_flower_offload *cls);\n int cxgb4_tc_flower_stats(struct net_device *dev,\n \t\t\t  struct tc_cls_flower_offload *cls);\n+\n+void cxgb4_init_tc_flower(struct adapter *adap);\n #endif /* __CXGB4_TC_FLOWER_H */\ndiff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h\nindex 84541fce94c5..88487095d14f 100644\n--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h\n+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h\n@@ -212,6 +212,7 @@ struct filter_ctx {\n \n struct ch_filter_specification;\n \n+int cxgb4_get_free_ftid(struct net_device *dev, int family);\n int __cxgb4_set_filter(struct net_device *dev, int filter_id,\n \t\t       struct ch_filter_specification *fs,\n \t\t       struct filter_ctx *ctx);\n",
    "prefixes": [
        "net-next",
        "2/4"
    ]
}