From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 00166A0561; Thu, 4 Mar 2021 17:57:14 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AA8E622A2E5; Thu, 4 Mar 2021 17:56:58 +0100 (CET) Received: from mail-qk1-f181.google.com (mail-qk1-f181.google.com [209.85.222.181]) by mails.dpdk.org (Postfix) with ESMTP id CC5EB22A2DA for ; Thu, 4 Mar 2021 17:56:57 +0100 (CET) Received: by mail-qk1-f181.google.com with SMTP id f124so10278966qkj.5 for ; Thu, 04 Mar 2021 08:56:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=atomicrules-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y9m7mwQsnE1kRUjDUK62rGUdKXenT35z1f9nBTISu/Q=; b=Fhx1YYJleLivaBN078C9MgpXe9CrvqZWIfNnO9PFPdXtc0Nn00gAz/on1TmX2Ym97Z o4RBVggWM3VzOj2/yaXvH8bvKQtpHvsqXNlCQkNU59Z1FAFvWuBL6AEbszMzXv6WB8Pz Oby/YMT+8Yr4eq3+y8r98x+pQZXfjuToD55nAKlnMX9kdiR7uljI8/WQm2FXkIHNh66X smGD2N/mYR2rOEwGdLuE2GfP+6QJXVscFxdripyLM3ewDHjB6M8zj1KbP/9wrv4oV4kA ycUYv/oTjQ8XN3RvLn3Gxl2Ny36m8mbI+Qv9VEZHJev1GUk8PdVdmWtGFdNZrfbmB26E VTbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y9m7mwQsnE1kRUjDUK62rGUdKXenT35z1f9nBTISu/Q=; b=LLJfMFUN783K5su0pJ/xh+vZjLG9Yp+gKk4eIztcsQqvvUYkZybZpOIScC0m8JsNZm yxDyDepyPZWjjo9F6jTQdgulDLtX41LzdTbVKNL+N9Us6H3Jvg//Rxys8ans6SnbopWH ZaGixZqBz8I5oVwMtDu4tkCBoHOFP2ffpFgnty+GWyahuQoDkEi5dKVtlIwHVWm6jMQs aLFFYRPlTRuVCyOAoluQ7L1eY1agxt7xTNzVznjatl/DdGxPWOYZAalLNtiEvwSjAJ3j WGTsap5pXdzFEwxpKHc7LfK1oVm68vKoKgEL/WKntGgQRCPj6ouDCxEPmsVTwgUbO07z CQZw== X-Gm-Message-State: AOAM533c1lRw5Ml5jLjTBX2zMeQWZIcphfJdfR4OZK8kGYOXcG4/anI/ ZbhsFGimDkJ7ePmnwA+1lPP+kroCHNQJ0w== X-Google-Smtp-Source: ABdhPJy9KKnBDd7r098cWlyFrpfUdTrjZ62e+U+GXfq1v6tOu5FaoleNbs9D1l1QN/x39TcS9fXFSQ== X-Received: by 2002:a37:ab0f:: with SMTP id u15mr4927700qke.438.1614877016353; Thu, 04 Mar 2021 08:56:56 -0800 (PST) Received: from z390.czeck.local (pool-72-74-133-40.bstnma.fios.verizon.net. [72.74.133.40]) by smtp.gmail.com with ESMTPSA id 131sm19566764qkl.74.2021.03.04.08.56.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 08:56:55 -0800 (PST) From: Ed Czeck To: dev@dpdk.org, ferruh.yigit@intel.com Cc: shepard.siegel@atomicrules.com, john.miller@atomicrules.com Date: Thu, 4 Mar 2021 11:56:36 -0500 Message-Id: <20210304165637.24658-4-ed.czeck@atomicrules.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210304165637.24658-1-ed.czeck@atomicrules.com> References: <20210304165637.24658-1-ed.czeck@atomicrules.com> Subject: [dpdk-dev] [PATCH v1 4/5] net/ark: generalize meta data between FPGA and PMD X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" In this commit we generalize the movement of user-specified meta data between mbufs and FPGA AXIS tuser fields using user-defined hook functions. - Previous use of PMD dynfields are removed - Hook function added to ark_user_ext - Add hook function calls in rx and tx paths - Rename all extension function with rte_pmd_ark prefix - Move extension prototype to rte_pmd_ark.h - Update documentation with an extension example Signed-off-by: Ed Czeck --- doc/guides/nics/ark.rst | 137 +++++++++++- drivers/net/ark/ark_ethdev.c | 90 ++------ drivers/net/ark/ark_ethdev_rx.c | 27 ++- drivers/net/ark/ark_ethdev_rx.h | 3 - drivers/net/ark/ark_ethdev_tx.c | 23 +- drivers/net/ark/ark_ext.h | 90 -------- drivers/net/ark/ark_global.h | 20 ++ drivers/net/ark/ark_udm.h | 5 +- drivers/net/ark/rte_pmd_ark.h | 382 +++++++++++++++++++++++--------- drivers/net/ark/version.map | 7 - 10 files changed, 485 insertions(+), 299 deletions(-) delete mode 100644 drivers/net/ark/ark_ext.h diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst index 18434c7a4..b9c108b9b 100644 --- a/doc/guides/nics/ark.rst +++ b/doc/guides/nics/ark.rst @@ -1,5 +1,5 @@ .. SPDX-License-Identifier: BSD-3-Clause - Copyright (c) 2015-2017 Atomic Rules LLC + Copyright (c) 2015-2021 Atomic Rules LLC All rights reserved. ARK Poll Mode Driver @@ -130,6 +130,141 @@ Configuration Information be offloaded or remain in host software. +Dynamic PMD Extension +--------------------- + +Dynamic PMD extensions allow users to customize net/ark functionality +using their own code. Arkville RTL and this PMD support high-throughput data +movement, and these extensions allow PMD support for users' FPGA +features. +Dynamic PMD extensions operate by having users supply a shared object +file which is loaded by Arkville PMD during initialization. The +object file contains extension (or hook) functions that are registered +and then called during PMD operations. + +The allowable set of extension functions are defined and documented in +``rte_pmd_ark.h``, only the initialization function, +``rte_pmd_ark_dev_init()``, is required; all others are optional. The +following sections give a small extension example along with +instructions for compiling and using the extension. + + +Extension Example +^^^^^^^^^^^^^^^^^ + +The following example shows an extension which populates mbuf fields +during RX from user meta data coming from FPGA hardware. + +.. code-block:: c + + #include + #include + #include + #include + + /* Global structure passed to extension/hook functions */ + struct ark_user_extension { + int timestamp_dynfield_offset; + }; + + /* RX tuser field based on user's hardware */ + struct user_rx_meta { + uint64_t timestamp; + uint32_t rss; + } __rte_packed; + + /* Create ark_user_extension object for use in other hook functions */ + void *rte_pmd_ark_dev_init(struct rte_eth_dev * dev, + void * abar, int port_id ) + { + RTE_SET_USED(dev); + RTE_SET_USED(abar); + fprintf(stderr, "Called Arkville user extension for port %u\n", + port_id); + + struct ark_user_extension *xdata = rte_zmalloc("macExtS", + sizeof(struct ark_user_extension), 64); + if (!xdata) + return NULL; + + /* register dynfield for rx timestamp */ + rte_mbuf_dyn_rx_timestamp_register(&xdata->timestamp_dynfield_offset, + NULL); + + fprintf(stderr, "timestamp fields offset in extension is %d\n", + xdata->timestamp_dynfield_offset); + return xdata; + } + + /* uninitialization */ + void rte_pmd_ark_dev_uninit(struct rte_eth_dev * dev, void *user_data) + { + rte_free(user_data); + } + + /* Hook function -- called for each RX packet + * Extract RX timestamp and RSS from meta and place in mbuf + */ + void rte_pmd_ark_rx_user_meta_hook(struct rte_mbuf *mbuf, + const uint32_t *meta, + void *user_data) + { + struct ark_user_extension *xdata = user_data; + struct user_rx_meta *user_rx = (struct user_rx_meta*)meta; + *RTE_MBUF_DYNFIELD(mbuf, xdata->timestamp_dynfield_offset, uint64_t*) = + user_rx->timestamp; + mbuf->hash.rss = user_rx->rss; + } + + +Compiling Extension +^^^^^^^^^^^^^^^^^^^ + +It is recommended to the compile the extension code with +``-Wmissing-prototypes`` flag to insure correct function types. Typical +DPDK options will also be needed. + + +An example command line is give below + +.. code-block:: console + + cc `pkg-config --cflags libdpdk` \ + -O3 -DALLOW_EXPERIMENTAL_API -fPIC -Wall -Wmissing-prototypes -c \ + -o pmd_net_ark_ext.o pmd_net_ark_ext.c + # Linking + cc -o libfx1_100g_ext.so.1 -shared \ + `pkg-config --libs libdpdk` \ + -Wl,--unresolved-symbols=ignore-all \ + -Wl,-soname,libpmd_net_ark_ext.so.1 pmd_net_ark_ext.o + +In a ``Makefile`` this would be + +.. code-block:: Makefile + + CFLAGS += $(shell pkg-config --cflags libdpdk) + CFLAGS += -O3 -DALLOW_EXPERIMENTAL_API -fPIC -Wall -Wmissing-prototypes + # Linking + LDFLAGS += $(shell pkg-config --libs libdpdk) + LDFLAGS += -Wl,--unresolved-symbols=ignore-all -Wl,-soname,libpmd_net_ark_ext.so.1 + +The application must be linked with the ``-export-dynamic`` flags if any +DPDK or application specific code will called from the extension. + + +Enabling Extension +^^^^^^^^^^^^^^^^^^ + +The extensions are enabled in the application through the use of an +environment variable ``ARK_EXT_PATH`` This variable points to the lib +extension file generated above. For example: + +.. code-block:: console + + export ARK_EXT_PATH=$(PWD)/libpmd_net_ark_ext.so.1 + testpmd ... + + Building DPDK ------------- diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c index fc6d53a35..edbcfe8d4 100644 --- a/drivers/net/ark/ark_ethdev.c +++ b/drivers/net/ark/ark_ethdev.c @@ -79,12 +79,6 @@ static int eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size); #define ARK_TX_MAX_QUEUE (4096 * 4) #define ARK_TX_MIN_QUEUE (256) -uint64_t ark_timestamp_rx_dynflag; -int ark_timestamp_dynfield_offset = -1; - -int rte_pmd_ark_rx_userdata_dynfield_offset = -1; -int rte_pmd_ark_tx_userdata_dynfield_offset = -1; - static const char * const valid_arguments[] = { ARK_PKTGEN_ARG, ARK_PKTCHKR_ARG, @@ -190,58 +184,64 @@ check_for_ext(struct ark_adapter *ark) /* Get the entry points */ ark->user_ext.dev_init = (void *(*)(struct rte_eth_dev *, void *, int)) - dlsym(ark->d_handle, "dev_init"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_init"); ARK_PMD_LOG(DEBUG, "device ext init pointer = %p\n", ark->user_ext.dev_init); ark->user_ext.dev_get_port_count = (int (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_get_port_count"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_get_port_count"); ark->user_ext.dev_uninit = (void (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_uninit"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_uninit"); ark->user_ext.dev_configure = (int (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_configure"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_configure"); ark->user_ext.dev_start = (int (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_start"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_start"); ark->user_ext.dev_stop = (void (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_stop"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_stop"); ark->user_ext.dev_close = (void (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_close"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_close"); ark->user_ext.link_update = (int (*)(struct rte_eth_dev *, int, void *)) - dlsym(ark->d_handle, "link_update"); + dlsym(ark->d_handle, "rte_pmd_ark_link_update"); ark->user_ext.dev_set_link_up = (int (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_set_link_up"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_up"); ark->user_ext.dev_set_link_down = (int (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "dev_set_link_down"); + dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_down"); ark->user_ext.stats_get = (int (*)(struct rte_eth_dev *, struct rte_eth_stats *, void *)) - dlsym(ark->d_handle, "stats_get"); + dlsym(ark->d_handle, "rte_pmd_ark_stats_get"); ark->user_ext.stats_reset = (void (*)(struct rte_eth_dev *, void *)) - dlsym(ark->d_handle, "stats_reset"); + dlsym(ark->d_handle, "rte_pmd_ark_stats_reset"); ark->user_ext.mac_addr_add = (void (*)(struct rte_eth_dev *, struct rte_ether_addr *, uint32_t, uint32_t, void *)) - dlsym(ark->d_handle, "mac_addr_add"); + dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_add"); ark->user_ext.mac_addr_remove = (void (*)(struct rte_eth_dev *, uint32_t, void *)) - dlsym(ark->d_handle, "mac_addr_remove"); + dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_remove"); ark->user_ext.mac_addr_set = (void (*)(struct rte_eth_dev *, struct rte_ether_addr *, void *)) - dlsym(ark->d_handle, "mac_addr_set"); + dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_set"); ark->user_ext.set_mtu = (int (*)(struct rte_eth_dev *, uint16_t, void *)) - dlsym(ark->d_handle, "set_mtu"); + dlsym(ark->d_handle, "rte_pmd_ark_set_mtu"); + ark->user_ext.rx_user_meta_hook = + (rx_user_meta_hook_fn)dlsym(ark->d_handle, + "rte_pmd_ark_rx_user_meta_hook"); + ark->user_ext.tx_user_meta_hook = + (tx_user_meta_hook_fn)dlsym(ark->d_handle, + "rte_pmd_ark_tx_user_meta_hook"); return found; } @@ -254,16 +254,6 @@ eth_ark_dev_init(struct rte_eth_dev *dev) int ret; int port_count = 1; int p; - static const struct rte_mbuf_dynfield ark_tx_userdata_dynfield_desc = { - .name = RTE_PMD_ARK_TX_USERDATA_DYNFIELD_NAME, - .size = sizeof(rte_pmd_ark_tx_userdata_t), - .align = __alignof__(rte_pmd_ark_tx_userdata_t), - }; - static const struct rte_mbuf_dynfield ark_rx_userdata_dynfield_desc = { - .name = RTE_PMD_ARK_RX_USERDATA_DYNFIELD_NAME, - .size = sizeof(rte_pmd_ark_rx_userdata_t), - .align = __alignof__(rte_pmd_ark_rx_userdata_t), - }; ark->eth_dev = dev; @@ -274,30 +264,6 @@ eth_ark_dev_init(struct rte_eth_dev *dev) if (ret) return ret; - /* Extra mbuf fields for user data */ - if (RTE_PMD_ARK_TX_USERDATA_ENABLE) { - rte_pmd_ark_tx_userdata_dynfield_offset = - rte_mbuf_dynfield_register(&ark_tx_userdata_dynfield_desc); - if (rte_pmd_ark_tx_userdata_dynfield_offset < 0) { - ARK_PMD_LOG(ERR, - "Failed to register mbuf field for tx userdata\n"); - return -rte_errno; - } - ARK_PMD_LOG(INFO, "Registered TX-meta dynamic field at %d\n", - rte_pmd_ark_tx_userdata_dynfield_offset); - } - if (RTE_PMD_ARK_RX_USERDATA_ENABLE) { - rte_pmd_ark_rx_userdata_dynfield_offset = - rte_mbuf_dynfield_register(&ark_rx_userdata_dynfield_desc); - if (rte_pmd_ark_rx_userdata_dynfield_offset < 0) { - ARK_PMD_LOG(ERR, - "Failed to register mbuf field for rx userdata\n"); - return -rte_errno; - } - ARK_PMD_LOG(INFO, "Registered RX-meta dynamic field at %d\n", - rte_pmd_ark_rx_userdata_dynfield_offset); - } - pci_dev = RTE_ETH_DEV_TO_PCI(dev); rte_eth_copy_pci_info(dev, pci_dev); dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; @@ -558,18 +524,6 @@ static int eth_ark_dev_configure(struct rte_eth_dev *dev) { struct ark_adapter *ark = dev->data->dev_private; - int ret; - - if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP) { - ret = rte_mbuf_dyn_rx_timestamp_register( - &ark_timestamp_dynfield_offset, - &ark_timestamp_rx_dynflag); - if (ret != 0) { - ARK_PMD_LOG(ERR, - "Failed to register Rx timestamp field/flag\n"); - return -rte_errno; - } - } eth_ark_dev_set_link_up(dev); if (ark->user_ext.dev_configure) diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c index 21a9af41a..48ea48404 100644 --- a/drivers/net/ark/ark_ethdev_rx.c +++ b/drivers/net/ark/ark_ethdev_rx.c @@ -39,6 +39,9 @@ struct ark_rx_queue { struct ark_udm_t *udm; struct ark_mpu_t *mpu; + rx_user_meta_hook_fn rx_user_meta_hook; + void *ext_user_data; + uint32_t queue_size; uint32_t queue_mask; @@ -53,8 +56,7 @@ struct ark_rx_queue { uint32_t unused; - /* separate cache line */ - /* second cache line - fields only used in slow path */ + /* next cache line - fields written by device */ RTE_MARKER cacheline1 __rte_cache_min_aligned; volatile uint32_t prod_index; /* step 2 filled by FPGA */ @@ -167,6 +169,8 @@ eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev, queue->queue_index = queue_idx; queue->queue_size = nb_desc; queue->queue_mask = nb_desc - 1; + queue->rx_user_meta_hook = ark->user_ext.rx_user_meta_hook; + queue->ext_user_data = ark->user_data[dev->data->port_id]; queue->reserve_q = rte_zmalloc_socket("Ark_rx_queue mbuf", @@ -243,8 +247,11 @@ eth_ark_recv_pkts(void *rx_queue, struct ark_rx_queue *queue; register uint32_t cons_index, prod_index; uint16_t nb; + uint16_t i; struct rte_mbuf *mbuf; + struct rte_mbuf **pmbuf; struct ark_rx_meta *meta; + rx_user_meta_hook_fn rx_user_meta_hook; queue = (struct ark_rx_queue *)rx_queue; if (unlikely(queue == 0)) @@ -253,6 +260,8 @@ eth_ark_recv_pkts(void *rx_queue, return 0; prod_index = queue->prod_index; cons_index = queue->cons_index; + if (prod_index == cons_index) + return 0; nb = 0; while (prod_index != cons_index) { @@ -266,13 +275,6 @@ eth_ark_recv_pkts(void *rx_queue, mbuf->pkt_len = meta->pkt_len; mbuf->data_len = meta->pkt_len; - /* set timestamp if enabled at least on one device */ - if (ark_timestamp_rx_dynflag > 0) { - *RTE_MBUF_DYNFIELD(mbuf, ark_timestamp_dynfield_offset, - rte_mbuf_timestamp_t *) = meta->timestamp; - mbuf->ol_flags |= ark_timestamp_rx_dynflag; - } - rte_pmd_ark_mbuf_rx_userdata_set(mbuf, meta->user_data); if (ARK_DEBUG_CORE) { /* debug sanity checks */ if ((meta->pkt_len > (1024 * 16)) || @@ -315,6 +317,13 @@ eth_ark_recv_pkts(void *rx_queue, break; } + rx_user_meta_hook = queue->rx_user_meta_hook; + for (pmbuf = rx_pkts, i = 0; rx_user_meta_hook && i < nb; i++) { + mbuf = *pmbuf++; + meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET); + rx_user_meta_hook(mbuf, meta->user_meta, queue->ext_user_data); + } + eth_ark_rx_update_cons_index(queue, cons_index); return nb; diff --git a/drivers/net/ark/ark_ethdev_rx.h b/drivers/net/ark/ark_ethdev_rx.h index 33c1f2c95..c8dc340a8 100644 --- a/drivers/net/ark/ark_ethdev_rx.h +++ b/drivers/net/ark/ark_ethdev_rx.h @@ -11,9 +11,6 @@ #include #include -extern uint64_t ark_timestamp_rx_dynflag; -extern int ark_timestamp_dynfield_offset; - int eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, uint16_t nb_desc, diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c index efd3d3fca..bea0cb8d4 100644 --- a/drivers/net/ark/ark_ethdev_tx.c +++ b/drivers/net/ark/ark_ethdev_tx.c @@ -33,6 +33,9 @@ struct ark_tx_queue { /* Stats HW tracks bytes and packets, need to count send errors */ uint64_t tx_errors; + tx_user_meta_hook_fn tx_user_meta_hook; + void *ext_user_data; + uint32_t queue_size; uint32_t queue_mask; @@ -45,9 +48,7 @@ struct ark_tx_queue { /* The queue Index within the dpdk device structures */ uint16_t queue_index; - uint32_t pad[1]; - - /* second cache line - fields written by device */ + /* next cache line - fields written by device */ RTE_MARKER cacheline1 __rte_cache_min_aligned; volatile int32_t cons_index; /* hw is done, can be freed */ } __rte_cache_aligned; @@ -120,15 +121,17 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { struct ark_tx_queue *queue; struct rte_mbuf *mbuf; - uint32_t user_meta; + uint32_t user_meta[5]; int stat; int32_t prod_index_limit; uint16_t nb; - uint8_t user_len = 1; + uint8_t user_len = 0; const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN; + tx_user_meta_hook_fn tx_user_meta_hook; queue = (struct ark_tx_queue *)vtxq; + tx_user_meta_hook = queue->tx_user_meta_hook; /* free any packets after the HW is done with them */ free_completed_tx(queue); @@ -163,16 +166,18 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) memset(appended, 0, to_add); } - user_meta = rte_pmd_ark_mbuf_tx_userdata_get(mbuf); + if (tx_user_meta_hook) + tx_user_meta_hook(mbuf, user_meta, &user_len, + queue->ext_user_data); if (unlikely(mbuf->nb_segs != 1)) { stat = eth_ark_tx_jumbo(queue, mbuf, - &user_meta, user_len); + user_meta, user_len); if (unlikely(stat != 0)) break; /* Queue is full */ } else { eth_ark_tx_desc_fill(queue, mbuf, ARK_DDM_SOP | ARK_DDM_EOP, - &user_meta, user_len); + user_meta, user_len); } } @@ -271,6 +276,8 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev, queue->phys_qid = qidx; queue->queue_index = queue_idx; dev->data->tx_queues[queue_idx] = queue; + queue->tx_user_meta_hook = ark->user_ext.tx_user_meta_hook; + queue->ext_user_data = ark->user_data[dev->data->port_id]; queue->meta_q = rte_zmalloc_socket("Ark_txqueue meta", diff --git a/drivers/net/ark/ark_ext.h b/drivers/net/ark/ark_ext.h deleted file mode 100644 index 821fb55bb..000000000 --- a/drivers/net/ark/ark_ext.h +++ /dev/null @@ -1,90 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2015-2018 Atomic Rules LLC - */ - -#ifndef _ARK_EXT_H_ -#define _ARK_EXT_H_ - -#include - -/* - * This is the template file for users who which to define a dynamic - * extension to the Arkville PMD. User's who create an extension - * should include this file and define the necessary and desired - * functions. - * Only 1 function is required for an extension, dev_init(); all other - * functions prototyped in this file are optional. - */ - -/* - * Called post PMD init. - * The implementation returns its private data that gets passed into - * all other functions as user_data - * The ARK extension implementation MUST implement this function - */ -void *dev_init(struct rte_eth_dev *dev, void *a_bar, int port_id); - -/* Called during device shutdown */ -void dev_uninit(struct rte_eth_dev *dev, void *user_data); - -/* This call is optional and allows the - * extension to specify the number of supported ports. - */ -uint8_t dev_get_port_count(struct rte_eth_dev *dev, - void *user_data); - -/* - * The following functions are optional and are directly mapped - * from the DPDK PMD ops structure. - * Each function if implemented is called after the ARK PMD - * implementation executes. - */ - -int dev_configure(struct rte_eth_dev *dev, - void *user_data); - -int dev_start(struct rte_eth_dev *dev, - void *user_data); - -void dev_stop(struct rte_eth_dev *dev, - void *user_data); - -void dev_close(struct rte_eth_dev *dev, - void *user_data); - -int link_update(struct rte_eth_dev *dev, - int wait_to_complete, - void *user_data); - -int dev_set_link_up(struct rte_eth_dev *dev, - void *user_data); - -int dev_set_link_down(struct rte_eth_dev *dev, - void *user_data); - -int stats_get(struct rte_eth_dev *dev, - struct rte_eth_stats *stats, - void *user_data); - -void stats_reset(struct rte_eth_dev *dev, - void *user_data); - -void mac_addr_add(struct rte_eth_dev *dev, - struct rte_ether_addr *macadr, - uint32_t index, - uint32_t pool, - void *user_data); - -void mac_addr_remove(struct rte_eth_dev *dev, - uint32_t index, - void *user_data); - -void mac_addr_set(struct rte_eth_dev *dev, - struct rte_ether_addr *mac_addr, - void *user_data); - -int set_mtu(struct rte_eth_dev *dev, - uint16_t size, - void *user_data); - -#endif diff --git a/drivers/net/ark/ark_global.h b/drivers/net/ark/ark_global.h index 91726ecc2..214f8fb77 100644 --- a/drivers/net/ark/ark_global.h +++ b/drivers/net/ark/ark_global.h @@ -57,6 +57,23 @@ void *v; \ } name + +/* Extension hooks for extraction and placement of user meta data + * during RX an TX operations. These functions are the bridge + * between the mbuf struct and the tuser fields on the AXIS + * interfaces in the FPGA + */ +/* RX hook populates mbuf fields from user defined *user, upto 20 bytes */ +typedef void (*rx_user_meta_hook_fn)(struct rte_mbuf *mbuf, + const uint32_t *meta, + void *ext_user_data); +/* TX hook poplulate *user from mbuf, with up to 20 bytes. user_cnt + * returns the number of uint32_t words populated, 0 to 5 + */ +typedef void (*tx_user_meta_hook_fn)(const struct rte_mbuf *mbuf, + uint32_t *meta, uint8_t *meta_cnt, + void *ext_user_data); + struct ark_user_ext { void *(*dev_init)(struct rte_eth_dev *, void *abar, int port_id); void (*dev_uninit)(struct rte_eth_dev *, void *); @@ -79,6 +96,9 @@ struct ark_user_ext { void (*mac_addr_set)(struct rte_eth_dev *, struct rte_ether_addr *, void *); int (*set_mtu)(struct rte_eth_dev *, uint16_t, void *); + /* user meta, hook functions */ + rx_user_meta_hook_fn rx_user_meta_hook; + tx_user_meta_hook_fn tx_user_meta_hook; }; struct ark_adapter { diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h index ea92d4b6e..4e51a5e82 100644 --- a/drivers/net/ark/ark_udm.h +++ b/drivers/net/ark/ark_udm.h @@ -19,9 +19,8 @@ * -- 32 bytes */ struct ark_rx_meta { - uint64_t timestamp; - uint64_t user_data; - uint8_t reserved[14]; + uint32_t user_meta[5]; /* user defined based on fpga code */ + uint8_t reserved[10]; uint16_t pkt_len; } __rte_packed; diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h index 6f26d66b1..015ba8130 100644 --- a/drivers/net/ark/rte_pmd_ark.h +++ b/drivers/net/ark/rte_pmd_ark.h @@ -1,125 +1,287 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2020 Atomic Rules LLC + * Copyright (c) 2020-2021 Atomic Rules LLC */ #ifndef RTE_PMD_ARK_H #define RTE_PMD_ARK_H +#include +struct rte_eth_dev; +struct rte_mbuf; +struct rte_ether_addr; +struct rte_eth_stats; + /** * @file * ARK driver-specific API */ -#include -#include +/* The following section lists function prototypes for Arkville's + * dynamic PMD extension. User's who create an extension + * must include this file and define the necessary and desired + * functions. Only 1 function is required for an extension, + * rte_pmd_ark_dev_init(); all other functions prototyped in this + * section are optional. + * See documentation for compiling and use of extensions. + */ + +/** + * Extension prototype, required implementation if extensions are used. + * Called during device probe to initialize the user structure + * passed to other extension functions. This is called once for each + * port of the device. + * + * @param dev + * current device. + * @param a_bar + * access to pcie device bar (application bar) and hence access to + * user's portion of FPGA. + * @param port_id + * port identifier. + * @return user_data + * which will be passed to other extension functions. + */ +void *rte_pmd_ark_dev_init(struct rte_eth_dev *dev, void *a_bar, int port_id); + +/** + * Extension prototype, optional implementation. + * Called during device uninit. + * + * @param user_data + * user argument from dev_init() call. + */ +void rte_pmd_ark_dev_uninit(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during device probe to change the port count from 1. + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +uint8_t dev_get_port_count(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_configure(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_dev_configure(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_start(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_dev_start(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_stop(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_dev_stop(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_close(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_dev_close(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during link_update status event. + * + * @param dev + * current device. + * @param wait_to_complete + * argument from update event. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_link_update(struct rte_eth_dev *dev, + int wait_to_complete, + void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_set_link_up(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_dev_set_link_up(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_set_link_down(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_dev_set_link_down(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_stats_get(); allows updates to the stats + * struct in addition Ark's PMD operations. + * + * @param dev + * current device. + * @param stats + * stats struct already populated by Ark PMD. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_stats_get(struct rte_eth_dev *dev, + struct rte_eth_stats *stats, + void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_stats_reset(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_stats_reset(struct rte_eth_dev *dev, void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_mac_addr_add(). + * + * @param dev + * current device. + * @param macadr + * The MAC address to add + * @param pool + * VMDq pool index from caller + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_mac_addr_add(struct rte_eth_dev *dev, + struct rte_ether_addr *macadr, + uint32_t index, + uint32_t pool, + void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_mac_addr_remove(). + * + * @param dev + * current device. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_mac_addr_remove(struct rte_eth_dev *dev, + uint32_t index, + void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_default_mac_addr_set(). + * + * @param dev + * current device. + * @param mac_addr + * The new default MAC address. + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +void rte_pmd_ark_mac_addr_set(struct rte_eth_dev *dev, + struct rte_ether_addr *mac_addr, + void *user_data); + +/** + * Extension prototype, optional implementation. + * Called during rte_eth_dev_set_mtu(). + * + * @param dev + * current device. + * @param size + * The MTU to be applied + * @param user_data + * user argument from dev_init() call. + * @return (0) if successful. + */ +int rte_pmd_ark_set_mtu(struct rte_eth_dev *dev, + uint16_t size, + void *user_data); -#ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE -#define RTE_PMD_ARK_TX_USERDATA_ENABLE 0 -#endif +/** + * Extension prototype, optional implementation. + * Called during rte_eth_rx_burst() for each packet. This extension + * function allows the transfer of meta data from the user's FPGA to + * mbuf fields. + * + * @param mbuf + * The newly received mbuf + * @param meta + * The meta data from the user, upto 20 bytes. + * @param user_data + * user argument from dev_init() call. + */ +void rte_pmd_ark_rx_user_meta_hook(struct rte_mbuf *mbuf, + const uint32_t *meta, + void *user_data); -#ifndef RTE_PMD_ARK_RX_USERDATA_ENABLE -#define RTE_PMD_ARK_RX_USERDATA_ENABLE 0 -#endif - -typedef uint32_t rte_pmd_ark_tx_userdata_t; -typedef uint64_t rte_pmd_ark_rx_userdata_t; - -extern int rte_pmd_ark_tx_userdata_dynfield_offset; -extern int rte_pmd_ark_rx_userdata_dynfield_offset; - -/** mbuf dynamic field for custom Tx ARK data */ -#define RTE_PMD_ARK_TX_USERDATA_DYNFIELD_NAME "rte_net_ark_dynfield_tx_userdata" -/** mbuf dynamic field for custom Rx ARK data */ -#define RTE_PMD_ARK_RX_USERDATA_DYNFIELD_NAME "rte_net_ark_dynfield_rx_userdata" - -/** - * @warning - * @b EXPERIMENTAL: this API may change without prior notice - * - * Read Tx user data from mbuf. - * - * @param mbuf Structure to read from. - * @return user data - */ -__rte_experimental -static inline rte_pmd_ark_tx_userdata_t -rte_pmd_ark_mbuf_tx_userdata_get(const struct rte_mbuf *mbuf) -{ -#if RTE_PMD_ARK_TX_USERDATA_ENABLE - return *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_tx_userdata_dynfield_offset, - rte_pmd_ark_tx_userdata_t *); -#else - RTE_SET_USED(mbuf); - return 0; -#endif -} - -/** - * @warning - * @b EXPERIMENTAL: this API may change without prior notice - * - * Write Tx user data to mbuf. - * - * @param mbuf Structure to write into. - * @param data User data. - */ -__rte_experimental -static inline void -rte_pmd_ark_mbuf_tx_userdata_set(struct rte_mbuf *mbuf, - rte_pmd_ark_tx_userdata_t data) -{ -#if RTE_PMD_ARK_TX_USERDATA_ENABLE - *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_tx_userdata_dynfield_offset, - rte_pmd_ark_tx_userdata_t *) = data; -#else - RTE_SET_USED(mbuf); - RTE_SET_USED(data); -#endif -} - -/** - * @warning - * @b EXPERIMENTAL: this API may change without prior notice - * - * Read Rx user data from mbuf. - * - * @param mbuf Structure to read from. - * @return user data - */ -__rte_experimental -static inline rte_pmd_ark_rx_userdata_t -rte_pmd_ark_mbuf_rx_userdata_get(const struct rte_mbuf *mbuf) -{ -#if RTE_PMD_ARK_RX_USERDATA_ENABLE - return *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_rx_userdata_dynfield_offset, - rte_pmd_ark_rx_userdata_t *); -#else - RTE_SET_USED(mbuf); - return 0; -#endif -} - -/** - * @warning - * @b EXPERIMENTAL: this API may change without prior notice - * - * Write Rx user data to mbuf. - * - * @param mbuf Structure to write into. - * @param data User data. - */ -__rte_experimental -static inline void -rte_pmd_ark_mbuf_rx_userdata_set(struct rte_mbuf *mbuf, - rte_pmd_ark_rx_userdata_t data) -{ -#if RTE_PMD_ARK_RX_USERDATA_ENABLE - *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_rx_userdata_dynfield_offset, - rte_pmd_ark_rx_userdata_t *) = data; -#else - RTE_SET_USED(mbuf); - RTE_SET_USED(data); -#endif -} +/** + * Extension prototype, optional implementation. + * Called during rte_eth_tx_burst() for each packet. This extension + * function allows the transfer of data from the mbuf to the user's + * FPGA. Upto 20 bytes (5 32-bit words) are transferable + * + * @param mbuf + * The mbuf about to be transmitted. + * @param meta + * The meta data to be populate by this call. + * @param meta_cnt + * The count in 32-bit words of the meta data populated, 0 to 5. + * @param user_data + * user argument from dev_init() call. + */ +void rte_pmd_ark_tx_user_meta_hook(const struct rte_mbuf *mbuf, + uint32_t *meta, + uint8_t *meta_cnt, + void *user_data); #endif /* RTE_PMD_ARK_H */ diff --git a/drivers/net/ark/version.map b/drivers/net/ark/version.map index 954bea679..4a76d1d52 100644 --- a/drivers/net/ark/version.map +++ b/drivers/net/ark/version.map @@ -1,10 +1,3 @@ DPDK_21 { local: *; }; - -EXPERIMENTAL { - global: - - rte_pmd_ark_tx_userdata_dynfield_offset; - rte_pmd_ark_rx_userdata_dynfield_offset; -}; -- 2.17.1