get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 101043,
    "url": "http://patches.dpdk.org/api/patches/101043/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20211011144857.446802-5-andrew.rybchenko@oktetlabs.ru/",
    "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": "<20211011144857.446802-5-andrew.rybchenko@oktetlabs.ru>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211011144857.446802-5-andrew.rybchenko@oktetlabs.ru",
    "date": "2021-10-11T14:48:23",
    "name": "[v2,04/38] net/sfc: insert switchdev mode MAE rules",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "f2a615a1505d2680366e573f94077c93961daf5d",
    "submitter": {
        "id": 2013,
        "url": "http://patches.dpdk.org/api/people/2013/?format=api",
        "name": "Andrew Rybchenko",
        "email": "Andrew.Rybchenko@oktetlabs.ru"
    },
    "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/20211011144857.446802-5-andrew.rybchenko@oktetlabs.ru/mbox/",
    "series": [
        {
            "id": 19526,
            "url": "http://patches.dpdk.org/api/series/19526/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19526",
            "date": "2021-10-11T14:48:19",
            "name": "net/sfc: support port representors",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/19526/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/101043/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/101043/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 91C32A034F;\n\tMon, 11 Oct 2021 16:49:41 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 035984111B;\n\tMon, 11 Oct 2021 16:49:21 +0200 (CEST)",
            "from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113])\n by mails.dpdk.org (Postfix) with ESMTP id 011AC410FF\n for <dev@dpdk.org>; Mon, 11 Oct 2021 16:49:19 +0200 (CEST)",
            "by shelob.oktetlabs.ru (Postfix, from userid 122)\n id C45837F6F3; Mon, 11 Oct 2021 17:49:18 +0300 (MSK)",
            "from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17])\n by shelob.oktetlabs.ru (Postfix) with ESMTP id 5E0C37F6F8;\n Mon, 11 Oct 2021 17:49:07 +0300 (MSK)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=0.8 required=5.0 tests=ALL_TRUSTED,\n DKIM_ADSP_DISCARD,\n URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2",
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 5E0C37F6F8",
        "Authentication-Results": "shelob.oktetlabs.ru/5E0C37F6F8; dkim=none;\n dkim-atps=neutral",
        "From": "Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>",
        "To": "dev@dpdk.org",
        "Cc": "Igor Romanov <igor.romanov@oktetlabs.ru>,\n Andy Moreton <amoreton@xilinx.com>, Ivan Malov <ivan.malov@oktetlabs.ru>",
        "Date": "Mon, 11 Oct 2021 17:48:23 +0300",
        "Message-Id": "<20211011144857.446802-5-andrew.rybchenko@oktetlabs.ru>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20211011144857.446802-1-andrew.rybchenko@oktetlabs.ru>",
        "References": "<20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru>\n <20211011144857.446802-1-andrew.rybchenko@oktetlabs.ru>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v2 04/38] net/sfc: insert switchdev mode MAE rules",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Igor Romanov <igor.romanov@oktetlabs.ru>\n\nBy default, the firmware is in EVB mode, but insertion of the first MAE\nrule resets it to switchdev mode automatically and removes all automatic\nMAE rules added by EVB support. On initialisation, insert MAE rules that\nforward traffic between PHY and PF.\n\nAdd an API for creation and insertion of driver-internal MAE\nrules(flows).\n\nSigned-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>\nSigned-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\nReviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>\n---\n drivers/net/sfc/sfc.c     |   8 ++\n drivers/net/sfc/sfc_mae.c | 211 ++++++++++++++++++++++++++++++++++++++\n drivers/net/sfc/sfc_mae.h |  49 +++++++++\n 3 files changed, 268 insertions(+)",
    "diff": "diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c\nindex 274a98e228..cd2c97f3b2 100644\n--- a/drivers/net/sfc/sfc.c\n+++ b/drivers/net/sfc/sfc.c\n@@ -895,6 +895,10 @@ sfc_attach(struct sfc_adapter *sa)\n \tif (rc != 0)\n \t\tgoto fail_mae_attach;\n \n+\trc = sfc_mae_switchdev_init(sa);\n+\tif (rc != 0)\n+\t\tgoto fail_mae_switchdev_init;\n+\n \tsfc_log_init(sa, \"fini nic\");\n \tefx_nic_fini(enp);\n \n@@ -923,6 +927,9 @@ sfc_attach(struct sfc_adapter *sa)\n \n fail_sw_xstats_init:\n \tsfc_flow_fini(sa);\n+\tsfc_mae_switchdev_fini(sa);\n+\n+fail_mae_switchdev_init:\n \tsfc_mae_detach(sa);\n \n fail_mae_attach:\n@@ -969,6 +976,7 @@ sfc_detach(struct sfc_adapter *sa)\n \n \tsfc_flow_fini(sa);\n \n+\tsfc_mae_switchdev_fini(sa);\n \tsfc_mae_detach(sa);\n \tsfc_mae_counter_rxq_detach(sa);\n \tsfc_filter_detach(sa);\ndiff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c\nindex 4b520bc619..b3607a178b 100644\n--- a/drivers/net/sfc/sfc_mae.c\n+++ b/drivers/net/sfc/sfc_mae.c\n@@ -44,6 +44,139 @@ sfc_mae_counter_registry_fini(struct sfc_mae_counter_registry *registry)\n \tsfc_mae_counters_fini(&registry->counters);\n }\n \n+static int\n+sfc_mae_internal_rule_find_empty_slot(struct sfc_adapter *sa,\n+\t\t\t\t      struct sfc_mae_rule **rule)\n+{\n+\tstruct sfc_mae *mae = &sa->mae;\n+\tstruct sfc_mae_internal_rules *internal_rules = &mae->internal_rules;\n+\tunsigned int entry;\n+\tint rc;\n+\n+\tfor (entry = 0; entry < SFC_MAE_NB_RULES_MAX; entry++) {\n+\t\tif (internal_rules->rules[entry].spec == NULL)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (entry == SFC_MAE_NB_RULES_MAX) {\n+\t\trc = ENOSPC;\n+\t\tsfc_err(sa, \"failed too many rules (%u rules used)\", entry);\n+\t\tgoto fail_too_many_rules;\n+\t}\n+\n+\t*rule = &internal_rules->rules[entry];\n+\n+\treturn 0;\n+\n+fail_too_many_rules:\n+\treturn rc;\n+}\n+\n+int\n+sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa,\n+\t\t\t\t     const efx_mport_sel_t *mport_match,\n+\t\t\t\t     const efx_mport_sel_t *mport_deliver,\n+\t\t\t\t     int prio, struct sfc_mae_rule **rulep)\n+{\n+\tstruct sfc_mae *mae = &sa->mae;\n+\tstruct sfc_mae_rule *rule;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\tif (prio > 0 && (unsigned int)prio >= mae->nb_action_rule_prios_max) {\n+\t\trc = EINVAL;\n+\t\tsfc_err(sa, \"failed: invalid priority %d (max %u)\", prio,\n+\t\t\tmae->nb_action_rule_prios_max);\n+\t\tgoto fail_invalid_prio;\n+\t}\n+\tif (prio < 0)\n+\t\tprio = mae->nb_action_rule_prios_max - 1;\n+\n+\trc = sfc_mae_internal_rule_find_empty_slot(sa, &rule);\n+\tif (rc != 0)\n+\t\tgoto fail_find_empty_slot;\n+\n+\tsfc_log_init(sa, \"init MAE match spec\");\n+\trc = efx_mae_match_spec_init(sa->nic, EFX_MAE_RULE_ACTION,\n+\t\t\t\t     (uint32_t)prio, &rule->spec);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to init MAE match spec\");\n+\t\tgoto fail_match_init;\n+\t}\n+\n+\trc = efx_mae_match_spec_mport_set(rule->spec, mport_match, NULL);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to get MAE match mport selector\");\n+\t\tgoto fail_mport_set;\n+\t}\n+\n+\trc = efx_mae_action_set_spec_init(sa->nic, &rule->actions);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to init MAE action set\");\n+\t\tgoto fail_action_init;\n+\t}\n+\n+\trc = efx_mae_action_set_populate_deliver(rule->actions,\n+\t\t\t\t\t\t mport_deliver);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to populate deliver action\");\n+\t\tgoto fail_populate_deliver;\n+\t}\n+\n+\trc = efx_mae_action_set_alloc(sa->nic, rule->actions,\n+\t\t\t\t      &rule->action_set);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to allocate action set\");\n+\t\tgoto fail_action_set_alloc;\n+\t}\n+\n+\trc = efx_mae_action_rule_insert(sa->nic, rule->spec, NULL,\n+\t\t\t\t\t&rule->action_set,\n+\t\t\t\t\t&rule->rule_id);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to insert action rule\");\n+\t\tgoto fail_rule_insert;\n+\t}\n+\n+\t*rulep = rule;\n+\n+\tsfc_log_init(sa, \"done\");\n+\n+\treturn 0;\n+\n+fail_rule_insert:\n+\tefx_mae_action_set_free(sa->nic, &rule->action_set);\n+\n+fail_action_set_alloc:\n+fail_populate_deliver:\n+\tefx_mae_action_set_spec_fini(sa->nic, rule->actions);\n+\n+fail_action_init:\n+fail_mport_set:\n+\tefx_mae_match_spec_fini(sa->nic, rule->spec);\n+\n+fail_match_init:\n+fail_find_empty_slot:\n+fail_invalid_prio:\n+\tsfc_log_init(sa, \"failed: %s\", rte_strerror(rc));\n+\treturn rc;\n+}\n+\n+void\n+sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule)\n+{\n+\tif (rule == NULL || rule->spec == NULL)\n+\t\treturn;\n+\n+\tefx_mae_action_rule_remove(sa->nic, &rule->rule_id);\n+\tefx_mae_action_set_free(sa->nic, &rule->action_set);\n+\tefx_mae_action_set_spec_fini(sa->nic, rule->actions);\n+\tefx_mae_match_spec_fini(sa->nic, rule->spec);\n+\n+\trule->spec = NULL;\n+}\n+\n int\n sfc_mae_attach(struct sfc_adapter *sa)\n {\n@@ -3443,3 +3576,81 @@ sfc_mae_flow_query(struct rte_eth_dev *dev,\n \t\t\t\"Query for action of this type is not supported\");\n \t}\n }\n+\n+int\n+sfc_mae_switchdev_init(struct sfc_adapter *sa)\n+{\n+\tconst efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);\n+\tstruct sfc_mae *mae = &sa->mae;\n+\tefx_mport_sel_t pf;\n+\tefx_mport_sel_t phy;\n+\tint rc;\n+\n+\tsfc_log_init(sa, \"entry\");\n+\n+\tif (!sa->switchdev) {\n+\t\tsfc_log_init(sa, \"switchdev is not enabled - skip\");\n+\t\treturn 0;\n+\t}\n+\n+\tif (mae->status != SFC_MAE_STATUS_SUPPORTED) {\n+\t\trc = ENOTSUP;\n+\t\tsfc_err(sa, \"failed to init switchdev - no MAE support\");\n+\t\tgoto fail_no_mae;\n+\t}\n+\n+\trc = efx_mae_mport_by_pcie_function(encp->enc_pf, EFX_PCI_VF_INVALID,\n+\t\t\t\t\t    &pf);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed get PF mport\");\n+\t\tgoto fail_pf_get;\n+\t}\n+\n+\trc = efx_mae_mport_by_phy_port(encp->enc_assigned_port, &phy);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed get PHY mport\");\n+\t\tgoto fail_phy_get;\n+\t}\n+\n+\trc = sfc_mae_rule_add_mport_match_deliver(sa, &pf, &phy,\n+\t\t\tSFC_MAE_RULE_PRIO_LOWEST,\n+\t\t\t&mae->switchdev_rule_pf_to_ext);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed add MAE rule to forward from PF to PHY\");\n+\t\tgoto fail_pf_add;\n+\t}\n+\n+\trc = sfc_mae_rule_add_mport_match_deliver(sa, &phy, &pf,\n+\t\t\tSFC_MAE_RULE_PRIO_LOWEST,\n+\t\t\t&mae->switchdev_rule_ext_to_pf);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed add MAE rule to forward from PHY to PF\");\n+\t\tgoto fail_phy_add;\n+\t}\n+\n+\tsfc_log_init(sa, \"done\");\n+\n+\treturn 0;\n+\n+fail_phy_add:\n+\tsfc_mae_rule_del(sa, mae->switchdev_rule_pf_to_ext);\n+\n+fail_pf_add:\n+fail_phy_get:\n+fail_pf_get:\n+fail_no_mae:\n+\tsfc_log_init(sa, \"failed: %s\", rte_strerror(rc));\n+\treturn rc;\n+}\n+\n+void\n+sfc_mae_switchdev_fini(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_mae *mae = &sa->mae;\n+\n+\tif (!sa->switchdev)\n+\t\treturn;\n+\n+\tsfc_mae_rule_del(sa, mae->switchdev_rule_pf_to_ext);\n+\tsfc_mae_rule_del(sa, mae->switchdev_rule_ext_to_pf);\n+}\ndiff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h\nindex 7e3b6a7a97..684f0daf7a 100644\n--- a/drivers/net/sfc/sfc_mae.h\n+++ b/drivers/net/sfc/sfc_mae.h\n@@ -139,6 +139,26 @@ struct sfc_mae_counter_registry {\n \tuint32_t\t\t\tservice_id;\n };\n \n+/** Rules to forward traffic from PHY port to PF and from PF to PHY port */\n+#define SFC_MAE_NB_SWITCHDEV_RULES\t(2)\n+/** Maximum required internal MAE rules */\n+#define SFC_MAE_NB_RULES_MAX\t\t(SFC_MAE_NB_SWITCHDEV_RULES)\n+\n+struct sfc_mae_rule {\n+\tefx_mae_match_spec_t\t\t*spec;\n+\tefx_mae_actions_t\t\t*actions;\n+\tefx_mae_aset_id_t\t\taction_set;\n+\tefx_mae_rule_id_t\t\trule_id;\n+};\n+\n+struct sfc_mae_internal_rules {\n+\t/*\n+\t * Rules required to sustain switchdev mode or to provide\n+\t * port representor functionality.\n+\t */\n+\tstruct sfc_mae_rule\t\trules[SFC_MAE_NB_RULES_MAX];\n+};\n+\n struct sfc_mae {\n \t/** Assigned switch domain identifier */\n \tuint16_t\t\t\tswitch_domain_id;\n@@ -164,6 +184,14 @@ struct sfc_mae {\n \tbool\t\t\t\tcounter_rxq_running;\n \t/** Counter registry */\n \tstruct sfc_mae_counter_registry\tcounter_registry;\n+\t/** Driver-internal flow rules */\n+\tstruct sfc_mae_internal_rules\tinternal_rules;\n+\t/**\n+\t * Switchdev default rules. They forward traffic from PHY port\n+\t * to PF and vice versa.\n+\t */\n+\tstruct sfc_mae_rule\t\t*switchdev_rule_pf_to_ext;\n+\tstruct sfc_mae_rule\t\t*switchdev_rule_ext_to_pf;\n };\n \n struct sfc_adapter;\n@@ -306,6 +334,27 @@ sfc_flow_insert_cb_t sfc_mae_flow_insert;\n sfc_flow_remove_cb_t sfc_mae_flow_remove;\n sfc_flow_query_cb_t sfc_mae_flow_query;\n \n+/**\n+ * The value used to represent the lowest priority.\n+ * Used in MAE rule API.\n+ */\n+#define SFC_MAE_RULE_PRIO_LOWEST\t(-1)\n+\n+/**\n+ * Insert a driver-internal flow rule that matches traffic originating from\n+ * some m-port selector and redirects it to another one\n+ * (eg. PF --> PHY, PHY --> PF).\n+ *\n+ * If requested priority is negative, use the lowest priority.\n+ */\n+int sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa,\n+\t\t\t\t\t const efx_mport_sel_t *mport_match,\n+\t\t\t\t\t const efx_mport_sel_t *mport_deliver,\n+\t\t\t\t\t int prio, struct sfc_mae_rule **rulep);\n+void sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule);\n+int sfc_mae_switchdev_init(struct sfc_adapter *sa);\n+void sfc_mae_switchdev_fini(struct sfc_adapter *sa);\n+\n #ifdef __cplusplus\n }\n #endif\n",
    "prefixes": [
        "v2",
        "04/38"
    ]
}