get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 104100,
    "url": "http://patchwork.dpdk.org/api/patches/104100/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20211110074829.16654-5-apeksha.gupta@nxp.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20211110074829.16654-5-apeksha.gupta@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211110074829.16654-5-apeksha.gupta@nxp.com",
    "date": "2021-11-10T07:48:28",
    "name": "[v9,4/5] net/enetfec: add Rx/Tx support",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "6b12f8f18316b50091bd40316c37cee8b46cd631",
    "submitter": {
        "id": 1570,
        "url": "http://patchwork.dpdk.org/api/people/1570/?format=api",
        "name": "Apeksha Gupta",
        "email": "apeksha.gupta@nxp.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20211110074829.16654-5-apeksha.gupta@nxp.com/mbox/",
    "series": [
        {
            "id": 20445,
            "url": "http://patchwork.dpdk.org/api/series/20445/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=20445",
            "date": "2021-11-10T07:48:24",
            "name": "drivers/net: add NXP ENETFEC driver",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/20445/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/104100/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/104100/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 9CB31A034F;\n\tWed, 10 Nov 2021 08:48:55 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id AF5E841130;\n\tWed, 10 Nov 2021 08:48:40 +0100 (CET)",
            "from inva020.nxp.com (inva020.nxp.com [92.121.34.13])\n by mails.dpdk.org (Postfix) with ESMTP id 0D1E5410EF\n for <dev@dpdk.org>; Wed, 10 Nov 2021 08:48:36 +0100 (CET)",
            "from inva020.nxp.com (localhost [127.0.0.1])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id DE89D1A0E9A;\n Wed, 10 Nov 2021 08:48:35 +0100 (CET)",
            "from aprdc01srsp001v.ap-rdc01.nxp.com\n (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16])\n by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 7D5361A0E97;\n Wed, 10 Nov 2021 08:48:35 +0100 (CET)",
            "from lsv03186.swis.in-blr01.nxp.com (lsv03186.swis.in-blr01.nxp.com\n [92.120.146.182])\n by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 7EB21183AC8B;\n Wed, 10 Nov 2021 15:48:34 +0800 (+08)"
        ],
        "From": "Apeksha Gupta <apeksha.gupta@nxp.com>",
        "To": "ferruh.yigit@intel.com, david.marchand@redhat.com,\n andrew.rybchenko@oktetlabs.ru",
        "Cc": "dev@dpdk.org, sachin.saxena@nxp.com, hemant.agrawal@nxp.com,\n Apeksha Gupta <apeksha.gupta@nxp.com>",
        "Date": "Wed, 10 Nov 2021 13:18:28 +0530",
        "Message-Id": "<20211110074829.16654-5-apeksha.gupta@nxp.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20211110074829.16654-1-apeksha.gupta@nxp.com>",
        "References": "<20211109113432.11876-6-apeksha.gupta@nxp.com>\n <20211110074829.16654-1-apeksha.gupta@nxp.com>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "Subject": "[dpdk-dev] [PATCH v9 4/5] net/enetfec: add Rx/Tx support",
        "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": "This patch adds burst enqueue and dequeue operations to the enetfec\nPMD. Loopback mode is also added, compile time flag 'ENETFEC_LOOPBACK' is\nused to enable this feature. By default loopback mode is disabled.\nBasic features added like promiscuous enable, basic stats.\n\nSigned-off-by: Sachin Saxena <sachin.saxena@nxp.com>\nSigned-off-by: Apeksha Gupta <apeksha.gupta@nxp.com>\n---\n doc/guides/nics/enetfec.rst          |   2 +\n doc/guides/nics/features/enetfec.ini |   2 +\n drivers/net/enetfec/enet_ethdev.c    | 183 ++++++++++++++++++++++\n drivers/net/enetfec/enet_ethdev.h    |  23 +++\n drivers/net/enetfec/enet_rxtx.c      | 220 +++++++++++++++++++++++++++\n drivers/net/enetfec/meson.build      |   3 +-\n 6 files changed, 432 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/enetfec/enet_rxtx.c",
    "diff": "diff --git a/doc/guides/nics/enetfec.rst b/doc/guides/nics/enetfec.rst\nindex 2c29ad362c..63d6fb81ee 100644\n--- a/doc/guides/nics/enetfec.rst\n+++ b/doc/guides/nics/enetfec.rst\n@@ -84,6 +84,8 @@ driver.\n ENETFEC Features\n ~~~~~~~~~~~~~~~~~\n \n+- Basic stats\n+- Promiscuous\n - Linux\n - ARMv8\n \ndiff --git a/doc/guides/nics/features/enetfec.ini b/doc/guides/nics/features/enetfec.ini\nindex bdfbdbd9d4..3d8aa5b627 100644\n--- a/doc/guides/nics/features/enetfec.ini\n+++ b/doc/guides/nics/features/enetfec.ini\n@@ -4,6 +4,8 @@\n ; Refer to default.ini for the full list of available PMD features.\n ;\n [Features]\n+Promiscuous mode     = Y\n+Basic stats\t     = Y\n Linux\t\t     = Y\n ARMv8\t\t     = Y\n Usage doc\t     = Y\ndiff --git a/drivers/net/enetfec/enet_ethdev.c b/drivers/net/enetfec/enet_ethdev.c\nindex f70489ff91..8c8788ad8f 100644\n--- a/drivers/net/enetfec/enet_ethdev.c\n+++ b/drivers/net/enetfec/enet_ethdev.c\n@@ -39,6 +39,8 @@\n #define ENETFEC_RAFL_V\t\t\t0x8\n #define ENETFEC_OPD_V\t\t\t0xFFF0\n \n+/* Extended buffer descriptor */\n+#define ENETFEC_EXTENDED_BD\t\t0\n #define NUM_OF_BD_QUEUES\t\t6\n \n /* Supported Rx offloads */\n@@ -152,6 +154,40 @@ enetfec_restart(struct rte_eth_dev *dev)\n \trte_delay_us(10);\n }\n \n+static void\n+enet_free_buffers(struct rte_eth_dev *dev)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\tunsigned int i, q;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct bufdesc  *bdp;\n+\tstruct enetfec_priv_rx_q *rxq;\n+\tstruct enetfec_priv_tx_q *txq;\n+\n+\tfor (q = 0; q < dev->data->nb_rx_queues; q++) {\n+\t\trxq = fep->rx_queues[q];\n+\t\tbdp = rxq->bd.base;\n+\t\tfor (i = 0; i < rxq->bd.ring_size; i++) {\n+\t\t\tmbuf = rxq->rx_mbuf[i];\n+\t\t\trxq->rx_mbuf[i] = NULL;\n+\t\t\tif (mbuf)\n+\t\t\t\trte_pktmbuf_free(mbuf);\n+\t\t\tbdp = enet_get_nextdesc(bdp, &rxq->bd);\n+\t\t}\n+\t}\n+\n+\tfor (q = 0; q < dev->data->nb_tx_queues; q++) {\n+\t\ttxq = fep->tx_queues[q];\n+\t\tbdp = txq->bd.base;\n+\t\tfor (i = 0; i < txq->bd.ring_size; i++) {\n+\t\t\tmbuf = txq->tx_mbuf[i];\n+\t\t\ttxq->tx_mbuf[i] = NULL;\n+\t\t\tif (mbuf)\n+\t\t\t\trte_pktmbuf_free(mbuf);\n+\t\t}\n+\t}\n+}\n+\n static int\n enetfec_eth_configure(struct rte_eth_dev *dev)\n {\n@@ -165,6 +201,8 @@ static int\n enetfec_eth_start(struct rte_eth_dev *dev)\n {\n \tenetfec_restart(dev);\n+\tdev->rx_pkt_burst = &enetfec_recv_pkts;\n+\tdev->tx_pkt_burst = &enetfec_xmit_pkts;\n \n \treturn 0;\n }\n@@ -191,6 +229,100 @@ enetfec_eth_stop(struct rte_eth_dev *dev)\n \treturn 0;\n }\n \n+static int\n+enetfec_eth_close(struct rte_eth_dev *dev)\n+{\n+\tenet_free_buffers(dev);\n+\treturn 0;\n+}\n+\n+static int\n+enetfec_eth_link_update(struct rte_eth_dev *dev,\n+\t\t\tint wait_to_complete __rte_unused)\n+{\n+\tstruct rte_eth_link link;\n+\tunsigned int lstatus = 1;\n+\n+\tmemset(&link, 0, sizeof(struct rte_eth_link));\n+\n+\tlink.link_status = lstatus;\n+\tlink.link_speed = ETH_SPEED_NUM_1G;\n+\n+\tENETFEC_PMD_INFO(\"Port (%d) link is %s\\n\", dev->data->port_id,\n+\t\t\t \"Up\");\n+\n+\treturn rte_eth_linkstatus_set(dev, &link);\n+}\n+\n+static int\n+enetfec_promiscuous_enable(struct rte_eth_dev *dev)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\tuint32_t tmp;\n+\n+\ttmp = rte_read32((uint8_t *)fep->hw_baseaddr_v + ENETFEC_RCR);\n+\ttmp |= 0x8;\n+\ttmp &= ~0x2;\n+\trte_write32(rte_cpu_to_le_32(tmp),\n+\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_RCR);\n+\n+\treturn 0;\n+}\n+\n+static int\n+enetfec_multicast_enable(struct rte_eth_dev *dev)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\n+\trte_write32(rte_cpu_to_le_32(0xffffffff),\n+\t\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_GAUR);\n+\trte_write32(rte_cpu_to_le_32(0xffffffff),\n+\t\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_GALR);\n+\tdev->data->all_multicast = 1;\n+\n+\trte_write32(rte_cpu_to_le_32(0x04400002),\n+\t\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_GAUR);\n+\trte_write32(rte_cpu_to_le_32(0x10800049),\n+\t\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_GALR);\n+\n+\treturn 0;\n+}\n+\n+/* Set a MAC change in hardware. */\n+static int\n+enetfec_set_mac_address(struct rte_eth_dev *dev,\n+\t\t    struct rte_ether_addr *addr)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\n+\twritel(addr->addr_bytes[3] | (addr->addr_bytes[2] << 8) |\n+\t\t(addr->addr_bytes[1] << 16) | (addr->addr_bytes[0] << 24),\n+\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_PALR);\n+\twritel((addr->addr_bytes[5] << 16) | (addr->addr_bytes[4] << 24),\n+\t\t(uint8_t *)fep->hw_baseaddr_v + ENETFEC_PAUR);\n+\n+\trte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);\n+\n+\treturn 0;\n+}\n+\n+static int\n+enetfec_stats_get(struct rte_eth_dev *dev,\n+\t      struct rte_eth_stats *stats)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\tstruct rte_eth_stats *eth_stats = &fep->stats;\n+\n+\tstats->ipackets = eth_stats->ipackets;\n+\tstats->ibytes = eth_stats->ibytes;\n+\tstats->ierrors = eth_stats->ierrors;\n+\tstats->opackets = eth_stats->opackets;\n+\tstats->obytes = eth_stats->obytes;\n+\tstats->oerrors = eth_stats->oerrors;\n+\n+\treturn 0;\n+}\n+\n static int\n enetfec_eth_info(__rte_unused struct rte_eth_dev *dev,\n \tstruct rte_eth_dev_info *dev_info)\n@@ -202,6 +334,18 @@ enetfec_eth_info(__rte_unused struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n+static void\n+enet_free_queue(struct rte_eth_dev *dev)\n+{\n+\tstruct enetfec_private *fep = dev->data->dev_private;\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++)\n+\t\trte_free(fep->rx_queues[i]);\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++)\n+\t\trte_free(fep->rx_queues[i]);\n+}\n+\n static const unsigned short offset_des_active_rxq[] = {\n \tENETFEC_RDAR_0, ENETFEC_RDAR_1, ENETFEC_RDAR_2\n };\n@@ -407,6 +551,12 @@ static const struct eth_dev_ops enetfec_ops = {\n \t.dev_configure          = enetfec_eth_configure,\n \t.dev_start              = enetfec_eth_start,\n \t.dev_stop               = enetfec_eth_stop,\n+\t.dev_close              = enetfec_eth_close,\n+\t.link_update            = enetfec_eth_link_update,\n+\t.promiscuous_enable     = enetfec_promiscuous_enable,\n+\t.allmulticast_enable    = enetfec_multicast_enable,\n+\t.mac_addr_set           = enetfec_set_mac_address,\n+\t.stats_get              = enetfec_stats_get,\n \t.dev_infos_get          = enetfec_eth_info,\n \t.rx_queue_setup         = enetfec_rx_queue_setup,\n \t.tx_queue_setup         = enetfec_tx_queue_setup\n@@ -432,6 +582,9 @@ pmd_enetfec_probe(struct rte_vdev_device *vdev)\n \tint rc;\n \tint i;\n \tunsigned int bdsize;\n+\tstruct rte_ether_addr macaddr = {\n+\t\t.addr_bytes = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }\n+\t};\n \n \tname = rte_vdev_device_name(vdev);\n \tif (name == NULL)\n@@ -474,6 +627,21 @@ pmd_enetfec_probe(struct rte_vdev_device *vdev)\n \t\tfep->bd_addr_p = fep->bd_addr_p + bdsize;\n \t}\n \n+\t/* Copy the station address into the dev structure, */\n+\tdev->data->mac_addrs = rte_zmalloc(\"mac_addr\", RTE_ETHER_ADDR_LEN, 0);\n+\tif (dev->data->mac_addrs == NULL) {\n+\t\tENETFEC_PMD_ERR(\"Failed to allocate mem %d to store MAC addresses\",\n+\t\t\tRTE_ETHER_ADDR_LEN);\n+\t\trc = -ENOMEM;\n+\t\tgoto err;\n+\t}\n+\n+\t/*\n+\t * Set default mac address\n+\t */\n+\tenetfec_set_mac_address(dev, &macaddr);\n+\n+\tfep->bufdesc_ex = ENETFEC_EXTENDED_BD;\n \trc = enetfec_eth_init(dev);\n \tif (rc)\n \t\tgoto failed_init;\n@@ -482,6 +650,8 @@ pmd_enetfec_probe(struct rte_vdev_device *vdev)\n \n failed_init:\n \tENETFEC_PMD_ERR(\"Failed to init\");\n+err:\n+\trte_eth_dev_release_port(dev);\n \treturn rc;\n }\n \n@@ -489,6 +659,8 @@ static int\n pmd_enetfec_remove(struct rte_vdev_device *vdev)\n {\n \tstruct rte_eth_dev *eth_dev = NULL;\n+\tstruct enetfec_private *fep;\n+\tstruct enetfec_priv_rx_q *rxq;\n \tint ret;\n \n \t/* find the ethdev entry */\n@@ -496,11 +668,22 @@ pmd_enetfec_remove(struct rte_vdev_device *vdev)\n \tif (eth_dev == NULL)\n \t\treturn -ENODEV;\n \n+\tfep = eth_dev->data->dev_private;\n+\t/* Free descriptor base of first RX queue as it was configured\n+\t * first in enetfec_eth_init().\n+\t */\n+\trxq = fep->rx_queues[0];\n+\trte_free(rxq->bd.base);\n+\tenet_free_queue(eth_dev);\n+\tenetfec_eth_stop(eth_dev);\n+\n \tret = rte_eth_dev_release_port(eth_dev);\n \tif (ret != 0)\n \t\treturn -EINVAL;\n \n \tENETFEC_PMD_INFO(\"Release enetfec sw device\");\n+\tenetfec_cleanup(fep);\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/enetfec/enet_ethdev.h b/drivers/net/enetfec/enet_ethdev.h\nindex babc7190fb..c6f8cf7f03 100644\n--- a/drivers/net/enetfec/enet_ethdev.h\n+++ b/drivers/net/enetfec/enet_ethdev.h\n@@ -7,6 +7,10 @@\n \n #include <rte_ethdev.h>\n \n+#define BD_LEN\t\t\t49152\n+#define ENETFEC_TX_FR_SIZE\t2048\n+#define ETH_HLEN\t\tRTE_ETHER_HDR_LEN\n+\n /* full duplex */\n #define FULL_DUPLEX             0x00\n \n@@ -17,6 +21,20 @@\n #define ENETFEC_MAX_RX_PKT_LEN  3000\n \n #define __iomem\n+#if defined(RTE_ARCH_ARM)\n+#if defined(RTE_ARCH_64)\n+#define dcbf(p) { asm volatile(\"dc cvac, %0\" : : \"r\"(p) : \"memory\"); }\n+#define dcbf_64(p) dcbf(p)\n+\n+#else /* RTE_ARCH_32 */\n+#define dcbf(p) RTE_SET_USED(p)\n+#define dcbf_64(p) dcbf(p)\n+#endif\n+\n+#else\n+#define dcbf(p) RTE_SET_USED(p)\n+#define dcbf_64(p) dcbf(p)\n+#endif\n \n /*\n  * ENETFEC can support 1 rx and tx queue..\n@@ -128,4 +146,9 @@ enet_get_bd_index(struct bufdesc *bdp, struct bufdesc_prop *bd)\n \treturn ((const char *)bdp - (const char *)bd->base) >> bd->d_size_log2;\n }\n \n+uint16_t enetfec_recv_pkts(void *rxq1, __rte_unused struct rte_mbuf **rx_pkts,\n+\t\tuint16_t nb_pkts);\n+uint16_t enetfec_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n+\t\tuint16_t nb_pkts);\n+\n #endif /*__ENETFEC_ETHDEV_H__*/\ndiff --git a/drivers/net/enetfec/enet_rxtx.c b/drivers/net/enetfec/enet_rxtx.c\nnew file mode 100644\nindex 0000000000..4e6a263e67\n--- /dev/null\n+++ b/drivers/net/enetfec/enet_rxtx.c\n@@ -0,0 +1,220 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2021 NXP\n+ */\n+\n+#include <signal.h>\n+#include <rte_mbuf.h>\n+#include <rte_io.h>\n+#include \"enet_regs.h\"\n+#include \"enet_ethdev.h\"\n+#include \"enet_pmd_logs.h\"\n+\n+/* This function does enetfec_rx_queue processing. Dequeue packet from Rx queue\n+ * When update through the ring, just set the empty indicator.\n+ */\n+uint16_t\n+enetfec_recv_pkts(void *rxq1, __rte_unused struct rte_mbuf **rx_pkts,\n+\t\tuint16_t nb_pkts)\n+{\n+\tstruct rte_mempool *pool;\n+\tstruct bufdesc *bdp;\n+\tstruct rte_mbuf *mbuf, *new_mbuf = NULL;\n+\tunsigned short status;\n+\tunsigned short pkt_len;\n+\tint pkt_received = 0, index = 0;\n+\tvoid *data;\n+\tstruct enetfec_priv_rx_q *rxq  = (struct enetfec_priv_rx_q *)rxq1;\n+\tstruct rte_eth_stats *stats = &rxq->fep->stats;\n+\tpool = rxq->pool;\n+\tbdp = rxq->bd.cur;\n+\n+\t/* Process the incoming packet */\n+\tstatus = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));\n+\twhile ((status & RX_BD_EMPTY) == 0) {\n+\t\tif (pkt_received >= nb_pkts)\n+\t\t\tbreak;\n+\n+\t\tnew_mbuf = rte_pktmbuf_alloc(pool);\n+\t\tif (unlikely(new_mbuf == NULL)) {\n+\t\t\tstats->ierrors++;\n+\t\t\tbreak;\n+\t\t}\n+\t\t/* Check for errors. */\n+\t\tstatus ^= RX_BD_LAST;\n+\t\tif (status & (RX_BD_LG | RX_BD_SH | RX_BD_NO |\n+\t\t\tRX_BD_CR | RX_BD_OV | RX_BD_LAST |\n+\t\t\tRX_BD_TR)) {\n+\t\t\tstats->ierrors++;\n+\t\t\tif (status & RX_BD_OV) {\n+\t\t\t\t/* FIFO overrun */\n+\t\t\t\t/* enet_dump_rx(rxq); */\n+\t\t\t\tENETFEC_DP_LOG(DEBUG, \"rx_fifo_error\");\n+\t\t\t\tgoto rx_processing_done;\n+\t\t\t}\n+\t\t\tif (status & (RX_BD_LG | RX_BD_SH\n+\t\t\t\t\t\t| RX_BD_LAST)) {\n+\t\t\t\t/* Frame too long or too short. */\n+\t\t\t\tENETFEC_DP_LOG(DEBUG, \"rx_length_error\");\n+\t\t\t\tif (status & RX_BD_LAST)\n+\t\t\t\t\tENETFEC_DP_LOG(DEBUG, \"rcv is not +last\");\n+\t\t\t}\n+\t\t\tif (status & RX_BD_CR) {     /* CRC Error */\n+\t\t\t\tENETFEC_DP_LOG(DEBUG, \"rx_crc_errors\");\n+\t\t\t}\n+\t\t\t/* Report late collisions as a frame error. */\n+\t\t\tif (status & (RX_BD_NO | RX_BD_TR))\n+\t\t\t\tENETFEC_DP_LOG(DEBUG, \"rx_frame_error\");\n+\t\t\tgoto rx_processing_done;\n+\t\t}\n+\n+\t\t/* Process the incoming frame. */\n+\t\tstats->ipackets++;\n+\t\tpkt_len = rte_le_to_cpu_16(rte_read16(&bdp->bd_datlen));\n+\t\tstats->ibytes += pkt_len;\n+\n+\t\t/* shows data with respect to the data_off field. */\n+\t\tindex = enet_get_bd_index(bdp, &rxq->bd);\n+\t\tmbuf = rxq->rx_mbuf[index];\n+\n+\t\tdata = rte_pktmbuf_mtod(mbuf, uint8_t *);\n+\t\trte_prefetch0(data);\n+\t\trte_pktmbuf_append((struct rte_mbuf *)mbuf,\n+\t\t\t\tpkt_len - 4);\n+\n+\t\tif (rxq->fep->quirks & QUIRK_RACC)\n+\t\t\tdata = rte_pktmbuf_adj(mbuf, 2);\n+\n+\t\trx_pkts[pkt_received] = mbuf;\n+\t\tpkt_received++;\n+\t\trxq->rx_mbuf[index] = new_mbuf;\n+\t\trte_write32(rte_cpu_to_le_32(rte_pktmbuf_iova(new_mbuf)),\n+\t\t\t\t&bdp->bd_bufaddr);\n+rx_processing_done:\n+\t\t/* when rx_processing_done clear the status flags\n+\t\t * for this buffer\n+\t\t */\n+\t\tstatus &= ~RX_BD_STATS;\n+\n+\t\t/* Mark the buffer empty */\n+\t\tstatus |= RX_BD_EMPTY;\n+\n+\t\tif (rxq->fep->bufdesc_ex) {\n+\t\t\tstruct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;\n+\t\t\trte_write32(rte_cpu_to_le_32(RX_BD_INT),\n+\t\t\t\t    &ebdp->bd_esc);\n+\t\t\trte_write32(0, &ebdp->bd_prot);\n+\t\t\trte_write32(0, &ebdp->bd_bdu);\n+\t\t}\n+\n+\t\t/* Make sure the updates to rest of the descriptor are\n+\t\t * performed before transferring ownership.\n+\t\t */\n+\t\trte_wmb();\n+\t\trte_write16(rte_cpu_to_le_16(status), &bdp->bd_sc);\n+\n+\t\t/* Update BD pointer to next entry */\n+\t\tbdp = enet_get_nextdesc(bdp, &rxq->bd);\n+\n+\t\t/* Doing this here will keep the FEC running while we process\n+\t\t * incoming frames.\n+\t\t */\n+\t\trte_write32(0, rxq->bd.active_reg_desc);\n+\t\tstatus = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));\n+\t}\n+\trxq->bd.cur = bdp;\n+\treturn pkt_received;\n+}\n+\n+uint16_t\n+enetfec_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)\n+{\n+\tstruct enetfec_priv_tx_q *txq  =\n+\t\t\t(struct enetfec_priv_tx_q *)tx_queue;\n+\tstruct rte_eth_stats *stats = &txq->fep->stats;\n+\tstruct bufdesc *bdp, *last_bdp;\n+\tstruct rte_mbuf *mbuf;\n+\tunsigned short status;\n+\tunsigned short buflen;\n+\tunsigned int index, estatus = 0;\n+\tunsigned int i, pkt_transmitted = 0;\n+\tuint8_t *data;\n+\tint tx_st = 1;\n+\n+\twhile (tx_st) {\n+\t\tif (pkt_transmitted >= nb_pkts) {\n+\t\t\ttx_st = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tbdp = txq->bd.cur;\n+\t\t/* First clean the ring */\n+\t\tindex = enet_get_bd_index(bdp, &txq->bd);\n+\t\tstatus = rte_le_to_cpu_16(rte_read16(&bdp->bd_sc));\n+\n+\t\tif (status & TX_BD_READY) {\n+\t\t\tstats->oerrors++;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (txq->tx_mbuf[index]) {\n+\t\t\trte_pktmbuf_free(txq->tx_mbuf[index]);\n+\t\t\ttxq->tx_mbuf[index] = NULL;\n+\t\t}\n+\n+\t\tmbuf = *(tx_pkts);\n+\t\ttx_pkts++;\n+\n+\t\t/* Fill in a Tx ring entry */\n+\t\tlast_bdp = bdp;\n+\t\tstatus &= ~TX_BD_STATS;\n+\n+\t\t/* Set buffer length and buffer pointer */\n+\t\tbuflen = rte_pktmbuf_pkt_len(mbuf);\n+\t\tstats->opackets++;\n+\t\tstats->obytes += buflen;\n+\n+\t\tif (mbuf->nb_segs > 1) {\n+\t\t\tENETFEC_PMD_DEBUG(\"SG not supported\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tstatus |= (TX_BD_LAST);\n+\t\tdata = rte_pktmbuf_mtod(mbuf, void *);\n+\t\tfor (i = 0; i <= buflen; i += RTE_CACHE_LINE_SIZE)\n+\t\t\tdcbf(data + i);\n+\n+\t\trte_write32(rte_cpu_to_le_32(rte_pktmbuf_iova(mbuf)),\n+\t\t\t    &bdp->bd_bufaddr);\n+\t\trte_write16(rte_cpu_to_le_16(buflen), &bdp->bd_datlen);\n+\n+\t\tif (txq->fep->bufdesc_ex) {\n+\t\t\tstruct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;\n+\t\t\trte_write32(0, &ebdp->bd_bdu);\n+\t\t\trte_write32(rte_cpu_to_le_32(estatus),\n+\t\t\t\t    &ebdp->bd_esc);\n+\t\t}\n+\n+\t\tindex = enet_get_bd_index(last_bdp, &txq->bd);\n+\t\t/* Save mbuf pointer */\n+\t\ttxq->tx_mbuf[index] = mbuf;\n+\n+\t\t/* Make sure the updates to rest of the descriptor are performed\n+\t\t * before transferring ownership.\n+\t\t */\n+\t\tstatus |= (TX_BD_READY | TX_BD_TC);\n+\t\trte_wmb();\n+\t\trte_write16(rte_cpu_to_le_16(status), &bdp->bd_sc);\n+\n+\t\t/* Trigger transmission start */\n+\t\trte_write32(0, txq->bd.active_reg_desc);\n+\t\tpkt_transmitted++;\n+\n+\t\t/* If this was the last BD in the ring, start at the\n+\t\t * beginning again.\n+\t\t */\n+\t\tbdp = enet_get_nextdesc(last_bdp, &txq->bd);\n+\n+\t\t/* Make sure the update to bdp and tx_skbuff are performed\n+\t\t * before txq->bd.cur.\n+\t\t */\n+\t\ttxq->bd.cur = bdp;\n+\t}\n+\treturn nb_pkts;\n+}\ndiff --git a/drivers/net/enetfec/meson.build b/drivers/net/enetfec/meson.build\nindex 57f316b8a5..79dca58dea 100644\n--- a/drivers/net/enetfec/meson.build\n+++ b/drivers/net/enetfec/meson.build\n@@ -7,4 +7,5 @@ if not is_linux\n endif\n \n sources = files('enet_ethdev.c',\n-\t\t'enet_uio.c')\n+\t\t'enet_uio.c',\n+\t\t'enet_rxtx.c')\n",
    "prefixes": [
        "v9",
        "4/5"
    ]
}