get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 54677,
    "url": "http://patches.dpdk.org/api/patches/54677/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190611155221.2703-56-leyi.rong@intel.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": "<20190611155221.2703-56-leyi.rong@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190611155221.2703-56-leyi.rong@intel.com",
    "date": "2019-06-11T15:52:10",
    "name": "[v2,55/66] net/ice/base: enable additional switch rules",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f2ddd1112d7d6d4483dd53d9c5bd06e322408bc8",
    "submitter": {
        "id": 1204,
        "url": "http://patches.dpdk.org/api/people/1204/?format=api",
        "name": "Leyi Rong",
        "email": "leyi.rong@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190611155221.2703-56-leyi.rong@intel.com/mbox/",
    "series": [
        {
            "id": 4981,
            "url": "http://patches.dpdk.org/api/series/4981/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4981",
            "date": "2019-06-11T15:51:15",
            "name": "shared code update",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/4981/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/54677/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/54677/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 B1DE81C5F6;\n\tTue, 11 Jun 2019 17:55:37 +0200 (CEST)",
            "from mga12.intel.com (mga12.intel.com [192.55.52.136])\n\tby dpdk.org (Postfix) with ESMTP id 453BA1C36B\n\tfor <dev@dpdk.org>; Tue, 11 Jun 2019 17:54:47 +0200 (CEST)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t11 Jun 2019 08:54:46 -0700",
            "from lrong-srv-03.sh.intel.com ([10.67.119.177])\n\tby orsmga001.jf.intel.com with ESMTP; 11 Jun 2019 08:54:45 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Leyi Rong <leyi.rong@intel.com>",
        "To": "qi.z.zhang@intel.com",
        "Cc": "dev@dpdk.org, Leyi Rong <leyi.rong@intel.com>,\n\tDan Nowlin <dan.nowlin@intel.com>,\n\tPaul M Stillwell Jr <paul.m.stillwell.jr@intel.com>",
        "Date": "Tue, 11 Jun 2019 23:52:10 +0800",
        "Message-Id": "<20190611155221.2703-56-leyi.rong@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190611155221.2703-1-leyi.rong@intel.com>",
        "References": "<20190604054248.68510-1-leyi.rong@intel.com>\n\t<20190611155221.2703-1-leyi.rong@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 55/66] net/ice/base: enable additional switch\n\trules",
        "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": "Add capability to create inner IP and inner TCP switch recipes and\nrules. Change UDP tunnel dummy packet to accommodate the training of\nthese new rules.\n\nSigned-off-by: Dan Nowlin <dan.nowlin@intel.com>\nSigned-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>\nSigned-off-by: Leyi Rong <leyi.rong@intel.com>\n---\n drivers/net/ice/base/ice_protocol_type.h |   8 +-\n drivers/net/ice/base/ice_switch.c        | 361 ++++++++++++-----------\n drivers/net/ice/base/ice_switch.h        |   1 +\n 3 files changed, 203 insertions(+), 167 deletions(-)",
    "diff": "diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h\nindex 82822fb74..38bed7a79 100644\n--- a/drivers/net/ice/base/ice_protocol_type.h\n+++ b/drivers/net/ice/base/ice_protocol_type.h\n@@ -35,6 +35,7 @@ enum ice_protocol_type {\n \tICE_IPV6_IL,\n \tICE_IPV6_OFOS,\n \tICE_TCP_IL,\n+\tICE_UDP_OF,\n \tICE_UDP_ILOS,\n \tICE_SCTP_IL,\n \tICE_VXLAN,\n@@ -112,6 +113,7 @@ enum ice_prot_id {\n #define ICE_IPV6_OFOS_HW\t40\n #define ICE_IPV6_IL_HW\t\t41\n #define ICE_TCP_IL_HW\t\t49\n+#define ICE_UDP_OF_HW\t\t52\n #define ICE_UDP_ILOS_HW\t\t53\n #define ICE_SCTP_IL_HW\t\t96\n \n@@ -188,8 +190,7 @@ struct ice_l4_hdr {\n struct ice_udp_tnl_hdr {\n \tu16 field;\n \tu16 proto_type;\n-\tu16 vni;\n-\tu16 reserved;\n+\tu32 vni;\t/* only use lower 24-bits */\n };\n \n struct ice_nvgre {\n@@ -225,6 +226,7 @@ struct ice_prot_lkup_ext {\n \tu8 n_val_words;\n \t/* create a buffer to hold max words per recipe */\n \tu16 field_off[ICE_MAX_CHAIN_WORDS];\n+\tu16 field_mask[ICE_MAX_CHAIN_WORDS];\n \n \tstruct ice_fv_word fv_words[ICE_MAX_CHAIN_WORDS];\n \n@@ -235,6 +237,7 @@ struct ice_prot_lkup_ext {\n struct ice_pref_recipe_group {\n \tu8 n_val_pairs;\t\t/* Number of valid pairs */\n \tstruct ice_fv_word pairs[ICE_NUM_WORDS_RECIPE];\n+\tu16 mask[ICE_NUM_WORDS_RECIPE];\n };\n \n struct ice_recp_grp_entry {\n@@ -244,6 +247,7 @@ struct ice_recp_grp_entry {\n \tu16 rid;\n \tu8 chain_idx;\n \tu16 fv_idx[ICE_NUM_WORDS_RECIPE];\n+\tu16 fv_mask[ICE_NUM_WORDS_RECIPE];\n \tstruct ice_pref_recipe_group r_group;\n };\n #endif /* _ICE_PROTOCOL_TYPE_H_ */\ndiff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c\nindex c7fcd71a7..0dae1b609 100644\n--- a/drivers/net/ice/base/ice_switch.c\n+++ b/drivers/net/ice/base/ice_switch.c\n@@ -53,60 +53,109 @@ static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,\n \t sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi) + \\\n \t ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi)))\n \n+static const struct ice_dummy_pkt_offsets {\n+\tenum ice_protocol_type type;\n+\tu16 offset; /* ICE_PROTOCOL_LAST indicates end of list */\n+} dummy_gre_packet_offsets[] = {\n+\t{ ICE_MAC_OFOS,\t\t0 },\n+\t{ ICE_IPV4_OFOS,\t14 },\n+\t{ ICE_VXLAN,\t\t34 },\n+\t{ ICE_MAC_IL,\t\t42 },\n+\t{ ICE_IPV4_IL,\t\t54 },\n+\t{ ICE_PROTOCOL_LAST,\t0 },\n+};\n+\n static const\n-u8 dummy_gre_packet[] = { 0, 0, 0, 0,\t\t/* Ether starts */\n+u8 dummy_gre_packet[] = { 0, 0, 0, 0,\t\t/* ICE_MAC_OFOS 0 */\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0x08, 0,\t\t/* Ether ends */\n-\t\t\t  0x45, 0, 0, 0x3E,\t/* IP starts */\n+\t\t\t  0x08, 0,\n+\t\t\t  0x45, 0, 0, 0x3E,\t/* ICE_IPV4_OFOS 14 */\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0, 0x2F, 0, 0,\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0,\t\t/* IP ends */\n-\t\t\t  0x80, 0, 0x65, 0x58,\t/* GRE starts */\n-\t\t\t  0, 0, 0, 0,\t\t/* GRE ends */\n-\t\t\t  0, 0, 0, 0,\t\t/* Ether starts */\n-\t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0,\n-\t\t\t  0x08, 0,\t\t/* Ether ends */\n-\t\t\t  0x45, 0, 0, 0x14,\t/* IP starts */\n \t\t\t  0, 0, 0, 0,\n+\t\t\t  0x80, 0, 0x65, 0x58,\t/* ICE_VXLAN_GRE 34 */\n \t\t\t  0, 0, 0, 0,\n+\t\t\t  0, 0, 0, 0,\t\t/* ICE_MAC_IL 42 */\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0\t\t/* IP ends */\n-\t\t\t};\n-\n-static const u8\n-dummy_udp_tun_packet[] = {0, 0, 0, 0,\t\t/* Ether starts */\n-\t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0,\n-\t\t\t  0x08, 0,\t\t/* Ether ends */\n-\t\t\t  0x45, 0, 0, 0x32,\t/* IP starts */\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0x11, 0, 0,\n+\t\t\t  0x08, 0,\n+\t\t\t  0x45, 0, 0, 0x14,\t/* ICE_IPV4_IL 54 */\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0,\t\t/* IP ends */\n-\t\t\t  0, 0, 0x12, 0xB5,\t/* UDP start*/\n-\t\t\t  0, 0x1E, 0, 0,\t/* UDP end*/\n-\t\t\t  0, 0, 0, 0,\t\t/* VXLAN start */\n-\t\t\t  0, 0, 0, 0,\t\t/* VXLAN end*/\n-\t\t\t  0, 0, 0, 0,\t\t/* Ether starts */\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0\t\t\t/* Ether ends */\n+\t\t\t  0, 0, 0, 0\n \t\t\t};\n \n+static const\n+struct ice_dummy_pkt_offsets dummy_udp_tun_packet_offsets[] = {\n+\t{ ICE_MAC_OFOS,\t\t0 },\n+\t{ ICE_IPV4_OFOS,\t14 },\n+\t{ ICE_UDP_OF,\t\t34 },\n+\t{ ICE_VXLAN,\t\t42 },\n+\t{ ICE_MAC_IL,\t\t50 },\n+\t{ ICE_IPV4_IL,\t\t64 },\n+\t{ ICE_TCP_IL,\t\t84 },\n+\t{ ICE_PROTOCOL_LAST,\t0 },\n+};\n+\n+static const\n+u8 dummy_udp_tun_packet[] = {\n+\t0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x08, 0x00,\n+\n+\t0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */\n+\t0x00, 0x01, 0x00, 0x00,\n+\t0x40, 0x11, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\n+\t0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */\n+\t0x00, 0x46, 0x00, 0x00,\n+\n+\t0x04, 0x00, 0x00, 0x03, /* ICE_VXLAN 42 */\n+\t0x00, 0x00, 0x00, 0x00,\n+\n+\t0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x08, 0x00,\n+\n+\t0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */\n+\t0x00, 0x01, 0x00, 0x00,\n+\t0x40, 0x06, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\n+\t0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x00, 0x00, 0x00, 0x00,\n+\t0x50, 0x02, 0x20, 0x00,\n+\t0x00, 0x00, 0x00, 0x00\n+};\n+\n+static const\n+struct ice_dummy_pkt_offsets dummy_tcp_tun_packet_offsets[] = {\n+\t{ ICE_MAC_OFOS,\t\t0 },\n+\t{ ICE_IPV4_OFOS,\t14 },\n+\t{ ICE_TCP_IL,\t\t34 },\n+\t{ ICE_PROTOCOL_LAST,\t0 },\n+};\n+\n static const u8\n-dummy_tcp_tun_packet[] = {0, 0, 0, 0,\t\t/* Ether starts */\n+dummy_tcp_tun_packet[] = {0, 0, 0, 0,\t\t/* ICE_MAC_OFOS 0 */\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0x08, 0,              /* Ether ends */\n-\t\t\t  0x45, 0, 0, 0x28,     /* IP starts */\n+\t\t\t  0x08, 0,\n+\t\t\t  0x45, 0, 0, 0x28,     /* ICE_IPV4_OFOS 14 */\n \t\t\t  0, 0x01, 0, 0,\n \t\t\t  0x40, 0x06, 0xF5, 0x69,\n \t\t\t  0, 0, 0, 0,\n-\t\t\t  0, 0, 0, 0,   /* IP ends */\n \t\t\t  0, 0, 0, 0,\n+\t\t\t  0, 0, 0, 0,\t\t/* ICE_TCP_IL 34 */\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0, 0, 0, 0,\n \t\t\t  0x50, 0x02, 0x20,\n@@ -184,6 +233,9 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid)\n \t\t\tu8 lkup_indx = root_bufs.content.lkup_indx[i + 1];\n \n \t\t\trg_entry->fv_idx[i] = lkup_indx;\n+\t\t\trg_entry->fv_mask[i] =\n+\t\t\t\tLE16_TO_CPU(root_bufs.content.mask[i + 1]);\n+\n \t\t\t/* If the recipe is a chained recipe then all its\n \t\t\t * child recipe's result will have a result index.\n \t\t\t * To fill fv_words we should not use those result\n@@ -4246,10 +4298,11 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[] = {\n \t{ ICE_IPV6_OFOS,\t{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,\n \t\t\t\t 26, 28, 30, 32, 34, 36, 38 } },\n \t{ ICE_TCP_IL,\t\t{ 0, 2 } },\n+\t{ ICE_UDP_OF,\t\t{ 0, 2 } },\n \t{ ICE_UDP_ILOS,\t\t{ 0, 2 } },\n \t{ ICE_SCTP_IL,\t\t{ 0, 2 } },\n-\t{ ICE_VXLAN,\t\t{ 8, 10, 12 } },\n-\t{ ICE_GENEVE,\t\t{ 8, 10, 12 } },\n+\t{ ICE_VXLAN,\t\t{ 8, 10, 12, 14 } },\n+\t{ ICE_GENEVE,\t\t{ 8, 10, 12, 14 } },\n \t{ ICE_VXLAN_GPE,\t{ 0, 2, 4 } },\n \t{ ICE_NVGRE,\t\t{ 0, 2 } },\n \t{ ICE_PROTOCOL_LAST,\t{ 0 } }\n@@ -4262,11 +4315,14 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[] = {\n  */\n static const struct ice_pref_recipe_group ice_recipe_pack[] = {\n \t{3, { { ICE_MAC_OFOS_HW, 0, 0 }, { ICE_MAC_OFOS_HW, 2, 0 },\n-\t      { ICE_MAC_OFOS_HW, 4, 0 } } },\n+\t      { ICE_MAC_OFOS_HW, 4, 0 } }, { 0xffff, 0xffff, 0xffff, 0xffff } },\n \t{4, { { ICE_MAC_IL_HW, 0, 0 }, { ICE_MAC_IL_HW, 2, 0 },\n-\t      { ICE_MAC_IL_HW, 4, 0 }, { ICE_META_DATA_ID_HW, 44, 0 } } },\n-\t{2, { { ICE_IPV4_IL_HW, 0, 0 }, { ICE_IPV4_IL_HW, 2, 0 } } },\n-\t{2, { { ICE_IPV4_IL_HW, 12, 0 }, { ICE_IPV4_IL_HW, 14, 0 } } },\n+\t      { ICE_MAC_IL_HW, 4, 0 }, { ICE_META_DATA_ID_HW, 44, 0 } },\n+\t\t{ 0xffff, 0xffff, 0xffff, 0xffff } },\n+\t{2, { { ICE_IPV4_IL_HW, 0, 0 }, { ICE_IPV4_IL_HW, 2, 0 } },\n+\t\t{ 0xffff, 0xffff, 0xffff, 0xffff } },\n+\t{2, { { ICE_IPV4_IL_HW, 12, 0 }, { ICE_IPV4_IL_HW, 14, 0 } },\n+\t\t{ 0xffff, 0xffff, 0xffff, 0xffff } },\n };\n \n static const struct ice_protocol_entry ice_prot_id_tbl[] = {\n@@ -4277,6 +4333,7 @@ static const struct ice_protocol_entry ice_prot_id_tbl[] = {\n \t{ ICE_IPV6_OFOS,\tICE_IPV6_OFOS_HW },\n \t{ ICE_IPV6_IL,\t\tICE_IPV6_IL_HW },\n \t{ ICE_TCP_IL,\t\tICE_TCP_IL_HW },\n+\t{ ICE_UDP_OF,\t\tICE_UDP_OF_HW },\n \t{ ICE_UDP_ILOS,\t\tICE_UDP_ILOS_HW },\n \t{ ICE_SCTP_IL,\t\tICE_SCTP_IL_HW },\n \t{ ICE_VXLAN,\t\tICE_UDP_OF_HW },\n@@ -4395,7 +4452,7 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule,\n \tword = lkup_exts->n_val_words;\n \n \tfor (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)\n-\t\tif (((u16 *)&rule->m_u)[j] == 0xffff &&\n+\t\tif (((u16 *)&rule->m_u)[j] &&\n \t\t    rule->type < ARRAY_SIZE(ice_prot_ext)) {\n \t\t\t/* No more space to accommodate */\n \t\t\tif (word >= ICE_MAX_CHAIN_WORDS)\n@@ -4404,6 +4461,7 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule,\n \t\t\t\tice_prot_ext[rule->type].offs[j];\n \t\t\tlkup_exts->fv_words[word].prot_id =\n \t\t\t\tice_prot_id_tbl[rule->type].protocol_id;\n+\t\t\tlkup_exts->field_mask[word] = ((u16 *)&rule->m_u)[j];\n \t\t\tword++;\n \t\t}\n \n@@ -4527,6 +4585,7 @@ ice_create_first_fit_recp_def(struct ice_hw *hw,\n \t\t\t\tlkup_exts->fv_words[j].prot_id;\n \t\t\tgrp->pairs[grp->n_val_pairs].off =\n \t\t\t\tlkup_exts->fv_words[j].off;\n+\t\t\tgrp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];\n \t\t\tgrp->n_val_pairs++;\n \t\t}\n \n@@ -4561,14 +4620,22 @@ ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,\n \n \t\tfor (i = 0; i < rg->r_group.n_val_pairs; i++) {\n \t\t\tstruct ice_fv_word *pr;\n+\t\t\tu16 mask;\n \t\t\tu8 j;\n \n \t\t\tpr = &rg->r_group.pairs[i];\n+\t\t\tmask = rg->r_group.mask[i];\n+\n \t\t\tfor (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)\n \t\t\t\tif (fv_ext[j].prot_id == pr->prot_id &&\n \t\t\t\t    fv_ext[j].off == pr->off) {\n \t\t\t\t\t/* Store index of field vector */\n \t\t\t\t\trg->fv_idx[i] = j;\n+\t\t\t\t\t/* Mask is given by caller as big\n+\t\t\t\t\t * endian, but sent to FW as little\n+\t\t\t\t\t * endian\n+\t\t\t\t\t */\n+\t\t\t\t\trg->fv_mask[i] = mask << 8 | mask >> 8;\n \t\t\t\t\tbreak;\n \t\t\t\t}\n \t\t}\n@@ -4666,7 +4733,8 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,\n \n \t\tfor (i = 0; i < entry->r_group.n_val_pairs; i++) {\n \t\t\tbuf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];\n-\t\t\tbuf[recps].content.mask[i + 1] = CPU_TO_LE16(0xFFFF);\n+\t\t\tbuf[recps].content.mask[i + 1] =\n+\t\t\t\tCPU_TO_LE16(entry->fv_mask[i]);\n \t\t}\n \n \t\tif (rm->n_grp_count > 1) {\n@@ -4888,6 +4956,8 @@ ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,\n \t\trm->n_ext_words = lkup_exts->n_val_words;\n \t\tice_memcpy(&rm->ext_words, lkup_exts->fv_words,\n \t\t\t   sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);\n+\t\tice_memcpy(rm->word_masks, lkup_exts->field_mask,\n+\t\t\t   sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);\n \t\tgoto out;\n \t}\n \n@@ -5089,16 +5159,8 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \treturn status;\n }\n \n-#define ICE_MAC_HDR_OFFSET\t0\n-#define ICE_IP_HDR_OFFSET\t14\n-#define ICE_GRE_HDR_OFFSET\t34\n-#define ICE_MAC_IL_HDR_OFFSET\t42\n-#define ICE_IP_IL_HDR_OFFSET\t56\n-#define ICE_L4_HDR_OFFSET\t34\n-#define ICE_UDP_TUN_HDR_OFFSET\t42\n-\n /**\n- * ice_find_dummy_packet - find dummy packet with given match criteria\n+ * ice_find_dummy_packet - find dummy packet by tunnel type\n  *\n  * @lkups: lookup elements or match criteria for the advanced recipe, one\n  *\t   structure per protocol header\n@@ -5106,17 +5168,20 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n  * @tun_type: tunnel type from the match criteria\n  * @pkt: dummy packet to fill according to filter match criteria\n  * @pkt_len: packet length of dummy packet\n+ * @offsets: pointer to receive the pointer to the offsets for the packet\n  */\n static void\n ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n \t\t      enum ice_sw_tunnel_type tun_type, const u8 **pkt,\n-\t\t      u16 *pkt_len)\n+\t\t      u16 *pkt_len,\n+\t\t      const struct ice_dummy_pkt_offsets **offsets)\n {\n \tu16 i;\n \n \tif (tun_type == ICE_SW_TUN_NVGRE || tun_type == ICE_ALL_TUNNELS) {\n \t\t*pkt = dummy_gre_packet;\n \t\t*pkt_len = sizeof(dummy_gre_packet);\n+\t\t*offsets = dummy_gre_packet_offsets;\n \t\treturn;\n \t}\n \n@@ -5124,6 +5189,7 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n \t    tun_type == ICE_SW_TUN_VXLAN_GPE) {\n \t\t*pkt = dummy_udp_tun_packet;\n \t\t*pkt_len = sizeof(dummy_udp_tun_packet);\n+\t\t*offsets = dummy_udp_tun_packet_offsets;\n \t\treturn;\n \t}\n \n@@ -5131,12 +5197,14 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n \t\tif (lkups[i].type == ICE_UDP_ILOS) {\n \t\t\t*pkt = dummy_udp_tun_packet;\n \t\t\t*pkt_len = sizeof(dummy_udp_tun_packet);\n+\t\t\t*offsets = dummy_udp_tun_packet_offsets;\n \t\t\treturn;\n \t\t}\n \t}\n \n \t*pkt = dummy_tcp_tun_packet;\n \t*pkt_len = sizeof(dummy_tcp_tun_packet);\n+\t*offsets = dummy_tcp_tun_packet_offsets;\n }\n \n /**\n@@ -5145,16 +5213,16 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n  * @lkups: lookup elements or match criteria for the advanced recipe, one\n  *\t   structure per protocol header\n  * @lkups_cnt: number of protocols\n- * @tun_type: to know if the dummy packet is supposed to be tunnel packet\n  * @s_rule: stores rule information from the match criteria\n  * @dummy_pkt: dummy packet to fill according to filter match criteria\n  * @pkt_len: packet length of dummy packet\n+ * @offsets: offset info for the dummy packet\n  */\n-static void\n+static enum ice_status\n ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n-\t\t\t  enum ice_sw_tunnel_type tun_type,\n \t\t\t  struct ice_aqc_sw_rules_elem *s_rule,\n-\t\t\t  const u8 *dummy_pkt, u16 pkt_len)\n+\t\t\t  const u8 *dummy_pkt, u16 pkt_len,\n+\t\t\t  const struct ice_dummy_pkt_offsets *offsets)\n {\n \tu8 *pkt;\n \tu16 i;\n@@ -5167,124 +5235,74 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n \tice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);\n \n \tfor (i = 0; i < lkups_cnt; i++) {\n-\t\tu32 len, pkt_off, hdr_size, field_off;\n+\t\tenum ice_protocol_type type;\n+\t\tu16 offset = 0, len = 0, j;\n+\t\tbool found = false;\n+\n+\t\t/* find the start of this layer; it should be found since this\n+\t\t * was already checked when search for the dummy packet\n+\t\t */\n+\t\ttype = lkups[i].type;\n+\t\tfor (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {\n+\t\t\tif (type == offsets[j].type) {\n+\t\t\t\toffset = offsets[j].offset;\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* this should never happen in a correct calling sequence */\n+\t\tif (!found)\n+\t\t\treturn ICE_ERR_PARAM;\n \n \t\tswitch (lkups[i].type) {\n \t\tcase ICE_MAC_OFOS:\n \t\tcase ICE_MAC_IL:\n-\t\t\tpkt_off = offsetof(struct ice_ether_hdr, dst_addr) +\n-\t\t\t\t((lkups[i].type == ICE_MAC_IL) ?\n-\t\t\t\t ICE_MAC_IL_HDR_OFFSET : 0);\n-\t\t\tlen = sizeof(lkups[i].h_u.eth_hdr.dst_addr);\n-\t\t\tif ((tun_type == ICE_SW_TUN_VXLAN ||\n-\t\t\t     tun_type == ICE_SW_TUN_GENEVE ||\n-\t\t\t     tun_type == ICE_SW_TUN_VXLAN_GPE) &&\n-\t\t\t     lkups[i].type == ICE_MAC_IL) {\n-\t\t\t\tpkt_off += sizeof(struct ice_udp_tnl_hdr);\n-\t\t\t}\n-\n-\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t   &lkups[i].h_u.eth_hdr.dst_addr, len,\n-\t\t\t\t   ICE_NONDMA_TO_NONDMA);\n-\t\t\tpkt_off = offsetof(struct ice_ether_hdr, src_addr) +\n-\t\t\t\t((lkups[i].type == ICE_MAC_IL) ?\n-\t\t\t\t ICE_MAC_IL_HDR_OFFSET : 0);\n-\t\t\tlen = sizeof(lkups[i].h_u.eth_hdr.src_addr);\n-\t\t\tif ((tun_type == ICE_SW_TUN_VXLAN ||\n-\t\t\t     tun_type == ICE_SW_TUN_GENEVE ||\n-\t\t\t     tun_type == ICE_SW_TUN_VXLAN_GPE) &&\n-\t\t\t     lkups[i].type == ICE_MAC_IL) {\n-\t\t\t\tpkt_off += sizeof(struct ice_udp_tnl_hdr);\n-\t\t\t}\n-\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t   &lkups[i].h_u.eth_hdr.src_addr, len,\n-\t\t\t\t   ICE_NONDMA_TO_NONDMA);\n-\t\t\tif (lkups[i].h_u.eth_hdr.ethtype_id) {\n-\t\t\t\tpkt_off = offsetof(struct ice_ether_hdr,\n-\t\t\t\t\t\t   ethtype_id) +\n-\t\t\t\t\t((lkups[i].type == ICE_MAC_IL) ?\n-\t\t\t\t\t ICE_MAC_IL_HDR_OFFSET : 0);\n-\t\t\t\tlen = sizeof(lkups[i].h_u.eth_hdr.ethtype_id);\n-\t\t\t\tif ((tun_type == ICE_SW_TUN_VXLAN ||\n-\t\t\t\t     tun_type == ICE_SW_TUN_GENEVE ||\n-\t\t\t\t     tun_type == ICE_SW_TUN_VXLAN_GPE) &&\n-\t\t\t\t     lkups[i].type == ICE_MAC_IL) {\n-\t\t\t\t\tpkt_off +=\n-\t\t\t\t\t\tsizeof(struct ice_udp_tnl_hdr);\n-\t\t\t\t}\n-\t\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t\t   &lkups[i].h_u.eth_hdr.ethtype_id,\n-\t\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n-\t\t\t}\n+\t\t\tlen = sizeof(struct ice_ether_hdr);\n \t\t\tbreak;\n \t\tcase ICE_IPV4_OFOS:\n-\t\t\thdr_size = sizeof(struct ice_ipv4_hdr);\n-\t\t\tif (lkups[i].h_u.ipv4_hdr.dst_addr) {\n-\t\t\t\tpkt_off = ICE_IP_HDR_OFFSET +\n-\t\t\t\t\t   offsetof(struct ice_ipv4_hdr,\n-\t\t\t\t\t\t    dst_addr);\n-\t\t\t\tfield_off = offsetof(struct ice_ipv4_hdr,\n-\t\t\t\t\t\t     dst_addr);\n-\t\t\t\tlen = hdr_size - field_off;\n-\t\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t\t   &lkups[i].h_u.ipv4_hdr.dst_addr,\n-\t\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n-\t\t\t}\n-\t\t\tif (lkups[i].h_u.ipv4_hdr.src_addr) {\n-\t\t\t\tpkt_off = ICE_IP_HDR_OFFSET +\n-\t\t\t\t\t   offsetof(struct ice_ipv4_hdr,\n-\t\t\t\t\t\t    src_addr);\n-\t\t\t\tfield_off = offsetof(struct ice_ipv4_hdr,\n-\t\t\t\t\t\t     src_addr);\n-\t\t\t\tlen = hdr_size - field_off;\n-\t\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t\t   &lkups[i].h_u.ipv4_hdr.src_addr,\n-\t\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n-\t\t\t}\n-\t\t\tbreak;\n \t\tcase ICE_IPV4_IL:\n+\t\t\tlen = sizeof(struct ice_ipv4_hdr);\n \t\t\tbreak;\n \t\tcase ICE_TCP_IL:\n+\t\tcase ICE_UDP_OF:\n \t\tcase ICE_UDP_ILOS:\n+\t\t\tlen = sizeof(struct ice_l4_hdr);\n+\t\t\tbreak;\n \t\tcase ICE_SCTP_IL:\n-\t\t\thdr_size = sizeof(struct ice_udp_tnl_hdr);\n-\t\t\tif (lkups[i].h_u.l4_hdr.dst_port) {\n-\t\t\t\tpkt_off = ICE_L4_HDR_OFFSET +\n-\t\t\t\t\t   offsetof(struct ice_l4_hdr,\n-\t\t\t\t\t\t    dst_port);\n-\t\t\t\tfield_off = offsetof(struct ice_l4_hdr,\n-\t\t\t\t\t\t     dst_port);\n-\t\t\t\tlen =  hdr_size - field_off;\n-\t\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t\t   &lkups[i].h_u.l4_hdr.dst_port,\n-\t\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n-\t\t\t}\n-\t\t\tif (lkups[i].h_u.l4_hdr.src_port) {\n-\t\t\t\tpkt_off = ICE_L4_HDR_OFFSET +\n-\t\t\t\t\toffsetof(struct ice_l4_hdr, src_port);\n-\t\t\t\tfield_off = offsetof(struct ice_l4_hdr,\n-\t\t\t\t\t\t     src_port);\n-\t\t\t\tlen =  hdr_size - field_off;\n-\t\t\t\tice_memcpy(&pkt[pkt_off],\n-\t\t\t\t\t   &lkups[i].h_u.l4_hdr.src_port,\n-\t\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n-\t\t\t}\n+\t\t\tlen = sizeof(struct ice_sctp_hdr);\n \t\t\tbreak;\n \t\tcase ICE_VXLAN:\n \t\tcase ICE_GENEVE:\n \t\tcase ICE_VXLAN_GPE:\n-\t\t\tpkt_off = ICE_UDP_TUN_HDR_OFFSET +\n-\t\t\t\t   offsetof(struct ice_udp_tnl_hdr, vni);\n-\t\t\tfield_off = offsetof(struct ice_udp_tnl_hdr, vni);\n-\t\t\tlen =  sizeof(struct ice_udp_tnl_hdr) - field_off;\n-\t\t\tice_memcpy(&pkt[pkt_off], &lkups[i].h_u.tnl_hdr.vni,\n-\t\t\t\t   len, ICE_NONDMA_TO_NONDMA);\n+\t\t\tlen = sizeof(struct ice_udp_tnl_hdr);\n \t\t\tbreak;\n \t\tdefault:\n-\t\t\tbreak;\n+\t\t\treturn ICE_ERR_PARAM;\n \t\t}\n+\n+\t\t/* the length should be a word multiple */\n+\t\tif (len % ICE_BYTES_PER_WORD)\n+\t\t\treturn ICE_ERR_CFG;\n+\n+\t\t/* We have the offset to the header start, the length, the\n+\t\t * caller's header values and mask. Use this information to\n+\t\t * copy the data into the dummy packet appropriately based on\n+\t\t * the mask. Note that we need to only write the bits as\n+\t\t * indicated by the mask to make sure we don't improperly write\n+\t\t * over any significant packet data.\n+\t\t */\n+\t\tfor (j = 0; j < len / sizeof(u16); j++)\n+\t\t\tif (((u16 *)&lkups[i].m_u)[j])\n+\t\t\t\t((u16 *)(pkt + offset))[j] =\n+\t\t\t\t\t(((u16 *)(pkt + offset))[j] &\n+\t\t\t\t\t ~((u16 *)&lkups[i].m_u)[j]) |\n+\t\t\t\t\t(((u16 *)&lkups[i].h_u)[j] &\n+\t\t\t\t\t ((u16 *)&lkups[i].m_u)[j]);\n \t}\n+\n \ts_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len);\n+\n+\treturn ICE_SUCCESS;\n }\n \n /**\n@@ -5438,7 +5456,7 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw,\n }\n \n /**\n- * ice_add_adv_rule - create an advanced switch rule\n+ * ice_add_adv_rule - helper function to create an advanced switch rule\n  * @hw: pointer to the hardware structure\n  * @lkups: information on the words that needs to be looked up. All words\n  * together makes one recipe\n@@ -5462,11 +5480,13 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n {\n \tstruct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;\n \tu16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;\n-\tstruct ice_aqc_sw_rules_elem *s_rule;\n+\tconst struct ice_dummy_pkt_offsets *pkt_offsets;\n+\tstruct ice_aqc_sw_rules_elem *s_rule = NULL;\n \tstruct LIST_HEAD_TYPE *rule_head;\n \tstruct ice_switch_info *sw;\n \tenum ice_status status;\n \tconst u8 *pkt = NULL;\n+\tbool found = false;\n \tu32 act = 0;\n \n \tif (!lkups_cnt)\n@@ -5475,13 +5495,25 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \tfor (i = 0; i < lkups_cnt; i++) {\n \t\tu16 j, *ptr;\n \n-\t\t/* Validate match masks to make sure they match complete 16-bit\n-\t\t * words.\n+\t\t/* Validate match masks to make sure that there is something\n+\t\t * to match.\n \t\t */\n-\t\tptr = (u16 *)&lkups->m_u;\n+\t\tptr = (u16 *)&lkups[i].m_u;\n \t\tfor (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)\n-\t\t\tif (ptr[j] != 0 && ptr[j] != 0xffff)\n-\t\t\t\treturn ICE_ERR_PARAM;\n+\t\t\tif (ptr[j] != 0) {\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t}\n+\tif (!found)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\t/* make sure that we can locate a dummy packet */\n+\tice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,\n+\t\t\t      &pkt_offsets);\n+\tif (!pkt) {\n+\t\tstatus = ICE_ERR_PARAM;\n+\t\tgoto err_ice_add_adv_rule;\n \t}\n \n \tif (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||\n@@ -5522,8 +5554,6 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \t\t}\n \t\treturn status;\n \t}\n-\tice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt,\n-\t\t\t      &pkt_len);\n \trule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;\n \ts_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz);\n \tif (!s_rule)\n@@ -5568,8 +5598,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \ts_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid);\n \ts_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);\n \n-\tice_fill_adv_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, s_rule,\n-\t\t\t\t  pkt, pkt_len);\n+\tice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt, pkt_len,\n+\t\t\t\t  pkt_offsets);\n \n \tstatus = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,\n \t\t\t\t rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,\n@@ -5745,11 +5775,12 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \t\t u16 lkups_cnt, struct ice_adv_rule_info *rinfo)\n {\n \tstruct ice_adv_fltr_mgmt_list_entry *list_elem;\n+\tconst struct ice_dummy_pkt_offsets *offsets;\n \tstruct ice_prot_lkup_ext lkup_exts;\n \tu16 rule_buf_sz, pkt_len, i, rid;\n+\tstruct ice_lock *rule_lock; /* Lock to protect filter rule list */\n \tenum ice_status status = ICE_SUCCESS;\n \tbool remove_rule = false;\n-\tstruct ice_lock *rule_lock; /* Lock to protect filter rule list */\n \tconst u8 *pkt = NULL;\n \tu16 vsi_handle;\n \n@@ -5797,7 +5828,7 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \t\tstruct ice_aqc_sw_rules_elem *s_rule;\n \n \t\tice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt,\n-\t\t\t\t      &pkt_len);\n+\t\t\t\t      &pkt_len, &offsets);\n \t\trule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;\n \t\ts_rule =\n \t\t\t(struct ice_aqc_sw_rules_elem *)ice_malloc(hw,\ndiff --git a/drivers/net/ice/base/ice_switch.h b/drivers/net/ice/base/ice_switch.h\nindex b788aa7ec..4c34bc2ea 100644\n--- a/drivers/net/ice/base/ice_switch.h\n+++ b/drivers/net/ice/base/ice_switch.h\n@@ -192,6 +192,7 @@ struct ice_sw_recipe {\n \t * recipe\n \t */\n \tstruct ice_fv_word ext_words[ICE_MAX_CHAIN_WORDS];\n+\tu16 word_masks[ICE_MAX_CHAIN_WORDS];\n \n \t/* if this recipe is a collection of other recipe */\n \tu8 big_recp;\n",
    "prefixes": [
        "v2",
        "55/66"
    ]
}