get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 68504,
    "url": "https://patches.dpdk.org/api/patches/68504/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1586938751-32808-19-git-send-email-venkatkumar.duvvuru@broadcom.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": "<1586938751-32808-19-git-send-email-venkatkumar.duvvuru@broadcom.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1586938751-32808-19-git-send-email-venkatkumar.duvvuru@broadcom.com",
    "date": "2020-04-15T08:18:55",
    "name": "[v4,18/34] net/bnxt: add helper functions for blob/regfile ops",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "98121876388b06cdfd8780a8ce18f17e72530249",
    "submitter": {
        "id": 1635,
        "url": "https://patches.dpdk.org/api/people/1635/?format=api",
        "name": "Venkat Duvvuru",
        "email": "venkatkumar.duvvuru@broadcom.com"
    },
    "delegate": {
        "id": 1766,
        "url": "https://patches.dpdk.org/api/users/1766/?format=api",
        "username": "ajitkhaparde",
        "first_name": "Ajit",
        "last_name": "Khaparde",
        "email": "ajit.khaparde@broadcom.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1586938751-32808-19-git-send-email-venkatkumar.duvvuru@broadcom.com/mbox/",
    "series": [
        {
            "id": 9386,
            "url": "https://patches.dpdk.org/api/series/9386/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=9386",
            "date": "2020-04-15T08:18:37",
            "name": "add support for host based flow table management",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/9386/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/68504/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/68504/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 DD178A0563;\n\tWed, 15 Apr 2020 10:23:56 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 7F8701D528;\n\tWed, 15 Apr 2020 10:20:14 +0200 (CEST)",
            "from mail-pg1-f195.google.com (mail-pg1-f195.google.com\n [209.85.215.195]) by dpdk.org (Postfix) with ESMTP id 490D51D5BD\n for <dev@dpdk.org>; Wed, 15 Apr 2020 10:20:12 +0200 (CEST)",
            "by mail-pg1-f195.google.com with SMTP id c23so1169700pgj.3\n for <dev@dpdk.org>; Wed, 15 Apr 2020 01:20:12 -0700 (PDT)",
            "from S60.dhcp.broadcom.net ([192.19.234.250])\n by smtp.gmail.com with ESMTPSA id fy21sm3819019pjb.25.2020.04.15.01.20.07\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Wed, 15 Apr 2020 01:20:09 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com;\n s=google;\n h=from:to:cc:subject:date:message-id:in-reply-to:references;\n bh=VM+YrQRm4hidujGcWyoQEHnvxY/mP9TRy4aNGS4nWL0=;\n b=TvEUWs4CWpNxy2+zZRKrtfk7XYb5ULPXhHj7D9hywB1bLV3F7XiExUxG3lLeW/u2VU\n boYVzu+0cVRtpR67PLsdMKQmQr5pT2Sd0wfmk5vxeOY2NTPig6t8XxAmW/OXXwqEZLSn\n 4+5gBr5NJx//DAks1qJ5RzjzmCf8TpabJxj54=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references;\n bh=VM+YrQRm4hidujGcWyoQEHnvxY/mP9TRy4aNGS4nWL0=;\n b=IOSdugepDIN8guYAKHVV4VWRd6fyEMGyBdaqN5j/AfDYeUEaGxV+/Xs/c26MTF7K62\n 7qTUJJ+HsA5TFmPGaYPXqnx4kJW6peQe3ZCHNadFhUqDp94YCFFtAKpaEAiK6CaoPE8N\n /8mYwSDUaRDGIj80HguvUFig1oCyAh2BU/hbZC+WYIptjR3r4o4UrUAEejcs0BXZ2HCI\n REqj4jY7O1+HChNK7gVRUQXaizDqKnlCCjgcQabXkux2ECKHXil0T7vLY5oydcKh1HmU\n Ec4uzAVB+k3OwXBaoRtrJoDlTcRGr/93KKIq3ezDNCkbT71DA2bST8MJeuwxRonYkG+a\n 8/LA==",
        "X-Gm-Message-State": "AGi0PubfxInuUzz9Nexam1WKfQw3ZroDRLVR9XZleGembACA6y7XS42G\n pgVYE6MJBXAen4iHMjjWm7Y0HvYrhQ1ygPasWfRaQwg+KpBAbaxsNrw0UhlXtQGkyg0ItMvsF3P\n SETHRyV8uYvgeBAW16Hr5kpNFDbi6ZjQRCB8iL13dBi1ld2TbCDCnO+SDTCU8e987crT0",
        "X-Google-Smtp-Source": "\n APiQypLDUTNc2a4HXX9h5bDqQIHCsgol/TeRQoLjfWqVVLz5XtnYkuqeeRPaV/LQE3LuLIRvBbbImg==",
        "X-Received": "by 2002:aa7:9515:: with SMTP id b21mr5661782pfp.226.1586938809842;\n Wed, 15 Apr 2020 01:20:09 -0700 (PDT)",
        "From": "Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "To": "dev@dpdk.org",
        "Cc": "Mike Baucom <michael.baucom@broadcom.com>,\n Kishore Padmanabha <kishore.padmanabha@broadcom.com>,\n Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>",
        "Date": "Wed, 15 Apr 2020 13:48:55 +0530",
        "Message-Id": "\n <1586938751-32808-19-git-send-email-venkatkumar.duvvuru@broadcom.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "\n <1586938751-32808-1-git-send-email-venkatkumar.duvvuru@broadcom.com>",
        "References": "\n <1586852011-37536-1-git-send-email-venkatkumar.duvvuru@broadcom.com>\n <1586938751-32808-1-git-send-email-venkatkumar.duvvuru@broadcom.com>",
        "Subject": "[dpdk-dev] [PATCH v4 18/34] net/bnxt: add helper functions for\n\tblob/regfile ops",
        "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": "From: Mike Baucom <michael.baucom@broadcom.com>\n\n1. blob routines for managing key/mask/result data\n2. regfile routines for managing temporal data during flow\n   construction\n\nSigned-off-by: Mike Baucom <michael.baucom@broadcom.com>\nSigned-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>\nSigned-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>\nReviewed-by: Lance Richardson <lance.richardson@broadcom.com>\nReviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>\n---\n drivers/net/bnxt/Makefile                 |   2 +\n drivers/net/bnxt/tf_ulp/ulp_template_db.h |  12 +\n drivers/net/bnxt/tf_ulp/ulp_utils.c       | 521 ++++++++++++++++++++++++++++++\n drivers/net/bnxt/tf_ulp/ulp_utils.h       | 279 ++++++++++++++++\n 4 files changed, 814 insertions(+)\n create mode 100644 drivers/net/bnxt/tf_ulp/ulp_utils.c\n create mode 100644 drivers/net/bnxt/tf_ulp/ulp_utils.h",
    "diff": "diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile\nindex bb9b888..4e0dea1 100644\n--- a/drivers/net/bnxt/Makefile\n+++ b/drivers/net/bnxt/Makefile\n@@ -61,6 +61,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/bnxt_ulp.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_mark_mgr.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_flow_db.c\n SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_template_db.c\n+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_utils.c\n+\n #\n # Export include files\n #\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.h b/drivers/net/bnxt/tf_ulp/ulp_template_db.h\nindex ba2a101..1eed828 100644\n--- a/drivers/net/bnxt/tf_ulp/ulp_template_db.h\n+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.h\n@@ -27,6 +27,18 @@ enum bnxt_ulp_device_id {\n \tBNXT_ULP_DEVICE_ID_LAST\n };\n \n+enum bnxt_ulp_fmf_mask {\n+\tBNXT_ULP_FMF_MASK_IGNORE,\n+\tBNXT_ULP_FMF_MASK_ANY,\n+\tBNXT_ULP_FMF_MASK_EXACT,\n+\tBNXT_ULP_FMF_MASK_WILDCARD,\n+\tBNXT_ULP_FMF_MASK_LAST\n+};\n+\n+enum bnxt_ulp_regfile_index {\n+\tBNXT_ULP_REGFILE_INDEX_LAST\n+};\n+\n enum bnxt_ulp_sym {\n \tBNXT_ULP_SYM_LITTLE_ENDIAN = 1,\n \tBNXT_ULP_SYM_YES = 1\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.c b/drivers/net/bnxt/tf_ulp/ulp_utils.c\nnew file mode 100644\nindex 0000000..1d463cd\n--- /dev/null\n+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.c\n@@ -0,0 +1,521 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2014-2019 Broadcom\n+ * All rights reserved.\n+ */\n+\n+#include \"ulp_utils.h\"\n+#include \"bnxt_tf_common.h\"\n+\n+/*\n+ * Initialize the regfile structure for writing\n+ *\n+ * regfile [in] Ptr to a regfile instance\n+ *\n+ * returns 0 on error or 1 on success\n+ */\n+uint32_t\n+ulp_regfile_init(struct ulp_regfile *regfile)\n+{\n+\t/* validate the arguments */\n+\tif (!regfile) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\tmemset(regfile, 0, sizeof(struct ulp_regfile));\n+\treturn 1; /* Success */\n+}\n+\n+/*\n+ * Read a value from the regfile\n+ *\n+ * regfile [in] The regfile instance. Must be initialized prior to being used\n+ *\n+ * field [in] The field to be read within the regfile.\n+ *\n+ * data [in/out]\n+ *\n+ * returns size, zero on failure\n+ */\n+uint32_t\n+ulp_regfile_read(struct ulp_regfile *regfile,\n+\t\t enum bnxt_ulp_regfile_index field,\n+\t\t uint64_t *data)\n+{\n+\t/* validate the arguments */\n+\tif (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\n+\t*data = regfile->entry[field].data;\n+\treturn sizeof(*data);\n+}\n+\n+/*\n+ * Write a value to the regfile\n+ *\n+ * regfile [in] The regfile instance.  Must be initialized prior to being used\n+ *\n+ * field [in] The field to be written within the regfile.\n+ *\n+ * data [in] The value is written into this variable.  It is going to be in the\n+ * same byte order as it was written.\n+ *\n+ * size [in] The size in bytes of the value beingritten into this\n+ * variable.\n+ *\n+ * returns 0 on fail\n+ */\n+uint32_t\n+ulp_regfile_write(struct ulp_regfile *regfile,\n+\t\t  enum bnxt_ulp_regfile_index field,\n+\t\t  uint64_t data)\n+{\n+\t/* validate the arguments */\n+\tif (!regfile || field >= BNXT_ULP_REGFILE_INDEX_LAST) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\n+\tregfile->entry[field].data = data;\n+\treturn sizeof(data); /* Success */\n+}\n+\n+static void\n+ulp_bs_put_msb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)\n+{\n+\tuint8_t bitoffs = bitpos % 8;\n+\tuint16_t index  = bitpos / 8;\n+\tuint8_t mask;\n+\tuint8_t tmp;\n+\tint8_t shift;\n+\n+\ttmp = bs[index];\n+\tmask = ((uint8_t)-1 >> (8 - bitlen));\n+\tshift = 8 - bitoffs - bitlen;\n+\tval &= mask;\n+\n+\tif (shift >= 0) {\n+\t\ttmp &= ~(mask << shift);\n+\t\ttmp |= val << shift;\n+\t\tbs[index] = tmp;\n+\t} else {\n+\t\ttmp &= ~((uint8_t)-1 >> bitoffs);\n+\t\ttmp |= val >> -shift;\n+\t\tbs[index++] = tmp;\n+\n+\t\ttmp = bs[index];\n+\t\ttmp &= ((uint8_t)-1 >> (bitlen - (8 - bitoffs)));\n+\t\ttmp |= val << (8 + shift);\n+\t\tbs[index] = tmp;\n+\t}\n+}\n+\n+static void\n+ulp_bs_put_lsb(uint8_t *bs, uint16_t bitpos, uint8_t bitlen, uint8_t val)\n+{\n+\tuint8_t bitoffs = bitpos % 8;\n+\tuint16_t index  = bitpos / 8;\n+\tuint8_t mask;\n+\tuint8_t tmp;\n+\tuint8_t shift;\n+\tuint8_t partial;\n+\n+\ttmp = bs[index];\n+\tshift = bitoffs;\n+\n+\tif (bitoffs + bitlen <= 8) {\n+\t\tmask = ((1 << bitlen) - 1) << shift;\n+\t\ttmp &= ~mask;\n+\t\ttmp |= ((val << shift) & mask);\n+\t\tbs[index] = tmp;\n+\t} else {\n+\t\tpartial = 8 - bitoffs;\n+\t\tmask = ((1 << partial) - 1) << shift;\n+\t\ttmp &= ~mask;\n+\t\ttmp |= ((val << shift) & mask);\n+\t\tbs[index++] = tmp;\n+\n+\t\tval >>= partial;\n+\t\tpartial = bitlen - partial;\n+\t\tmask = ((1 << partial) - 1);\n+\t\ttmp = bs[index];\n+\t\ttmp &= ~mask;\n+\t\ttmp |= (val & mask);\n+\t\tbs[index] = tmp;\n+\t}\n+}\n+\n+/* Assuming that val is in Big-Endian Format */\n+static uint32_t\n+ulp_bs_push_lsb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)\n+{\n+\tint i;\n+\tint cnt = (len) / 8;\n+\tint tlen = len;\n+\n+\tif (cnt > 0 && !(len % 8))\n+\t\tcnt -= 1;\n+\n+\tfor (i = 0; i < cnt; i++) {\n+\t\tulp_bs_put_lsb(bs, pos, 8, val[cnt - i]);\n+\t\tpos += 8;\n+\t\ttlen -= 8;\n+\t}\n+\n+\t/* Handle the remainder bits */\n+\tif (tlen)\n+\t\tulp_bs_put_lsb(bs, pos, tlen, val[0]);\n+\treturn len;\n+}\n+\n+/* Assuming that val is in Big-Endian Format */\n+static uint32_t\n+ulp_bs_push_msb(uint8_t *bs, uint16_t pos, uint8_t len, uint8_t *val)\n+{\n+\tint i;\n+\tint cnt = (len + 7) / 8;\n+\tint tlen = len;\n+\n+\t/* Handle any remainder bits */\n+\tint tmp = len % 8;\n+\n+\tif (!tmp)\n+\t\ttmp = 8;\n+\n+\tulp_bs_put_msb(bs, pos, tmp, val[0]);\n+\n+\tpos += tmp;\n+\ttlen -= tmp;\n+\n+\tfor (i = 1; i < cnt; i++) {\n+\t\tulp_bs_put_msb(bs, pos, 8, val[i]);\n+\t\tpos += 8;\n+\t\ttlen -= 8;\n+\t}\n+\n+\treturn len;\n+}\n+\n+/*\n+ * Initializes the blob structure for creating binary blob\n+ *\n+ * blob [in] The blob to be initialized\n+ *\n+ * bitlen [in] The bit length of the blob\n+ *\n+ * order [in] The byte order for the blob.  Currently only supporting\n+ * big endian.  All fields are packed with this order.\n+ *\n+ * returns 0 on error or 1 on success\n+ */\n+uint32_t\n+ulp_blob_init(struct ulp_blob *blob,\n+\t      uint16_t bitlen,\n+\t      enum bnxt_ulp_byte_order order)\n+{\n+\t/* validate the arguments */\n+\tif (!blob || bitlen > (8 * sizeof(blob->data))) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\tblob->bitlen = bitlen;\n+\tblob->byte_order = order;\n+\tblob->write_idx = 0;\n+\tmemset(blob->data, 0, sizeof(blob->data));\n+\treturn 1; /* Success */\n+}\n+\n+/*\n+ * Add data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] A pointer to bytes to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error.\n+ */\n+#define ULP_BLOB_BYTE\t\t8\n+#define ULP_BLOB_BYTE_HEX\t0xFF\n+#define BLOB_MASK_CAL(x)\t((0xFF << (x)) & 0xFF)\n+uint32_t\n+ulp_blob_push(struct ulp_blob *blob,\n+\t      uint8_t *data,\n+\t      uint32_t datalen)\n+{\n+\tuint32_t rc;\n+\n+\t/* validate the arguments */\n+\tif (!blob || datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\n+\tif (blob->byte_order == BNXT_ULP_BYTE_ORDER_BE)\n+\t\trc = ulp_bs_push_msb(blob->data,\n+\t\t\t\t     blob->write_idx,\n+\t\t\t\t     datalen,\n+\t\t\t\t     data);\n+\telse\n+\t\trc = ulp_bs_push_lsb(blob->data,\n+\t\t\t\t     blob->write_idx,\n+\t\t\t\t     datalen,\n+\t\t\t\t     data);\n+\tif (!rc) {\n+\t\tBNXT_TF_DBG(ERR, \"Failed ro write blob\\n\");\n+\t\treturn 0;\n+\t}\n+\tblob->write_idx += datalen;\n+\treturn datalen;\n+}\n+\n+/*\n+ * Add data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] 64-bit value to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error, pointer pushed value otherwise.\n+ */\n+uint8_t *\n+ulp_blob_push_64(struct ulp_blob *blob,\n+\t\t uint64_t *data,\n+\t\t uint32_t datalen)\n+{\n+\tuint8_t *val = (uint8_t *)data;\n+\tint rc;\n+\n+\tint size = (datalen + 7) / 8;\n+\n+\tif (!blob || !data ||\n+\t    datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0;\n+\t}\n+\n+\trc = ulp_blob_push(blob, &val[8 - size], datalen);\n+\tif (!rc)\n+\t\treturn 0;\n+\n+\treturn &val[8 - size];\n+}\n+\n+/*\n+ * Add encap data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] value to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error, pointer pushed value otherwise.\n+ */\n+uint32_t\n+ulp_blob_push_encap(struct ulp_blob *blob,\n+\t\t    uint8_t *data,\n+\t\t    uint32_t datalen)\n+{\n+\tuint8_t\t\t*val = (uint8_t *)data;\n+\tuint32_t\tinitial_size, write_size = datalen;\n+\tuint32_t\tsize = 0;\n+\n+\tif (!blob || !data ||\n+\t    datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0;\n+\t}\n+\n+\tinitial_size = ULP_BYTE_2_BITS(sizeof(uint64_t)) -\n+\t    (blob->write_idx % ULP_BYTE_2_BITS(sizeof(uint64_t)));\n+\twhile (write_size > 0) {\n+\t\tif (initial_size && write_size > initial_size) {\n+\t\t\tsize = initial_size;\n+\t\t\tinitial_size = 0;\n+\t\t} else if (initial_size && write_size <= initial_size) {\n+\t\t\tsize = write_size;\n+\t\t\tinitial_size = 0;\n+\t\t} else if (write_size > ULP_BYTE_2_BITS(sizeof(uint64_t))) {\n+\t\t\tsize = ULP_BYTE_2_BITS(sizeof(uint64_t));\n+\t\t} else {\n+\t\t\tsize = write_size;\n+\t\t}\n+\t\tif (!ulp_blob_push(blob, val, size)) {\n+\t\t\tBNXT_TF_DBG(ERR, \"push field failed\\n\");\n+\t\t\treturn 0;\n+\t\t}\n+\t\tval += ULP_BITS_2_BYTE(size);\n+\t\twrite_size -= size;\n+\t}\n+\treturn datalen;\n+}\n+\n+/*\n+ * Adds pad to an initialized blob at the current offset\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * datalen [in] The number of bits of pad to add\n+ *\n+ * returns the number of pad bits added, zero on failure\n+ */\n+uint32_t\n+ulp_blob_pad_push(struct ulp_blob *blob,\n+\t\t  uint32_t datalen)\n+{\n+\tif (datalen > (uint32_t)(blob->bitlen - blob->write_idx)) {\n+\t\tBNXT_TF_DBG(ERR, \"Pad too large for blob\\n\");\n+\t\treturn 0;\n+\t}\n+\n+\tblob->write_idx += datalen;\n+\treturn datalen;\n+}\n+\n+/*\n+ * Get the data portion of the binary blob.\n+ *\n+ * blob [in] The blob's data to be retrieved. The blob must be\n+ * initialized prior to pushing data.\n+ *\n+ * datalen [out] The number of bits to that are filled.\n+ *\n+ * returns a byte array of the blob data.  Returns NULL on error.\n+ */\n+uint8_t *\n+ulp_blob_data_get(struct ulp_blob *blob,\n+\t\t  uint16_t *datalen)\n+{\n+\t/* validate the arguments */\n+\tif (!blob) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn NULL; /* failure */\n+\t}\n+\t*datalen = blob->write_idx;\n+\treturn blob->data;\n+}\n+\n+/*\n+ * Set the encap swap start index of the binary blob.\n+ *\n+ * blob [in] The blob's data to be retrieved. The blob must be\n+ * initialized prior to pushing data.\n+ *\n+ * returns void.\n+ */\n+void\n+ulp_blob_encap_swap_idx_set(struct ulp_blob *blob)\n+{\n+\t/* validate the arguments */\n+\tif (!blob) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn; /* failure */\n+\t}\n+\tblob->encap_swap_idx = blob->write_idx;\n+}\n+\n+/*\n+ * Perform the encap buffer swap to 64 bit reversal.\n+ *\n+ * blob [in] The blob's data to be used for swap.\n+ *\n+ * returns void.\n+ */\n+void\n+ulp_blob_perform_encap_swap(struct ulp_blob *blob)\n+{\n+\tuint32_t\t\ti, idx = 0, end_idx = 0;\n+\tuint8_t\t\ttemp_val_1, temp_val_2;\n+\n+\t/* validate the arguments */\n+\tif (!blob) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn; /* failure */\n+\t}\n+\tidx = ULP_BITS_2_BYTE_NR(blob->encap_swap_idx + 1);\n+\tend_idx = ULP_BITS_2_BYTE(blob->write_idx);\n+\n+\twhile (idx <= end_idx) {\n+\t\tfor (i = 0; i < 4; i = i + 2) {\n+\t\t\ttemp_val_1 = blob->data[idx + i];\n+\t\t\ttemp_val_2 = blob->data[idx + i + 1];\n+\t\t\tblob->data[idx + i] = blob->data[idx + 6 - i];\n+\t\t\tblob->data[idx + i + 1] = blob->data[idx + 7 - i];\n+\t\t\tblob->data[idx + 7 - i] = temp_val_2;\n+\t\t\tblob->data[idx + 6 - i] = temp_val_1;\n+\t\t}\n+\t\tidx += 8;\n+\t}\n+}\n+\n+/*\n+ * Read data from the operand\n+ *\n+ * operand [in] A pointer to a 16 Byte operand\n+ *\n+ * val [in/out] The variable to copy the operand to\n+ *\n+ * bytes [in] The number of bytes to read into val\n+ *\n+ * returns number of bits read, zero on error\n+ */\n+uint16_t\n+ulp_operand_read(uint8_t *operand,\n+\t\t uint8_t *val,\n+\t\t uint16_t bytes)\n+{\n+\t/* validate the arguments */\n+\tif (!operand || !val) {\n+\t\tBNXT_TF_DBG(ERR, \"invalid argument\\n\");\n+\t\treturn 0; /* failure */\n+\t}\n+\tmemcpy(val, operand, bytes);\n+\treturn bytes;\n+}\n+\n+/*\n+ * copy the buffer in the encap format which is 2 bytes.\n+ * The MSB of the src is placed at the LSB of dst.\n+ *\n+ * dst [out] The destination buffer\n+ * src [in] The source buffer dst\n+ * size[in] size of the buffer.\n+ */\n+void\n+ulp_encap_buffer_copy(uint8_t *dst,\n+\t\t      const uint8_t *src,\n+\t\t      uint16_t size)\n+{\n+\tuint16_t\tidx = 0;\n+\n+\t/* copy 2 bytes at a time. Write MSB to LSB */\n+\twhile ((idx + sizeof(uint16_t)) <= size) {\n+\t\tmemcpy(&dst[idx], &src[size - idx - sizeof(uint16_t)],\n+\t\t       sizeof(uint16_t));\n+\t\tidx += sizeof(uint16_t);\n+\t}\n+}\n+\n+/*\n+ * Check the buffer is empty\n+ *\n+ * buf [in] The buffer\n+ * size [in] The size of the buffer\n+ *\n+ */\n+int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size)\n+{\n+\treturn buf[0] == 0 && !memcmp(buf, buf + 1, size - 1);\n+}\ndiff --git a/drivers/net/bnxt/tf_ulp/ulp_utils.h b/drivers/net/bnxt/tf_ulp/ulp_utils.h\nnew file mode 100644\nindex 0000000..db88546\n--- /dev/null\n+++ b/drivers/net/bnxt/tf_ulp/ulp_utils.h\n@@ -0,0 +1,279 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2014-2019 Broadcom\n+ * All rights reserved.\n+ */\n+\n+#ifndef _ULP_UTILS_H_\n+#define _ULP_UTILS_H_\n+\n+#include \"bnxt.h\"\n+#include \"ulp_template_db.h\"\n+\n+/*\n+ * Macros for bitmap sets and gets\n+ * These macros can be used if the val are power of 2.\n+ */\n+#define ULP_BITMAP_SET(bitmap, val)\t((bitmap) |= (val))\n+#define ULP_BITMAP_RESET(bitmap, val)\t((bitmap) &= ~(val))\n+#define ULP_BITMAP_ISSET(bitmap, val)\t((bitmap) & (val))\n+#define ULP_BITSET_CMP(b1, b2)  memcmp(&(b1)->bits, \\\n+\t\t\t\t&(b2)->bits, sizeof((b1)->bits))\n+/*\n+ * Macros for bitmap sets and gets\n+ * These macros can be used if the val are not power of 2 and\n+ * are simple index values.\n+ */\n+#define ULP_INDEX_BITMAP_SIZE\t(sizeof(uint64_t) * 8)\n+#define ULP_INDEX_BITMAP_CSET(i)\t(1UL << \\\n+\t\t\t((ULP_INDEX_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % ULP_INDEX_BITMAP_SIZE)))\n+\n+#define ULP_INDEX_BITMAP_SET(b, i)\t((b) |= \\\n+\t\t\t(1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % ULP_INDEX_BITMAP_SIZE))))\n+\n+#define ULP_INDEX_BITMAP_RESET(b, i)\t((b) &= \\\n+\t\t\t(~(1UL << ((ULP_INDEX_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % ULP_INDEX_BITMAP_SIZE)))))\n+\n+#define ULP_INDEX_BITMAP_GET(b, i)\t\t(((b) >> \\\n+\t\t\t((ULP_INDEX_BITMAP_SIZE - 1) - \\\n+\t\t\t((i) % ULP_INDEX_BITMAP_SIZE))) & 1)\n+\n+#define ULP_DEVICE_PARAMS_INDEX(tid, dev_id)\t\\\n+\t(((tid) << BNXT_ULP_LOG2_MAX_NUM_DEV) | (dev_id))\n+\n+/* Macro to convert bytes to bits */\n+#define ULP_BYTE_2_BITS(byte_x)\t\t((byte_x) * 8)\n+/* Macro to convert bits to bytes */\n+#define ULP_BITS_2_BYTE(bits_x)\t\t(((bits_x) + 7) / 8)\n+/* Macro to convert bits to bytes with no round off*/\n+#define ULP_BITS_2_BYTE_NR(bits_x)\t((bits_x) / 8)\n+\n+/*\n+ * Making the blob statically sized to 128 bytes for now.\n+ * The blob must be initialized with ulp_blob_init prior to using.\n+ */\n+#define BNXT_ULP_FLMP_BLOB_SIZE\t(128)\n+#define BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS\tULP_BYTE_2_BITS(BNXT_ULP_FLMP_BLOB_SIZE)\n+struct ulp_blob {\n+\tenum bnxt_ulp_byte_order\tbyte_order;\n+\tuint16_t\t\t\twrite_idx;\n+\tuint16_t\t\t\tbitlen;\n+\tuint8_t\t\t\t\tdata[BNXT_ULP_FLMP_BLOB_SIZE];\n+\tuint16_t\t\t\tencap_swap_idx;\n+};\n+\n+/*\n+ * The data can likely be only 32 bits for now.  Just size check\n+ * the data when being written.\n+ */\n+#define ULP_REGFILE_ENTRY_SIZE\t(sizeof(uint32_t))\n+struct ulp_regfile_entry {\n+\tuint64_t\tdata;\n+\tuint32_t\tsize;\n+};\n+\n+struct ulp_regfile {\n+\tstruct ulp_regfile_entry entry[BNXT_ULP_REGFILE_INDEX_LAST];\n+};\n+\n+/*\n+ * Initialize the regfile structure for writing\n+ *\n+ * regfile [in] Ptr to a regfile instance\n+ *\n+ * returns 0 on error or 1 on success\n+ */\n+uint32_t\n+ulp_regfile_init(struct ulp_regfile *regfile);\n+\n+/*\n+ * Read a value from the regfile\n+ *\n+ * regfile [in] The regfile instance.  Must be initialized prior to being used\n+ *\n+ * field [in] The field to be read within the regfile.\n+ *\n+ * returns the byte array\n+ */\n+uint32_t\n+ulp_regfile_read(struct ulp_regfile *regfile,\n+\t\t enum bnxt_ulp_regfile_index field,\n+\t\t uint64_t *data);\n+\n+/*\n+ * Write a value to the regfile\n+ *\n+ * regfile [in] The regfile instance.  Must be initialized prior to being used\n+ *\n+ * field [in] The field to be written within the regfile.\n+ *\n+ * data [in] The value is written into this variable.  It is going to be in the\n+ * same byte order as it was written.\n+ *\n+ * returns zero on error\n+ */\n+uint32_t\n+ulp_regfile_write(struct ulp_regfile *regfile,\n+\t\t  enum bnxt_ulp_regfile_index field,\n+\t\t  uint64_t data);\n+\n+/*\n+ * Initializes the blob structure for creating binary blob\n+ *\n+ * blob [in] The blob to be initialized\n+ *\n+ * bitlen [in] The bit length of the blob\n+ *\n+ * order [in] The byte order for the blob.  Currently only supporting\n+ * big endian.  All fields are packed with this order.\n+ *\n+ * returns 0 on error or 1 on success\n+ */\n+uint32_t\n+ulp_blob_init(struct ulp_blob *blob,\n+\t      uint16_t bitlen,\n+\t      enum bnxt_ulp_byte_order order);\n+\n+/*\n+ * Add data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] A pointer to bytes to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error.\n+ */\n+uint32_t\n+ulp_blob_push(struct ulp_blob *blob,\n+\t      uint8_t *data,\n+\t      uint32_t datalen);\n+\n+/*\n+ * Add data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] 64-bit value to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error, ptr to pushed data otherwise\n+ */\n+uint8_t *\n+ulp_blob_push_64(struct ulp_blob *blob,\n+\t\t uint64_t *data,\n+\t\t uint32_t datalen);\n+\n+/*\n+ * Add encap data to the binary blob at the current offset.\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * data [in] value to be added to the blob.\n+ *\n+ * datalen [in] The number of bits to be added ot the blob.\n+ *\n+ * The offset of the data is updated after each push of data.\n+ * NULL returned on error, pointer pushed value otherwise.\n+ */\n+uint32_t\n+ulp_blob_push_encap(struct ulp_blob *blob,\n+\t\t    uint8_t *data,\n+\t\t    uint32_t datalen);\n+\n+/*\n+ * Get the data portion of the binary blob.\n+ *\n+ * blob [in] The blob's data to be retrieved. The blob must be\n+ * initialized prior to pushing data.\n+ *\n+ * datalen [out] The number of bits to that are filled.\n+ *\n+ * returns a byte array of the blob data.  Returns NULL on error.\n+ */\n+uint8_t *\n+ulp_blob_data_get(struct ulp_blob *blob,\n+\t\t  uint16_t *datalen);\n+\n+/*\n+ * Adds pad to an initialized blob at the current offset\n+ *\n+ * blob [in] The blob that data is added to.  The blob must\n+ * be initialized prior to pushing data.\n+ *\n+ * datalen [in] The number of bits of pad to add\n+ *\n+ * returns the number of pad bits added, zero on failure\n+ */\n+uint32_t\n+ulp_blob_pad_push(struct ulp_blob *blob,\n+\t\t  uint32_t datalen);\n+\n+/*\n+ * Set the 64 bit swap start index of the binary blob.\n+ *\n+ * blob [in] The blob's data to be retrieved. The blob must be\n+ * initialized prior to pushing data.\n+ *\n+ * returns void.\n+ */\n+void\n+ulp_blob_encap_swap_idx_set(struct ulp_blob *blob);\n+\n+/*\n+ * Perform the encap buffer swap to 64 bit reversal.\n+ *\n+ * blob [in] The blob's data to be used for swap.\n+ *\n+ * returns void.\n+ */\n+void\n+ulp_blob_perform_encap_swap(struct ulp_blob *blob);\n+\n+/*\n+ * Read data from the operand\n+ *\n+ * operand [in] A pointer to a 16 Byte operand\n+ *\n+ * val [in/out] The variable to copy the operand to\n+ *\n+ * bitlen [in] The number of bits to read into val\n+ *\n+ * returns number of bits read, zero on error\n+ */\n+uint16_t\n+ulp_operand_read(uint8_t *operand,\n+\t\t uint8_t *val,\n+\t\t uint16_t bitlen);\n+\n+/*\n+ * copy the buffer in the encap format which is 2 bytes.\n+ * The MSB of the src is placed at the LSB of dst.\n+ *\n+ * dst [out] The destination buffer\n+ * src [in] The source buffer dst\n+ * size[in] size of the buffer.\n+ */\n+void\n+ulp_encap_buffer_copy(uint8_t *dst,\n+\t\t      const uint8_t *src,\n+\t\t      uint16_t size);\n+\n+/*\n+ * Check the buffer is empty\n+ *\n+ * buf [in] The buffer\n+ * size [in] The size of the buffer\n+ */\n+int32_t ulp_buffer_is_empty(const uint8_t *buf, uint32_t size);\n+\n+#endif /* _ULP_UTILS_H_ */\n",
    "prefixes": [
        "v4",
        "18/34"
    ]
}