get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 85277,
    "url": "https://patches.dpdk.org/api/patches/85277/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201217085158.28367-3-orika@nvidia.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": "<20201217085158.28367-3-orika@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201217085158.28367-3-orika@nvidia.com",
    "date": "2020-12-17T08:51:56",
    "name": "[2/4] regex/mlx5: add support for combined rule file",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fd4b358e991a22cab5b1932e1905542f0396bb6b",
    "submitter": {
        "id": 1869,
        "url": "https://patches.dpdk.org/api/people/1869/?format=api",
        "name": "Ori Kam",
        "email": "orika@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201217085158.28367-3-orika@nvidia.com/mbox/",
    "series": [
        {
            "id": 14342,
            "url": "https://patches.dpdk.org/api/series/14342/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14342",
            "date": "2020-12-17T08:51:54",
            "name": "regex/mlx5: pmd improvements",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14342/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/85277/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/85277/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 5F96DA09F0;\n\tThu, 17 Dec 2020 09:53:43 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2B177CA3B;\n\tThu, 17 Dec 2020 09:52:33 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 753F0CA00\n for <dev@dpdk.org>; Thu, 17 Dec 2020 09:52:26 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n orika@nvidia.com) with SMTP; 17 Dec 2020 10:52:21 +0200",
            "from MTL-ORIKA.mtl.com ([172.27.14.211])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BH8qHp4015085;\n Thu, 17 Dec 2020 10:52:21 +0200"
        ],
        "From": "Ori Kam <orika@nvidia.com>",
        "To": "thomas@monjalon.net",
        "Cc": "orika@mellanox.com, dev@dpdk.org",
        "Date": "Thu, 17 Dec 2020 10:51:56 +0200",
        "Message-Id": "<20201217085158.28367-3-orika@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20201217085158.28367-1-orika@nvidia.com>",
        "References": "<20201217085158.28367-1-orika@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 2/4] regex/mlx5: add support for combined rule\n\tfile",
        "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 <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": "The rof file holds programming instructions for\na given HW version.\nIn order to support future generation of HW it\nwas decided that the rof file will hold number\nof rule configurations, and the driver will use\nthe one that matches the HW version.\n\nIn current code we force sync after each write block.\nThis has impact on performance.\n\nThe solution is to move the sync to the end of the\nentire programming sequence.\n\nSigned-off-by: Ori Kam <orika@nvidia.com>\n---\n drivers/regex/mlx5/mlx5_regex.c    |   9 +\n drivers/regex/mlx5/mlx5_regex.h    |   1 +\n drivers/regex/mlx5/mlx5_rxp.c      | 825 ++++++++++++-----------------\n drivers/regex/mlx5/mlx5_rxp_csrs.h |   3 +\n 4 files changed, 352 insertions(+), 486 deletions(-)",
    "diff": "diff --git a/drivers/regex/mlx5/mlx5_regex.c b/drivers/regex/mlx5/mlx5_regex.c\nindex c91c444dda..25eaec5802 100644\n--- a/drivers/regex/mlx5/mlx5_regex.c\n+++ b/drivers/regex/mlx5/mlx5_regex.c\n@@ -119,6 +119,7 @@ mlx5_regex_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \tstruct mlx5_hca_attr attr;\n \tchar name[RTE_REGEXDEV_NAME_MAX_LEN];\n \tint ret;\n+\tuint32_t val;\n \n \tibv = mlx5_regex_get_ib_device_match(&pci_dev->addr);\n \tif (!ibv) {\n@@ -161,6 +162,14 @@ mlx5_regex_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \t}\n \tpriv->ctx = ctx;\n \tpriv->nb_engines = 2; /* attr.regexp_num_of_engines */\n+\tret = mlx5_devx_regex_register_read(priv->ctx, 0,\n+\t\t\t\t\t    MLX5_RXP_CSR_IDENTIFIER, &val);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"CSR read failed!\");\n+\t\treturn -1;\n+\t}\n+\tif (val == MLX5_RXP_BF2_IDENTIFIER)\n+\t\tpriv->is_bf2 = 1;\n \t/* Default RXP programming mode to Shared. */\n \tpriv->prog_mode = MLX5_RXP_SHARED_PROG_MODE;\n \tmlx5_regex_get_name(name, pci_dev);\ndiff --git a/drivers/regex/mlx5/mlx5_regex.h b/drivers/regex/mlx5/mlx5_regex.h\nindex 2c4877c37d..60f29a84d2 100644\n--- a/drivers/regex/mlx5/mlx5_regex.h\n+++ b/drivers/regex/mlx5/mlx5_regex.h\n@@ -80,6 +80,7 @@ struct mlx5_regex_priv {\n \tstruct ibv_pd *pd;\n \tstruct mlx5_dbr_page_list dbrpgs; /* Door-bell pages. */\n \tstruct mlx5_mr_share_cache mr_scache; /* Global shared MR cache. */\n+\tuint8_t is_bf2; /* The device is BF2 device. */\n };\n \n /* mlx5_regex.c */\ndiff --git a/drivers/regex/mlx5/mlx5_rxp.c b/drivers/regex/mlx5/mlx5_rxp.c\nindex bd721f0b11..7bd3b669bc 100644\n--- a/drivers/regex/mlx5/mlx5_rxp.c\n+++ b/drivers/regex/mlx5/mlx5_rxp.c\n@@ -8,6 +8,7 @@\n #include <rte_regexdev.h>\n #include <rte_regexdev_core.h>\n #include <rte_regexdev_driver.h>\n+#include <sys/mman.h>\n \n #include <mlx5_glue.h>\n #include <mlx5_devx_cmds.h>\n@@ -24,6 +25,8 @@\n #define MLX5_REGEX_MAX_RULES_PER_GROUP UINT32_MAX\n #define MLX5_REGEX_MAX_GROUPS MLX5_RXP_MAX_SUBSETS\n \n+#define MLX5_REGEX_RXP_ROF2_LINE_LEN 34\n+\n /* Private Declarations */\n static int\n rxp_poll_csr_for_value(struct ibv_context *ctx, uint32_t *value,\n@@ -36,30 +39,15 @@ mlnx_resume_database(struct mlx5_regex_priv *priv, uint8_t id);\n static int\n mlnx_update_database(struct mlx5_regex_priv *priv, uint8_t id);\n static int\n-program_rxp_rules(struct mlx5_regex_priv *priv,\n-\t\t  struct mlx5_rxp_ctl_rules_pgm *rules, uint8_t id);\n+program_rxp_rules(struct mlx5_regex_priv *priv, const char *buf, uint32_t len,\n+\t\t  uint8_t id);\n static int\n rxp_init_eng(struct mlx5_regex_priv *priv, uint8_t id);\n static int\n-write_private_rules(struct mlx5_regex_priv *priv,\n-\t\t    struct mlx5_rxp_ctl_rules_pgm *rules,\n-\t\t    uint8_t id);\n-static int\n-write_shared_rules(struct mlx5_regex_priv *priv,\n-\t\t   struct mlx5_rxp_ctl_rules_pgm *rules, uint32_t count,\n-\t\t   uint8_t db_to_program);\n-static int\n rxp_db_setup(struct mlx5_regex_priv *priv);\n static void\n rxp_dump_csrs(struct ibv_context *ctx, uint8_t id);\n static int\n-rxp_write_rules_via_cp(struct ibv_context *ctx,\n-\t\t       struct mlx5_rxp_rof_entry *rules,\n-\t\t       int count, uint8_t id);\n-static int\n-rxp_flush_rules(struct ibv_context *ctx, struct mlx5_rxp_rof_entry *rules,\n-\t\tint count, uint8_t id);\n-static int\n rxp_start_engine(struct ibv_context *ctx, uint8_t id);\n static int\n rxp_stop_engine(struct ibv_context *ctx, uint8_t id);\n@@ -123,110 +111,6 @@ mlx5_regex_info_get(struct rte_regexdev *dev __rte_unused,\n \treturn 0;\n }\n \n-/**\n- * Actual writing of RXP instructions to RXP via CSRs.\n- */\n-static int\n-rxp_write_rules_via_cp(struct ibv_context *ctx,\n-\t\t       struct mlx5_rxp_rof_entry *rules,\n-\t\t       int count, uint8_t id)\n-{\n-\tint i, ret = 0;\n-\tuint32_t tmp;\n-\n-\tfor (i = 0; i < count; i++) {\n-\t\ttmp = (uint32_t)rules[i].value;\n-\t\tret |= mlx5_devx_regex_register_write(ctx, id,\n-\t\t\t\t\t\t      MLX5_RXP_RTRU_CSR_DATA_0,\n-\t\t\t\t\t\t      tmp);\n-\t\ttmp = (uint32_t)(rules[i].value >> 32);\n-\t\tret |= mlx5_devx_regex_register_write(ctx, id,\n-\t\t\t\t\t\t      MLX5_RXP_RTRU_CSR_DATA_0 +\n-\t\t\t\t\t\t      MLX5_RXP_CSR_WIDTH, tmp);\n-\t\ttmp = rules[i].addr;\n-\t\tret |= mlx5_devx_regex_register_write(ctx, id,\n-\t\t\t\t\t\t      MLX5_RXP_RTRU_CSR_ADDR,\n-\t\t\t\t\t\t      tmp);\n-\t\tif (ret) {\n-\t\t\tDRV_LOG(ERR, \"Failed to copy instructions to RXP.\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\tDRV_LOG(DEBUG, \"Written %d instructions\", count);\n-\treturn 0;\n-}\n-\n-static int\n-rxp_flush_rules(struct ibv_context *ctx, struct mlx5_rxp_rof_entry *rules,\n-\t\tint count, uint8_t id)\n-{\n-\tuint32_t val, fifo_depth;\n-\tint ret;\n-\n-\tret = rxp_write_rules_via_cp(ctx, rules, count, id);\n-\tif (ret < 0) {\n-\t\tDRV_LOG(ERR, \"Failed to write rules via CSRs.\");\n-\t\treturn -1;\n-\t}\n-\tret = mlx5_devx_regex_register_read(ctx, id,\n-\t\t\t\t\t    MLX5_RXP_RTRU_CSR_CAPABILITY,\n-\t\t\t\t\t    &fifo_depth);\n-\tif (ret) {\n-\t\tDRV_LOG(ERR, \"CSR read failed!\");\n-\t\treturn -1;\n-\t}\n-\tret = rxp_poll_csr_for_value(ctx, &val, MLX5_RXP_RTRU_CSR_FIFO_STAT,\n-\t\t\t\t     count, ~0,\n-\t\t\t\t     MLX5_RXP_POLL_CSR_FOR_VALUE_TIMEOUT, id);\n-\tif (ret < 0) {\n-\t\tif (ret == -EBUSY)\n-\t\t\tDRV_LOG(ERR, \"Rules not rx by RXP: credit: %d, depth:\"\n-\t\t\t\t\" %d\", val, fifo_depth);\n-\t\telse\n-\t\t\tDRV_LOG(ERR, \"CSR poll failed, can't read value!\");\n-\t\treturn ret;\n-\t}\n-\tDRV_LOG(DEBUG, \"RTRU FIFO depth: 0x%x\", fifo_depth);\n-\tret = mlx5_devx_regex_register_read(ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n-\t\t\t\t\t    &val);\n-\tif (ret) {\n-\t\tDRV_LOG(ERR, \"CSR read failed!\");\n-\t\treturn -1;\n-\t}\n-\tval |= MLX5_RXP_RTRU_CSR_CTRL_GO;\n-\tret = mlx5_devx_regex_register_write(ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n-\t\t\t\t\t     val);\n-\tif (ret) {\n-\t\tDRV_LOG(ERR, \"CSR write failed!\");\n-\t\treturn -1;\n-\t}\n-\tret = rxp_poll_csr_for_value(ctx, &val, MLX5_RXP_RTRU_CSR_STATUS,\n-\t\t\t\t     MLX5_RXP_RTRU_CSR_STATUS_UPDATE_DONE,\n-\t\t\t\t     MLX5_RXP_RTRU_CSR_STATUS_UPDATE_DONE,\n-\t\t\t\t     MLX5_RXP_POLL_CSR_FOR_VALUE_TIMEOUT, id);\n-\tif (ret < 0) {\n-\t\tif (ret == -EBUSY)\n-\t\t\tDRV_LOG(ERR, \"Rules update timeout: 0x%08X\", val);\n-\t\telse\n-\t\t\tDRV_LOG(ERR, \"CSR poll failed, can't read value!\");\n-\t\treturn ret;\n-\t}\n-\tif (mlx5_devx_regex_register_read(ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n-\t\t\t\t\t  &val)) {\n-\t\tDRV_LOG(ERR, \"CSR read failed!\");\n-\t\treturn -1;\n-\t}\n-\tval &= ~(MLX5_RXP_RTRU_CSR_CTRL_GO);\n-\tif (mlx5_devx_regex_register_write(ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n-\t\t\t\t\t   val)) {\n-\t\tDRV_LOG(ERR, \"CSR write failed!\");\n-\t\treturn -1;\n-\t}\n-\n-\tDRV_LOG(DEBUG, \"RXP Flush rules finished.\");\n-\treturn 0;\n-}\n-\n static int\n rxp_poll_csr_for_value(struct ibv_context *ctx, uint32_t *value,\n \t\t       uint32_t address, uint32_t expected_value,\n@@ -278,13 +162,14 @@ rxp_stop_engine(struct ibv_context *ctx, uint8_t id)\n }\n \n static int\n-rxp_init_rtru(struct ibv_context *ctx, uint8_t id, uint32_t init_bits)\n+rxp_init_rtru(struct mlx5_regex_priv *priv, uint8_t id, uint32_t init_bits)\n {\n \tuint32_t ctrl_value;\n \tuint32_t poll_value;\n \tuint32_t expected_value;\n \tuint32_t expected_mask;\n-\tint ret;\n+\tstruct ibv_context *ctx = priv->ctx;\n+\tint ret = 0;\n \n \t/* Read the rtru ctrl CSR. */\n \tret = mlx5_devx_regex_register_read(ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n@@ -317,13 +202,15 @@ rxp_init_rtru(struct ibv_context *ctx, uint8_t id, uint32_t init_bits)\n \t/* Check that the following bits are set in the RTRU_CSR. */\n \tif (init_bits == MLX5_RXP_RTRU_CSR_CTRL_INIT_MODE_L1_L2) {\n \t\t/* Must be incremental mode */\n-\t\texpected_value = MLX5_RXP_RTRU_CSR_STATUS_L1C_INIT_DONE |\n-\t\t\tMLX5_RXP_RTRU_CSR_STATUS_L2C_INIT_DONE;\n+\t\texpected_value = MLX5_RXP_RTRU_CSR_STATUS_L1C_INIT_DONE;\n \t} else {\n \t\texpected_value = MLX5_RXP_RTRU_CSR_STATUS_IM_INIT_DONE |\n-\t\t\tMLX5_RXP_RTRU_CSR_STATUS_L1C_INIT_DONE |\n-\t\t\tMLX5_RXP_RTRU_CSR_STATUS_L2C_INIT_DONE;\n+\t\t\tMLX5_RXP_RTRU_CSR_STATUS_L1C_INIT_DONE;\n \t}\n+\tif (priv->is_bf2)\n+\t\texpected_value |= MLX5_RXP_RTRU_CSR_STATUS_L2C_INIT_DONE;\n+\n+\n \texpected_mask = expected_value;\n \tret = rxp_poll_csr_for_value(ctx, &poll_value,\n \t\t\t\t     MLX5_RXP_RTRU_CSR_STATUS,\n@@ -340,69 +227,274 @@ rxp_init_rtru(struct ibv_context *ctx, uint8_t id, uint32_t init_bits)\n }\n \n static int\n-rxp_parse_rof(const char *buf, uint32_t len,\n-\t      struct mlx5_rxp_ctl_rules_pgm **rules)\n+rxp_parse_line(char *line, uint32_t *type, uint32_t *address, uint64_t *value)\n+{\n+\tchar *cur_pos;\n+\n+\tif (*line == '\\0' || *line == '#')\n+\t\treturn  1;\n+\t*type = strtoul(line, &cur_pos, 10);\n+\tif (*cur_pos != ',' && *cur_pos != '\\0')\n+\t\treturn -1;\n+\t*address = strtoul(cur_pos+1, &cur_pos, 16);\n+\tif (*cur_pos != ',' && *cur_pos != '\\0')\n+\t\treturn -1;\n+\t*value = strtoul(cur_pos+1, &cur_pos, 16);\n+\tif (*cur_pos != ',' && *cur_pos != '\\0')\n+\t\treturn -1;\n+\treturn 0;\n+}\n+\n+static uint32_t\n+rxp_get_reg_address(uint32_t address)\n+{\n+\tuint32_t block;\n+\tuint32_t reg;\n+\n+\tblock = (address >> 16) & 0xFFFF;\n+\tif (block == 0)\n+\t\treg = MLX5_RXP_CSR_BASE_ADDRESS;\n+\telse if (block == 1)\n+\t\treg = MLX5_RXP_RTRU_CSR_BASE_ADDRESS;\n+\telse {\n+\t\tDRV_LOG(ERR, \"Invalid ROF register 0x%08X!\", address);\n+\t\t\treturn UINT32_MAX;\n+\t}\n+\treg += (address & 0xFFFF) * MLX5_RXP_CSR_WIDTH;\n+\treturn reg;\n+}\n+\n+static int\n+rxp_program_rof(struct mlx5_regex_priv *priv, const char *buf, uint32_t len,\n+\t\tuint8_t id)\n {\n \tstatic const char del[] = \"\\n\\r\";\n \tchar *line;\n \tchar *tmp;\n-\tchar *cur_pos;\n-\tuint32_t lines = 0;\n-\tuint32_t entries;\n-\tstruct mlx5_rxp_rof_entry *curentry;\n+\tuint32_t type = 0;\n+\tuint32_t address;\n+\tuint64_t val;\n+\tuint32_t reg_val;\n+\tint ret;\n+\tint skip = -1;\n+\tint last = 0;\n+\tuint32_t temp;\n+\tuint32_t tmp_addr;\n+\tuint32_t rof_rule_addr;\n+\tuint64_t tmp_write_swap[4];\n+\tstruct mlx5_rxp_rof_entry rules[8];\n+\tint i;\n+\tint db_free;\n+\tint j;\n \n \ttmp = rte_malloc(\"\", len, 0);\n \tif (!tmp)\n \t\treturn -ENOMEM;\n \tmemcpy(tmp, buf, len);\n-\tline = strtok(tmp, del);\n-\twhile (line) {\n-\t\tif (line[0] != '#' && line[0] != '\\0')\n-\t\t\tlines++;\n-\t\tline = strtok(NULL, del);\n-\t}\n-\t*rules = rte_malloc(\"\", lines * sizeof(*curentry) + sizeof(**rules), 0);\n-\tif (!(*rules)) {\n+\tdb_free = mlnx_update_database(priv, id);\n+\tif (db_free < 0) {\n+\t\tDRV_LOG(ERR, \"Failed to setup db memory!\");\n \t\trte_free(tmp);\n-\t\treturn -ENOMEM;\n+\t\treturn db_free;\n \t}\n-\tmemset(*rules, 0, lines * sizeof(curentry) + sizeof(**rules));\n-\tcurentry = (*rules)->rules;\n-\t(*rules)->hdr.cmd = MLX5_RXP_CTL_RULES_PGM;\n-\tentries = 0;\n-\tmemcpy(tmp, buf, len);\n-\tline = strtok(tmp, del);\n-\twhile (line) {\n-\t\tif (line[0] == '#' || line[0] == '\\0') {\n-\t\t\tline = strtok(NULL, del);\n+\tfor (line = strtok(tmp, del), j = 0; line; line = strtok(NULL, del),\n+\t     j++, last = type) {\n+\t\tret = rxp_parse_line(line, &type, &address, &val);\n+\t\tif (ret != 0) {\n+\t\t\tif (ret < 0)\n+\t\t\t\tgoto parse_error;\n \t\t\tcontinue;\n \t\t}\n-\t\tcurentry->type = strtoul(line, &cur_pos, 10);\n-\t\tif (cur_pos == line || cur_pos[0] != ',')\n-\t\t\tgoto parse_error;\n-\t\tcur_pos++;\n-\t\tcurentry->addr = strtoul(cur_pos, &cur_pos, 16);\n-\t\tif (cur_pos[0] != ',')\n-\t\t\tgoto parse_error;\n-\t\tcur_pos++;\n-\t\tcurentry->value = strtoull(cur_pos, &cur_pos, 16);\n-\t\tif (cur_pos[0] != '\\0' && cur_pos[0] != '\\n')\n-\t\t\tgoto parse_error;\n-\t\tcurentry++;\n-\t\tentries++;\n-\t\tif (entries > lines)\n-\t\t\tgoto parse_error;\n-\t\tline = strtok(NULL, del);\n-\t}\n-\t(*rules)->count = entries;\n-\t(*rules)->hdr.len = entries * sizeof(*curentry) + sizeof(**rules);\n+\t\tswitch (type) {\n+\t\tcase MLX5_RXP_ROF_ENTRY_EQ:\n+\t\t\tif (skip == 0 && address == 0)\n+\t\t\t\tskip = 1;\n+\t\t\ttmp_addr = rxp_get_reg_address(address);\n+\t\t\tif (tmp_addr == UINT32_MAX)\n+\t\t\t\tgoto parse_error;\n+\t\t\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t\t\t    tmp_addr, &reg_val);\n+\t\t\tif (ret)\n+\t\t\t\tgoto parse_error;\n+\t\t\tif (skip == -1 && address == 0) {\n+\t\t\t\tif (val == reg_val) {\n+\t\t\t\t\tskip = 0;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t} else if (skip == 0) {\n+\t\t\t\tif (val != reg_val) {\n+\t\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\t\"got %08X expected == %\" PRIx64,\n+\t\t\t\t\t\treg_val, val);\n+\t\t\t\t\tgoto parse_error;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_GTE:\n+\t\t\tif (skip == 0 && address == 0)\n+\t\t\t\tskip = 1;\n+\t\t\ttmp_addr = rxp_get_reg_address(address);\n+\t\t\tif (tmp_addr == UINT32_MAX)\n+\t\t\t\tgoto parse_error;\n+\t\t\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t\t\t    tmp_addr, &reg_val);\n+\t\t\tif (ret)\n+\t\t\t\tgoto parse_error;\n+\t\t\tif (skip == -1 && address == 0) {\n+\t\t\t\tif (reg_val >= val) {\n+\t\t\t\t\tskip = 0;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t} else if (skip == 0) {\n+\t\t\t\tif (reg_val < val) {\n+\t\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\t\"got %08X expected >= %\" PRIx64,\n+\t\t\t\t\t\treg_val, val);\n+\t\t\t\t\tgoto parse_error;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_LTE:\n+\t\t\ttmp_addr = rxp_get_reg_address(address);\n+\t\t\tif (tmp_addr == UINT32_MAX)\n+\t\t\t\tgoto parse_error;\n+\t\t\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t\t\t    tmp_addr, &reg_val);\n+\t\t\tif (ret)\n+\t\t\t\tgoto parse_error;\n+\t\t\tif (skip == 0 && address == 0 &&\n+\t\t\t    last != MLX5_RXP_ROF_ENTRY_GTE) {\n+\t\t\t\tskip = 1;\n+\t\t\t} else if (skip == 0 && address == 0 &&\n+\t\t\t\t   last == MLX5_RXP_ROF_ENTRY_GTE) {\n+\t\t\t\tif (reg_val > val)\n+\t\t\t\t\tskip = -1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (skip == -1 && address == 0) {\n+\t\t\t\tif (reg_val <= val) {\n+\t\t\t\t\tskip = 0;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t} else if (skip == 0) {\n+\t\t\t\tif (reg_val > val) {\n+\t\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\t\"got %08X expected <= %\" PRIx64,\n+\t\t\t\t\t\treg_val, val);\n+\t\t\t\t\tgoto parse_error;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_CHECKSUM:\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_CHECKSUM_EX_EM:\n+\t\t\tif (skip)\n+\t\t\t\tcontinue;\n+\t\t\ttmp_addr = rxp_get_reg_address(address);\n+\t\t\tif (tmp_addr == UINT32_MAX)\n+\t\t\t\tgoto parse_error;\n+\n+\t\t\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t\t\t    tmp_addr, &reg_val);\n+\t\t\tif (ret) {\n+\t\t\t\tDRV_LOG(ERR, \"RXP CSR read failed!\");\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\t\t\tif (reg_val != val) {\n+\t\t\t\tDRV_LOG(ERR, \"got %08X expected <= %\" PRIx64,\n+\t\t\t\t\treg_val, val);\n+\t\t\t\tgoto parse_error;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_IM:\n+\t\t\tif (skip)\n+\t\t\t\tcontinue;\n+\t\t\t/*\n+\t\t\t * NOTE: All rules written to RXP must be carried out in\n+\t\t\t * triplets of: 2xData + 1xAddr.\n+\t\t\t * No optimisation is currently allowed in this\n+\t\t\t * sequence to perform less writes.\n+\t\t\t */\n+\t\t\ttemp = val;\n+\t\t\tret |= mlx5_devx_regex_register_write\n+\t\t\t\t\t(priv->ctx, id,\n+\t\t\t\t\t MLX5_RXP_RTRU_CSR_DATA_0, temp);\n+\t\t\ttemp = (uint32_t)(val >> 32);\n+\t\t\tret |= mlx5_devx_regex_register_write\n+\t\t\t\t\t(priv->ctx, id,\n+\t\t\t\t\t MLX5_RXP_RTRU_CSR_DATA_0 +\n+\t\t\t\t\t MLX5_RXP_CSR_WIDTH, temp);\n+\t\t\ttemp = address;\n+\t\t\tret |= mlx5_devx_regex_register_write\n+\t\t\t\t\t(priv->ctx, id, MLX5_RXP_RTRU_CSR_ADDR,\n+\t\t\t\t\t temp);\n+\t\t\tif (ret) {\n+\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\"Failed to copy instructions to RXP.\");\n+\t\t\t\tgoto parse_error;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase MLX5_RXP_ROF_ENTRY_EM:\n+\t\t\tif (skip)\n+\t\t\t\tcontinue;\n+\t\t\tfor (i = 0; i < 7; i++) {\n+\t\t\t\tret = rxp_parse_line(line, &type,\n+\t\t\t\t\t\t     &rules[i].addr,\n+\t\t\t\t\t\t     &rules[i].value);\n+\t\t\t\tif (ret != 0)\n+\t\t\t\t\tgoto parse_error;\n+\t\t\t\tline = strtok(NULL, del);\n+\t\t\t\tif (!line)\n+\t\t\t\t\tgoto parse_error;\n+\t\t\t}\n+\t\t\tif ((uint8_t *)((uint8_t *)\n+\t\t\t\t\tpriv->db[id].ptr +\n+\t\t\t\t\t((rules[7].addr <<\n+\t\t\t\t\t MLX5_RXP_INST_OFFSET))) >=\n+\t\t\t\t\t((uint8_t *)((uint8_t *)\n+\t\t\t\t\tpriv->db[id].ptr + MLX5_MAX_DB_SIZE))) {\n+\t\t\t\tDRV_LOG(ERR, \"DB exceeded memory!\");\n+\t\t\t\tgoto parse_error;\n+\t\t\t}\n+\t\t\t/*\n+\t\t\t * Rule address Offset to align with RXP\n+\t\t\t * external instruction offset.\n+\t\t\t */\n+\t\t\trof_rule_addr = (rules[0].addr << MLX5_RXP_INST_OFFSET);\n+\t\t\t/* 32 byte instruction swap (sw work around)! */\n+\t\t\ttmp_write_swap[0] = le64toh(rules[4].value);\n+\t\t\ttmp_write_swap[1] = le64toh(rules[5].value);\n+\t\t\ttmp_write_swap[2] = le64toh(rules[6].value);\n+\t\t\ttmp_write_swap[3] = le64toh(rules[7].value);\n+\t\t\t/* Write only 4 of the 8 instructions. */\n+\t\t\tmemcpy((uint8_t *)((uint8_t *)\n+\t\t\t\tpriv->db[id].ptr + rof_rule_addr),\n+\t\t\t\t&tmp_write_swap, (sizeof(uint64_t) * 4));\n+\t\t\t/* Write 1st 4 rules of block after last 4. */\n+\t\t\trof_rule_addr = (rules[4].addr << MLX5_RXP_INST_OFFSET);\n+\t\t\ttmp_write_swap[0] = le64toh(rules[0].value);\n+\t\t\ttmp_write_swap[1] = le64toh(rules[1].value);\n+\t\t\ttmp_write_swap[2] = le64toh(rules[2].value);\n+\t\t\ttmp_write_swap[3] = le64toh(rules[3].value);\n+\t\t\tmemcpy((uint8_t *)((uint8_t *)\n+\t\t\t\tpriv->db[id].ptr + rof_rule_addr),\n+\t\t\t\t&tmp_write_swap, (sizeof(uint64_t) * 4));\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\t}\n+\tret = mlnx_set_database(priv, id, db_free);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(ERR, \"Failed to register db memory!\");\n+\t\tgoto parse_error;\n+\t}\n \trte_free(tmp);\n \treturn 0;\n parse_error:\n \trte_free(tmp);\n-\tif (*rules)\n-\t\trte_free(*rules);\n-\treturn -EINVAL;\n+\treturn ret;\n }\n \n static int\n@@ -488,43 +580,81 @@ mlnx_update_database(struct mlx5_regex_priv *priv, uint8_t id)\n  * Program RXP instruction db to RXP engine/s.\n  */\n static int\n-program_rxp_rules(struct mlx5_regex_priv *priv,\n-\t\t  struct mlx5_rxp_ctl_rules_pgm *rules, uint8_t id)\n+program_rxp_rules(struct mlx5_regex_priv *priv, const char *buf, uint32_t len,\n+\t\t  uint8_t id)\n {\n-\tint ret, db_free;\n-\tuint32_t rule_cnt;\n+\tint ret;\n+\tint db_free;\n+\tuint32_t val;\n \n-\trule_cnt = rules->count;\n \tdb_free = mlnx_update_database(priv, id);\n \tif (db_free < 0) {\n \t\tDRV_LOG(ERR, \"Failed to setup db memory!\");\n \t\treturn db_free;\n \t}\n-\tif (priv->prog_mode == MLX5_RXP_PRIVATE_PROG_MODE) {\n-\t\t/* Register early to ensure RXP writes to EM use valid addr. */\n-\t\tret = mlnx_set_database(priv, id, db_free);\n-\t\tif (ret < 0) {\n-\t\t\tDRV_LOG(ERR, \"Failed to register db memory!\");\n-\t\t\treturn ret;\n-\t\t}\n-\t}\n-\tret = write_private_rules(priv, rules, id);\n-\tif (ret < 0) {\n-\t\tDRV_LOG(ERR, \"Failed to write rules!\");\n+\tret = rxp_init_eng(priv, id);\n+\tif (ret < 0)\n \t\treturn ret;\n+\t/* Confirm the RXP is initialised. */\n+\tif (mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t    MLX5_RXP_CSR_STATUS, &val)) {\n+\t\tDRV_LOG(ERR, \"Failed to read from RXP!\");\n+\t\treturn -ENODEV;\n+\t}\n+\tif (!(val & MLX5_RXP_CSR_STATUS_INIT_DONE)) {\n+\t\tDRV_LOG(ERR, \"RXP not initialised...\");\n+\t\treturn -EBUSY;\n+\t}\n+\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n+\t\t\t\t\t    MLX5_RXP_RTRU_CSR_CTRL, &val);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"CSR read failed!\");\n+\t\treturn -1;\n \t}\n-\tif (priv->prog_mode == MLX5_RXP_SHARED_PROG_MODE) {\n-\t\t/* Write external rules directly to EM. */\n-\t\trules->count = rule_cnt;\n-\t       /* Now write external instructions to EM. */\n-\t\tret = write_shared_rules(priv, rules, rules->hdr.len, db_free);\n+\tval |= MLX5_RXP_RTRU_CSR_CTRL_GO;\n+\tret = mlx5_devx_regex_register_write(priv->ctx, id,\n+\t\t\t\t\t     MLX5_RXP_RTRU_CSR_CTRL, val);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"Can't program rof file!\");\n+\t\treturn -1;\n+\t}\n+\tret = rxp_program_rof(priv, buf, len, id);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"Can't program rof file!\");\n+\t\treturn -1;\n+\t}\n+\tif (priv->is_bf2) {\n+\t\tret = rxp_poll_csr_for_value\n+\t\t\t(priv->ctx, &val, MLX5_RXP_RTRU_CSR_STATUS,\n+\t\t\t MLX5_RXP_RTRU_CSR_STATUS_UPDATE_DONE,\n+\t\t\t MLX5_RXP_RTRU_CSR_STATUS_UPDATE_DONE,\n+\t\t\t MLX5_RXP_POLL_CSR_FOR_VALUE_TIMEOUT, id);\n \t\tif (ret < 0) {\n-\t\t\tDRV_LOG(ERR, \"Failed to write EM rules!\");\n+\t\t\tDRV_LOG(ERR, \"Rules update timeout: 0x%08X\", val);\n \t\t\treturn ret;\n \t\t}\n-\t\tret = mlnx_set_database(priv, id, db_free);\n-\t\tif (ret < 0) {\n-\t\t\tDRV_LOG(ERR, \"Failed to register db memory!\");\n+\t\tDRV_LOG(DEBUG, \"Rules update took %d cycles\", ret);\n+\t}\n+\tif (mlx5_devx_regex_register_read(priv->ctx, id, MLX5_RXP_RTRU_CSR_CTRL,\n+\t\t\t\t\t  &val)) {\n+\t\tDRV_LOG(ERR, \"CSR read failed!\");\n+\t\treturn -1;\n+\t}\n+\tval &= ~(MLX5_RXP_RTRU_CSR_CTRL_GO);\n+\tif (mlx5_devx_regex_register_write(priv->ctx, id,\n+\t\t\t\t\t   MLX5_RXP_RTRU_CSR_CTRL, val)) {\n+\t\tDRV_LOG(ERR, \"CSR write write failed!\");\n+\t\treturn -1;\n+\t}\n+\tif (priv->is_bf2) {\n+\t\tret = rxp_poll_csr_for_value(priv->ctx, &val,\n+\t\t\t\t\t     MLX5_RXP_CSR_STATUS,\n+\t\t\t\t\t     MLX5_RXP_CSR_STATUS_INIT_DONE,\n+\t\t\t\t\t     MLX5_RXP_CSR_STATUS_INIT_DONE,\n+\t\t\t\t\t     MLX5_RXP_CSR_STATUS_TRIAL_TIMEOUT,\n+\t\t\t\t\t     id);\n+\t\tif (ret) {\n+\t\t\tDRV_LOG(ERR, \"Device init failed!\");\n \t\t\treturn ret;\n \t\t}\n \t}\n@@ -533,9 +663,9 @@ program_rxp_rules(struct mlx5_regex_priv *priv,\n \t\tDRV_LOG(ERR, \"Failed to resume engine!\");\n \t\treturn ret;\n \t}\n-\tDRV_LOG(DEBUG, \"Programmed RXP Engine %d\\n\", id);\n-\trules->count = rule_cnt;\n-\treturn 0;\n+\n+\treturn ret;\n+\n }\n \n static int\n@@ -579,7 +709,8 @@ rxp_init_eng(struct mlx5_regex_priv *priv, uint8_t id)\n \t\t\t\t\t     ctrl);\n \tif (ret)\n \t\treturn ret;\n-\tret = rxp_init_rtru(ctx, id, MLX5_RXP_RTRU_CSR_CTRL_INIT_MODE_IM_L1_L2);\n+\tret = rxp_init_rtru(priv, id,\n+\t\t\t    MLX5_RXP_RTRU_CSR_CTRL_INIT_MODE_IM_L1_L2);\n \tif (ret)\n \t\treturn ret;\n \tret = mlx5_devx_regex_register_read(ctx, id, MLX5_RXP_CSR_CAPABILITY_5,\n@@ -605,285 +736,6 @@ rxp_init_eng(struct mlx5_regex_priv *priv, uint8_t id)\n \treturn ret;\n }\n \n-static int\n-write_private_rules(struct mlx5_regex_priv *priv,\n-\t\t    struct mlx5_rxp_ctl_rules_pgm *rules,\n-\t\t    uint8_t id)\n-{\n-\tunsigned int pending;\n-\tuint32_t block, reg, val, rule_cnt, rule_offset, rtru_max_num_entries;\n-\tint ret = 1;\n-\n-\tif (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED)\n-\t\treturn -EINVAL;\n-\tif (rules->hdr.len == 0 || rules->hdr.cmd < MLX5_RXP_CTL_RULES_PGM ||\n-\t\t\t\t   rules->hdr.cmd > MLX5_RXP_CTL_RULES_PGM_INCR)\n-\t\treturn -EINVAL;\n-\t/* For a non-incremental rules program, re-init the RXP. */\n-\tif (rules->hdr.cmd == MLX5_RXP_CTL_RULES_PGM) {\n-\t\tret = rxp_init_eng(priv, id);\n-\t\tif (ret < 0)\n-\t\t\treturn ret;\n-\t} else if (rules->hdr.cmd == MLX5_RXP_CTL_RULES_PGM_INCR) {\n-\t\t/* Flush RXP L1 and L2 cache by using MODE_L1_L2. */\n-\t\tret = rxp_init_rtru(priv->ctx, id,\n-\t\t\t\t    MLX5_RXP_RTRU_CSR_CTRL_INIT_MODE_L1_L2);\n-\t\tif (ret < 0)\n-\t\t\treturn ret;\n-\t}\n-\tif (rules->count == 0)\n-\t\treturn -EINVAL;\n-\t/* Confirm the RXP is initialised. */\n-\tif (mlx5_devx_regex_register_read(priv->ctx, id,\n-\t\t\t\t\t    MLX5_RXP_CSR_STATUS, &val)) {\n-\t\tDRV_LOG(ERR, \"Failed to read from RXP!\");\n-\t\treturn -ENODEV;\n-\t}\n-\tif (!(val & MLX5_RXP_CSR_STATUS_INIT_DONE)) {\n-\t\tDRV_LOG(ERR, \"RXP not initialised...\");\n-\t\treturn -EBUSY;\n-\t}\n-\t/* Get the RTRU maximum number of entries allowed. */\n-\tif (mlx5_devx_regex_register_read(priv->ctx, id,\n-\t\t\tMLX5_RXP_RTRU_CSR_CAPABILITY, &rtru_max_num_entries)) {\n-\t\tDRV_LOG(ERR, \"Failed to read RTRU capability!\");\n-\t\treturn -ENODEV;\n-\t}\n-\trtru_max_num_entries = (rtru_max_num_entries & 0x00FF);\n-\trule_cnt = 0;\n-\tpending = 0;\n-\twhile (rules->count > 0) {\n-\t\tif ((rules->rules[rule_cnt].type == MLX5_RXP_ROF_ENTRY_INST) ||\n-\t\t    (rules->rules[rule_cnt].type == MLX5_RXP_ROF_ENTRY_IM) ||\n-\t\t    (rules->rules[rule_cnt].type == MLX5_RXP_ROF_ENTRY_EM)) {\n-\t\t\tif ((rules->rules[rule_cnt].type ==\n-\t\t\t     MLX5_RXP_ROF_ENTRY_EM) &&\n-\t\t\t    (priv->prog_mode == MLX5_RXP_SHARED_PROG_MODE)) {\n-\t\t\t\t/* Skip EM rules programming. */\n-\t\t\t\tif (pending > 0) {\n-\t\t\t\t\t/* Flush any rules that are pending. */\n-\t\t\t\t\trule_offset = (rule_cnt - pending);\n-\t\t\t\t\tret = rxp_flush_rules(priv->ctx,\n-\t\t\t\t\t\t&rules->rules[rule_offset],\n-\t\t\t\t\t\tpending, id);\n-\t\t\t\t\tif (ret < 0) {\n-\t\t\t\t\t\tDRV_LOG(ERR, \"Flushing rules.\");\n-\t\t\t\t\t\treturn -ENODEV;\n-\t\t\t\t\t}\n-\t\t\t\t\tpending = 0;\n-\t\t\t\t}\n-\t\t\t\trule_cnt++;\n-\t\t\t} else {\n-\t\t\t\tpending++;\n-\t\t\t\trule_cnt++;\n-\t\t\t\t/*\n-\t\t\t\t * If parsing the last rule, or if reached the\n-\t\t\t\t * maximum number of rules for this batch, then\n-\t\t\t\t * flush the rules batch to the RXP.\n-\t\t\t\t */\n-\t\t\t\tif ((rules->count == 1) ||\n-\t\t\t\t    (pending == rtru_max_num_entries)) {\n-\t\t\t\t\trule_offset = (rule_cnt - pending);\n-\t\t\t\t\tret = rxp_flush_rules(priv->ctx,\n-\t\t\t\t\t\t&rules->rules[rule_offset],\n-\t\t\t\t\t\tpending, id);\n-\t\t\t\t\tif (ret < 0) {\n-\t\t\t\t\t\tDRV_LOG(ERR, \"Flushing rules.\");\n-\t\t\t\t\t\treturn -ENODEV;\n-\t\t\t\t\t}\n-\t\t\t\t\tpending = 0;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t} else if ((rules->rules[rule_cnt].type ==\n-\t\t\t\tMLX5_RXP_ROF_ENTRY_EQ) ||\n-\t\t\t (rules->rules[rule_cnt].type ==\n-\t\t\t\tMLX5_RXP_ROF_ENTRY_GTE) ||\n-\t\t\t (rules->rules[rule_cnt].type ==\n-\t\t\t\tMLX5_RXP_ROF_ENTRY_LTE) ||\n-\t\t\t (rules->rules[rule_cnt].type ==\n-\t\t\t\tMLX5_RXP_ROF_ENTRY_CHECKSUM) ||\n-\t\t\t (rules->rules[rule_cnt].type ==\n-\t\t\t\tMLX5_RXP_ROF_ENTRY_CHECKSUM_EX_EM)) {\n-\t\t\tif (pending) {\n-\t\t\t\t/* Flush rules before checking reg values. */\n-\t\t\t\trule_offset = (rule_cnt - pending);\n-\t\t\t\tret = rxp_flush_rules(priv->ctx,\n-\t\t\t\t\t&rules->rules[rule_offset],\n-\t\t\t\t\tpending, id);\n-\t\t\t\tif (ret < 0) {\n-\t\t\t\t\tDRV_LOG(ERR, \"Failed to flush rules.\");\n-\t\t\t\t\treturn -ENODEV;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tblock = (rules->rules[rule_cnt].addr >> 16) & 0xFFFF;\n-\t\t\tif (block == 0)\n-\t\t\t\treg = MLX5_RXP_CSR_BASE_ADDRESS;\n-\t\t\telse if (block == 1)\n-\t\t\t\treg = MLX5_RXP_RTRU_CSR_BASE_ADDRESS;\n-\t\t\telse {\n-\t\t\t\tDRV_LOG(ERR, \"Invalid ROF register 0x%08X!\",\n-\t\t\t\t\trules->rules[rule_cnt].addr);\n-\t\t\t\treturn -EINVAL;\n-\t\t\t}\n-\t\t\treg += (rules->rules[rule_cnt].addr & 0xFFFF) *\n-\t\t\t\tMLX5_RXP_CSR_WIDTH;\n-\t\t\tret = mlx5_devx_regex_register_read(priv->ctx, id,\n-\t\t\t\t\t\t\t    reg, &val);\n-\t\t\tif (ret) {\n-\t\t\t\tDRV_LOG(ERR, \"RXP CSR read failed!\");\n-\t\t\t\treturn ret;\n-\t\t\t}\n-\t\t\tif ((priv->prog_mode == MLX5_RXP_SHARED_PROG_MODE) &&\n-\t\t\t    ((rules->rules[rule_cnt].type ==\n-\t\t\t    MLX5_RXP_ROF_ENTRY_CHECKSUM_EX_EM) &&\n-\t\t\t    (val != rules->rules[rule_cnt].value))) {\n-\t\t\t\tDRV_LOG(ERR, \"Unexpected value for register:\");\n-\t\t\t\tDRV_LOG(ERR, \"reg %x\" PRIu32 \" got %x\" PRIu32,\n-\t\t\t\t\trules->rules[rule_cnt].addr, val);\n-\t\t\t\tDRV_LOG(ERR, \"expected %\" PRIx64 \".\",\n-\t\t\t\t\trules->rules[rule_cnt].value);\n-\t\t\t\t\treturn -EINVAL;\n-\t\t\t} else if ((priv->prog_mode ==\n-\t\t\t\t MLX5_RXP_PRIVATE_PROG_MODE) &&\n-\t\t\t\t (rules->rules[rule_cnt].type ==\n-\t\t\t\t MLX5_RXP_ROF_ENTRY_CHECKSUM) &&\n-\t\t\t\t (val != rules->rules[rule_cnt].value)) {\n-\t\t\t\tDRV_LOG(ERR, \"Unexpected value for register:\");\n-\t\t\t\tDRV_LOG(ERR, \"reg %x\" PRIu32 \" got %x\" PRIu32,\n-\t\t\t\t\trules->rules[rule_cnt].addr, val);\n-\t\t\t\tDRV_LOG(ERR, \"expected %\" PRIx64 \".\",\n-\t\t\t\t\trules->rules[rule_cnt].value);\n-\t\t\t\treturn -EINVAL;\n-\t\t\t} else if ((rules->rules[rule_cnt].type ==\n-\t\t\t\t\tMLX5_RXP_ROF_ENTRY_EQ) &&\n-\t\t\t\t  (val != rules->rules[rule_cnt].value)) {\n-\t\t\t\tDRV_LOG(ERR, \"Unexpected value for register:\");\n-\t\t\t\tDRV_LOG(ERR, \"reg %x\" PRIu32 \" got %x\" PRIu32,\n-\t\t\t\t\trules->rules[rule_cnt].addr, val);\n-\t\t\t\tDRV_LOG(ERR, \"expected %\" PRIx64 \".\",\n-\t\t\t\t\trules->rules[rule_cnt].value);\n-\t\t\t\t\treturn -EINVAL;\n-\t\t\t} else if ((rules->rules[rule_cnt].type ==\n-\t\t\t\t\tMLX5_RXP_ROF_ENTRY_GTE) &&\n-\t\t\t\t (val < rules->rules[rule_cnt].value)) {\n-\t\t\t\tDRV_LOG(ERR, \"Unexpected value reg 0x%08X,\",\n-\t\t\t\t\trules->rules[rule_cnt].addr);\n-\t\t\t\tDRV_LOG(ERR, \"got %X, expected >= %\" PRIx64 \".\",\n-\t\t\t\t\tval, rules->rules[rule_cnt].value);\n-\t\t\t\treturn -EINVAL;\n-\t\t\t} else if ((rules->rules[rule_cnt].type ==\n-\t\t\t\t\tMLX5_RXP_ROF_ENTRY_LTE) &&\n-\t\t\t\t (val > rules->rules[rule_cnt].value)) {\n-\t\t\t\tDRV_LOG(ERR, \"Unexpected value reg 0x%08X,\",\n-\t\t\t\t\trules->rules[rule_cnt].addr);\n-\t\t\t\tDRV_LOG(ERR, \"got %08X expected <= %\" PRIx64,\n-\t\t\t\t\tval, rules->rules[rule_cnt].value);\n-\t\t\t\treturn -EINVAL;\n-\t\t\t}\n-\t\t\trule_cnt++;\n-\t\t\tpending = 0;\n-\t\t} else {\n-\t\t\tDRV_LOG(ERR, \"Error: Invalid rule type %d!\",\n-\t\t\t\trules->rules[rule_cnt].type);\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\t\trules->count--;\n-\t}\n-\treturn ret;\n-}\n-\n-/*\n- * Shared memory programming mode, here all external db instructions are written\n- * to EM via the host.\n- */\n-static int\n-write_shared_rules(struct mlx5_regex_priv *priv,\n-\t\t   struct mlx5_rxp_ctl_rules_pgm *rules, uint32_t count,\n-\t\t   uint8_t db_to_program)\n-{\n-\tuint32_t rule_cnt, rof_rule_addr;\n-\tuint64_t tmp_write_swap[4];\n-\n-\tif (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED)\n-\t\treturn -EINVAL;\n-\tif ((rules->count == 0) || (count == 0))\n-\t\treturn -EINVAL;\n-\trule_cnt = 0;\n-\t/*\n-\t * Note the following section of code carries out a 32byte swap of\n-\t * instruction to coincide with HW 32byte swap. This may need removed\n-\t * in new variants of this programming function!\n-\t */\n-\twhile (rule_cnt < rules->count) {\n-\t\tif ((rules->rules[rule_cnt].type == MLX5_RXP_ROF_ENTRY_EM) &&\n-\t\t    (priv->prog_mode == MLX5_RXP_SHARED_PROG_MODE)) {\n-\t\t\t/*\n-\t\t\t * Note there are always blocks of 8 instructions for\n-\t\t\t * 7's written sequentially. However there is no\n-\t\t\t * guarantee that all blocks are sequential!\n-\t\t\t */\n-\t\t\tif (count >= (rule_cnt + MLX5_RXP_INST_BLOCK_SIZE)) {\n-\t\t\t\t/*\n-\t\t\t\t * Ensure memory write not exceeding boundary\n-\t\t\t\t * Check essential to ensure 0x10000 offset\n-\t\t\t\t * accounted for!\n-\t\t\t\t */\n-\t\t\t\tif ((uint8_t *)((uint8_t *)\n-\t\t\t\t    priv->db[db_to_program].ptr +\n-\t\t\t\t    ((rules->rules[rule_cnt + 7].addr <<\n-\t\t\t\t    MLX5_RXP_INST_OFFSET))) >=\n-\t\t\t\t    ((uint8_t *)((uint8_t *)\n-\t\t\t\t    priv->db[db_to_program].ptr +\n-\t\t\t\t    MLX5_MAX_DB_SIZE))) {\n-\t\t\t\t\tDRV_LOG(ERR, \"DB exceeded memory!\");\n-\t\t\t\t\treturn -ENODEV;\n-\t\t\t\t}\n-\t\t\t\t/*\n-\t\t\t\t * Rule address Offset to align with RXP\n-\t\t\t\t * external instruction offset.\n-\t\t\t\t */\n-\t\t\t\trof_rule_addr = (rules->rules[rule_cnt].addr <<\n-\t\t\t\t\t\t MLX5_RXP_INST_OFFSET);\n-\t\t\t\t/* 32 byte instruction swap (sw work around)! */\n-\t\t\t\ttmp_write_swap[0] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 4)].value);\n-\t\t\t\ttmp_write_swap[1] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 5)].value);\n-\t\t\t\ttmp_write_swap[2] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 6)].value);\n-\t\t\t\ttmp_write_swap[3] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 7)].value);\n-\t\t\t\t/* Write only 4 of the 8 instructions. */\n-\t\t\t\tmemcpy((uint8_t *)((uint8_t *)\n-\t\t\t\t       priv->db[db_to_program].ptr +\n-\t\t\t\t       rof_rule_addr), &tmp_write_swap,\n-\t\t\t\t       (sizeof(uint64_t) * 4));\n-\t\t\t\t/* Write 1st 4 rules of block after last 4. */\n-\t\t\t\trof_rule_addr = (rules->rules[\n-\t\t\t\t\t\t (rule_cnt + 4)].addr <<\n-\t\t\t\t\t\t MLX5_RXP_INST_OFFSET);\n-\t\t\t\ttmp_write_swap[0] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 0)].value);\n-\t\t\t\ttmp_write_swap[1] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 1)].value);\n-\t\t\t\ttmp_write_swap[2] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 2)].value);\n-\t\t\t\ttmp_write_swap[3] = le64toh(\n-\t\t\t\t\trules->rules[(rule_cnt + 3)].value);\n-\t\t\t\tmemcpy((uint8_t *)((uint8_t *)\n-\t\t\t\t       priv->db[db_to_program].ptr +\n-\t\t\t\t       rof_rule_addr), &tmp_write_swap,\n-\t\t\t\t       (sizeof(uint64_t) * 4));\n-\t\t\t} else\n-\t\t\t\treturn -1;\n-\t\t\t/* Fast forward as already handled block of 8. */\n-\t\t\trule_cnt += MLX5_RXP_INST_BLOCK_SIZE;\n-\t\t} else\n-\t\t\trule_cnt++; /* Must be something other than EM rule. */\n-\t}\n-\treturn 0;\n-}\n-\n static int\n rxp_db_setup(struct mlx5_regex_priv *priv)\n {\n@@ -933,6 +785,7 @@ mlx5_regex_rules_db_import(struct rte_regexdev *dev,\n \tstruct mlx5_rxp_ctl_rules_pgm *rules = NULL;\n \tuint32_t id;\n \tint ret;\n+\tuint32_t ver;\n \n \tif (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED) {\n \t\tDRV_LOG(ERR, \"RXP programming mode not set!\");\n@@ -944,10 +797,10 @@ mlx5_regex_rules_db_import(struct rte_regexdev *dev,\n \t}\n \tif (rule_db_len == 0)\n \t\treturn -EINVAL;\n-\tret = rxp_parse_rof(rule_db, rule_db_len, &rules);\n-\tif (ret) {\n-\t\tDRV_LOG(ERR, \"Can't parse ROF file.\");\n-\t\treturn ret;\n+\tif (mlx5_devx_regex_register_read(priv->ctx, 0,\n+\t\t\t\t\t  MLX5_RXP_CSR_BASE_ADDRESS, &ver)) {\n+\t\tDRV_LOG(ERR, \"Failed to read Main CSRs Engine 0!\");\n+\t\treturn -1;\n \t}\n \t/* Need to ensure RXP not busy before stop! */\n \tfor (id = 0; id < priv->nb_engines; id++) {\n@@ -957,7 +810,7 @@ mlx5_regex_rules_db_import(struct rte_regexdev *dev,\n \t\t\tret = -ENODEV;\n \t\t\tgoto tidyup_error;\n \t\t}\n-\t\tret = program_rxp_rules(priv, rules, id);\n+\t\tret = program_rxp_rules(priv, rule_db, rule_db_len, id);\n \t\tif (ret < 0) {\n \t\t\tDRV_LOG(ERR, \"Failed to program rxp rules.\");\n \t\t\tret = -ENODEV;\ndiff --git a/drivers/regex/mlx5/mlx5_rxp_csrs.h b/drivers/regex/mlx5/mlx5_rxp_csrs.h\nindex d92b3fff53..f3ffdfdef2 100644\n--- a/drivers/regex/mlx5/mlx5_rxp_csrs.h\n+++ b/drivers/regex/mlx5/mlx5_rxp_csrs.h\n@@ -5,6 +5,9 @@\n #ifndef _MLX5_RXP_CSRS_H_\n #define _MLX5_RXP_CSRS_H_\n \n+/* BF types */\n+#define MLX5_RXP_BF2_IDENTIFIER 0x07055254ul\n+\n /*\n  * Common to all RXP implementations\n  */\n",
    "prefixes": [
        "2/4"
    ]
}