1908072e9SAllain Legacy /* 2908072e9SAllain Legacy * BSD LICENSE 3908072e9SAllain Legacy * 4908072e9SAllain Legacy * Copyright (c) 2013-2017, Wind River Systems, Inc. 5908072e9SAllain Legacy * 6908072e9SAllain Legacy * Redistribution and use in source and binary forms, with or without 7908072e9SAllain Legacy * modification, are permitted provided that the following conditions are met: 8908072e9SAllain Legacy * 9908072e9SAllain Legacy * 1) Redistributions of source code must retain the above copyright notice, 10908072e9SAllain Legacy * this list of conditions and the following disclaimer. 11908072e9SAllain Legacy * 12908072e9SAllain Legacy * 2) Redistributions in binary form must reproduce the above copyright notice, 13908072e9SAllain Legacy * this list of conditions and the following disclaimer in the documentation 14908072e9SAllain Legacy * and/or other materials provided with the distribution. 15908072e9SAllain Legacy * 16908072e9SAllain Legacy * 3) Neither the name of Wind River Systems nor the names of its contributors 17908072e9SAllain Legacy * may be used to endorse or promote products derived from this software 18908072e9SAllain Legacy * without specific prior written permission. 19908072e9SAllain Legacy * 20908072e9SAllain Legacy * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21908072e9SAllain Legacy * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22908072e9SAllain Legacy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23908072e9SAllain Legacy * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24908072e9SAllain Legacy * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25908072e9SAllain Legacy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26908072e9SAllain Legacy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27908072e9SAllain Legacy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28908072e9SAllain Legacy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29908072e9SAllain Legacy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30908072e9SAllain Legacy * POSSIBILITY OF SUCH DAMAGE. 31908072e9SAllain Legacy */ 32908072e9SAllain Legacy 33908072e9SAllain Legacy #include <stdint.h> 34908072e9SAllain Legacy #include <string.h> 35908072e9SAllain Legacy #include <stdio.h> 36908072e9SAllain Legacy #include <errno.h> 37908072e9SAllain Legacy #include <unistd.h> 38908072e9SAllain Legacy 39908072e9SAllain Legacy #include <rte_ethdev.h> 40908072e9SAllain Legacy #include <rte_memcpy.h> 41908072e9SAllain Legacy #include <rte_string_fns.h> 42908072e9SAllain Legacy #include <rte_memzone.h> 43908072e9SAllain Legacy #include <rte_malloc.h> 44908072e9SAllain Legacy #include <rte_atomic.h> 45908072e9SAllain Legacy #include <rte_branch_prediction.h> 46908072e9SAllain Legacy #include <rte_pci.h> 47908072e9SAllain Legacy #include <rte_ether.h> 48908072e9SAllain Legacy #include <rte_common.h> 49908072e9SAllain Legacy #include <rte_cycles.h> 50908072e9SAllain Legacy #include <rte_byteorder.h> 51908072e9SAllain Legacy #include <rte_dev.h> 52908072e9SAllain Legacy #include <rte_memory.h> 53908072e9SAllain Legacy #include <rte_eal.h> 54c0ad5842SAllain Legacy #include <rte_io.h> 55908072e9SAllain Legacy 56908072e9SAllain Legacy #include "rte_avp_common.h" 57908072e9SAllain Legacy #include "rte_avp_fifo.h" 58908072e9SAllain Legacy 59908072e9SAllain Legacy #include "avp_logs.h" 60908072e9SAllain Legacy 61908072e9SAllain Legacy 62908072e9SAllain Legacy 631a859223SAllain Legacy static int avp_dev_configure(struct rte_eth_dev *dev); 641a859223SAllain Legacy static void avp_dev_info_get(struct rte_eth_dev *dev, 651a859223SAllain Legacy struct rte_eth_dev_info *dev_info); 661a859223SAllain Legacy static void avp_vlan_offload_set(struct rte_eth_dev *dev, int mask); 671a859223SAllain Legacy static int avp_dev_link_update(struct rte_eth_dev *dev, 681a859223SAllain Legacy __rte_unused int wait_to_complete); 69cce4367fSAllain Legacy static int avp_dev_rx_queue_setup(struct rte_eth_dev *dev, 70cce4367fSAllain Legacy uint16_t rx_queue_id, 71cce4367fSAllain Legacy uint16_t nb_rx_desc, 72cce4367fSAllain Legacy unsigned int socket_id, 73cce4367fSAllain Legacy const struct rte_eth_rxconf *rx_conf, 74cce4367fSAllain Legacy struct rte_mempool *pool); 751a859223SAllain Legacy 76cce4367fSAllain Legacy static int avp_dev_tx_queue_setup(struct rte_eth_dev *dev, 77cce4367fSAllain Legacy uint16_t tx_queue_id, 78cce4367fSAllain Legacy uint16_t nb_tx_desc, 79cce4367fSAllain Legacy unsigned int socket_id, 80cce4367fSAllain Legacy const struct rte_eth_txconf *tx_conf); 81cce4367fSAllain Legacy 8250db69fdSAllain Legacy static uint16_t avp_recv_scattered_pkts(void *rx_queue, 8350db69fdSAllain Legacy struct rte_mbuf **rx_pkts, 8450db69fdSAllain Legacy uint16_t nb_pkts); 8550db69fdSAllain Legacy 8650db69fdSAllain Legacy static uint16_t avp_recv_pkts(void *rx_queue, 8750db69fdSAllain Legacy struct rte_mbuf **rx_pkts, 8850db69fdSAllain Legacy uint16_t nb_pkts); 89295abce2SAllain Legacy 90295abce2SAllain Legacy static uint16_t avp_xmit_scattered_pkts(void *tx_queue, 91295abce2SAllain Legacy struct rte_mbuf **tx_pkts, 92295abce2SAllain Legacy uint16_t nb_pkts); 93295abce2SAllain Legacy 94295abce2SAllain Legacy static uint16_t avp_xmit_pkts(void *tx_queue, 95295abce2SAllain Legacy struct rte_mbuf **tx_pkts, 96295abce2SAllain Legacy uint16_t nb_pkts); 97295abce2SAllain Legacy 98cce4367fSAllain Legacy static void avp_dev_rx_queue_release(void *rxq); 99cce4367fSAllain Legacy static void avp_dev_tx_queue_release(void *txq); 100295abce2SAllain Legacy 101*5a5abe2dSAllain Legacy static void avp_dev_stats_get(struct rte_eth_dev *dev, 102*5a5abe2dSAllain Legacy struct rte_eth_stats *stats); 103*5a5abe2dSAllain Legacy static void avp_dev_stats_reset(struct rte_eth_dev *dev); 104*5a5abe2dSAllain Legacy 105295abce2SAllain Legacy 106908072e9SAllain Legacy #define AVP_DEV_TO_PCI(eth_dev) RTE_DEV_TO_PCI((eth_dev)->device) 107908072e9SAllain Legacy 108908072e9SAllain Legacy 10950db69fdSAllain Legacy #define AVP_MAX_RX_BURST 64 110295abce2SAllain Legacy #define AVP_MAX_TX_BURST 64 111908072e9SAllain Legacy #define AVP_MAX_MAC_ADDRS 1 112908072e9SAllain Legacy #define AVP_MIN_RX_BUFSIZE ETHER_MIN_LEN 113908072e9SAllain Legacy 114908072e9SAllain Legacy 115908072e9SAllain Legacy /* 116908072e9SAllain Legacy * Defines the number of microseconds to wait before checking the response 117908072e9SAllain Legacy * queue for completion. 118908072e9SAllain Legacy */ 119908072e9SAllain Legacy #define AVP_REQUEST_DELAY_USECS (5000) 120908072e9SAllain Legacy 121908072e9SAllain Legacy /* 122908072e9SAllain Legacy * Defines the number times to check the response queue for completion before 123908072e9SAllain Legacy * declaring a timeout. 124908072e9SAllain Legacy */ 125908072e9SAllain Legacy #define AVP_MAX_REQUEST_RETRY (100) 126908072e9SAllain Legacy 127908072e9SAllain Legacy /* Defines the current PCI driver version number */ 128908072e9SAllain Legacy #define AVP_DPDK_DRIVER_VERSION RTE_AVP_CURRENT_GUEST_VERSION 129908072e9SAllain Legacy 130908072e9SAllain Legacy /* 131908072e9SAllain Legacy * The set of PCI devices this driver supports 132908072e9SAllain Legacy */ 133908072e9SAllain Legacy static const struct rte_pci_id pci_id_avp_map[] = { 134908072e9SAllain Legacy { .vendor_id = RTE_AVP_PCI_VENDOR_ID, 135908072e9SAllain Legacy .device_id = RTE_AVP_PCI_DEVICE_ID, 136908072e9SAllain Legacy .subsystem_vendor_id = RTE_AVP_PCI_SUB_VENDOR_ID, 137908072e9SAllain Legacy .subsystem_device_id = RTE_AVP_PCI_SUB_DEVICE_ID, 138908072e9SAllain Legacy .class_id = RTE_CLASS_ANY_ID, 139908072e9SAllain Legacy }, 140908072e9SAllain Legacy 141908072e9SAllain Legacy { .vendor_id = 0, /* sentinel */ 142908072e9SAllain Legacy }, 143908072e9SAllain Legacy }; 144908072e9SAllain Legacy 1451a859223SAllain Legacy /* 1461a859223SAllain Legacy * dev_ops for avp, bare necessities for basic operation 1471a859223SAllain Legacy */ 1481a859223SAllain Legacy static const struct eth_dev_ops avp_eth_dev_ops = { 1491a859223SAllain Legacy .dev_configure = avp_dev_configure, 1501a859223SAllain Legacy .dev_infos_get = avp_dev_info_get, 1511a859223SAllain Legacy .vlan_offload_set = avp_vlan_offload_set, 152*5a5abe2dSAllain Legacy .stats_get = avp_dev_stats_get, 153*5a5abe2dSAllain Legacy .stats_reset = avp_dev_stats_reset, 1541a859223SAllain Legacy .link_update = avp_dev_link_update, 155cce4367fSAllain Legacy .rx_queue_setup = avp_dev_rx_queue_setup, 156cce4367fSAllain Legacy .rx_queue_release = avp_dev_rx_queue_release, 157cce4367fSAllain Legacy .tx_queue_setup = avp_dev_tx_queue_setup, 158cce4367fSAllain Legacy .tx_queue_release = avp_dev_tx_queue_release, 1591a859223SAllain Legacy }; 160908072e9SAllain Legacy 161c0ad5842SAllain Legacy /**@{ AVP device flags */ 162c0ad5842SAllain Legacy #define AVP_F_PROMISC (1 << 1) 163c0ad5842SAllain Legacy #define AVP_F_CONFIGURED (1 << 2) 164c0ad5842SAllain Legacy #define AVP_F_LINKUP (1 << 3) 165c0ad5842SAllain Legacy /**@} */ 166c0ad5842SAllain Legacy 167c0ad5842SAllain Legacy /* Ethernet device validation marker */ 168c0ad5842SAllain Legacy #define AVP_ETHDEV_MAGIC 0x92972862 169c0ad5842SAllain Legacy 170908072e9SAllain Legacy /* 171908072e9SAllain Legacy * Defines the AVP device attributes which are attached to an RTE ethernet 172908072e9SAllain Legacy * device 173908072e9SAllain Legacy */ 174908072e9SAllain Legacy struct avp_dev { 175908072e9SAllain Legacy uint32_t magic; /**< Memory validation marker */ 176908072e9SAllain Legacy uint64_t device_id; /**< Unique system identifier */ 177908072e9SAllain Legacy struct ether_addr ethaddr; /**< Host specified MAC address */ 178908072e9SAllain Legacy struct rte_eth_dev_data *dev_data; 179908072e9SAllain Legacy /**< Back pointer to ethernet device data */ 180908072e9SAllain Legacy volatile uint32_t flags; /**< Device operational flags */ 181908072e9SAllain Legacy uint8_t port_id; /**< Ethernet port identifier */ 182908072e9SAllain Legacy struct rte_mempool *pool; /**< pkt mbuf mempool */ 183908072e9SAllain Legacy unsigned int guest_mbuf_size; /**< local pool mbuf size */ 184908072e9SAllain Legacy unsigned int host_mbuf_size; /**< host mbuf size */ 185908072e9SAllain Legacy unsigned int max_rx_pkt_len; /**< maximum receive unit */ 186908072e9SAllain Legacy uint32_t host_features; /**< Supported feature bitmap */ 187908072e9SAllain Legacy uint32_t features; /**< Enabled feature bitmap */ 188908072e9SAllain Legacy unsigned int num_tx_queues; /**< Negotiated number of transmit queues */ 189908072e9SAllain Legacy unsigned int max_tx_queues; /**< Maximum number of transmit queues */ 190908072e9SAllain Legacy unsigned int num_rx_queues; /**< Negotiated number of receive queues */ 191908072e9SAllain Legacy unsigned int max_rx_queues; /**< Maximum number of receive queues */ 192908072e9SAllain Legacy 193908072e9SAllain Legacy struct rte_avp_fifo *tx_q[RTE_AVP_MAX_QUEUES]; /**< TX queue */ 194908072e9SAllain Legacy struct rte_avp_fifo *rx_q[RTE_AVP_MAX_QUEUES]; /**< RX queue */ 195908072e9SAllain Legacy struct rte_avp_fifo *alloc_q[RTE_AVP_MAX_QUEUES]; 196908072e9SAllain Legacy /**< Allocated mbufs queue */ 197908072e9SAllain Legacy struct rte_avp_fifo *free_q[RTE_AVP_MAX_QUEUES]; 198908072e9SAllain Legacy /**< To be freed mbufs queue */ 199908072e9SAllain Legacy 200908072e9SAllain Legacy /* For request & response */ 201908072e9SAllain Legacy struct rte_avp_fifo *req_q; /**< Request queue */ 202908072e9SAllain Legacy struct rte_avp_fifo *resp_q; /**< Response queue */ 203908072e9SAllain Legacy void *host_sync_addr; /**< (host) Req/Resp Mem address */ 204908072e9SAllain Legacy void *sync_addr; /**< Req/Resp Mem address */ 205908072e9SAllain Legacy void *host_mbuf_addr; /**< (host) MBUF pool start address */ 206908072e9SAllain Legacy void *mbuf_addr; /**< MBUF pool start address */ 207908072e9SAllain Legacy } __rte_cache_aligned; 208908072e9SAllain Legacy 209908072e9SAllain Legacy /* RTE ethernet private data */ 210908072e9SAllain Legacy struct avp_adapter { 211908072e9SAllain Legacy struct avp_dev avp; 212908072e9SAllain Legacy } __rte_cache_aligned; 213908072e9SAllain Legacy 214c0ad5842SAllain Legacy 215c0ad5842SAllain Legacy /* 32-bit MMIO register write */ 216c0ad5842SAllain Legacy #define AVP_WRITE32(_value, _addr) rte_write32_relaxed((_value), (_addr)) 217c0ad5842SAllain Legacy 218c0ad5842SAllain Legacy /* 32-bit MMIO register read */ 219c0ad5842SAllain Legacy #define AVP_READ32(_addr) rte_read32_relaxed((_addr)) 220c0ad5842SAllain Legacy 221908072e9SAllain Legacy /* Macro to cast the ethernet device private data to a AVP object */ 222908072e9SAllain Legacy #define AVP_DEV_PRIVATE_TO_HW(adapter) \ 223908072e9SAllain Legacy (&((struct avp_adapter *)adapter)->avp) 224908072e9SAllain Legacy 225908072e9SAllain Legacy /* 226c0ad5842SAllain Legacy * Defines the structure of a AVP device queue for the purpose of handling the 227c0ad5842SAllain Legacy * receive and transmit burst callback functions 228c0ad5842SAllain Legacy */ 229c0ad5842SAllain Legacy struct avp_queue { 230c0ad5842SAllain Legacy struct rte_eth_dev_data *dev_data; 231c0ad5842SAllain Legacy /**< Backpointer to ethernet device data */ 232c0ad5842SAllain Legacy struct avp_dev *avp; /**< Backpointer to AVP device */ 233c0ad5842SAllain Legacy uint16_t queue_id; 234c0ad5842SAllain Legacy /**< Queue identifier used for indexing current queue */ 235c0ad5842SAllain Legacy uint16_t queue_base; 236c0ad5842SAllain Legacy /**< Base queue identifier for queue servicing */ 237c0ad5842SAllain Legacy uint16_t queue_limit; 238c0ad5842SAllain Legacy /**< Maximum queue identifier for queue servicing */ 239c0ad5842SAllain Legacy 240c0ad5842SAllain Legacy uint64_t packets; 241c0ad5842SAllain Legacy uint64_t bytes; 242c0ad5842SAllain Legacy uint64_t errors; 243c0ad5842SAllain Legacy }; 244c0ad5842SAllain Legacy 2451a859223SAllain Legacy /* send a request and wait for a response 2461a859223SAllain Legacy * 2471a859223SAllain Legacy * @warning must be called while holding the avp->lock spinlock. 2481a859223SAllain Legacy */ 2491a859223SAllain Legacy static int 2501a859223SAllain Legacy avp_dev_process_request(struct avp_dev *avp, struct rte_avp_request *request) 2511a859223SAllain Legacy { 2521a859223SAllain Legacy unsigned int retry = AVP_MAX_REQUEST_RETRY; 2531a859223SAllain Legacy void *resp_addr = NULL; 2541a859223SAllain Legacy unsigned int count; 2551a859223SAllain Legacy int ret; 2561a859223SAllain Legacy 2571a859223SAllain Legacy PMD_DRV_LOG(DEBUG, "Sending request %u to host\n", request->req_id); 2581a859223SAllain Legacy 2591a859223SAllain Legacy request->result = -ENOTSUP; 2601a859223SAllain Legacy 2611a859223SAllain Legacy /* Discard any stale responses before starting a new request */ 2621a859223SAllain Legacy while (avp_fifo_get(avp->resp_q, (void **)&resp_addr, 1)) 2631a859223SAllain Legacy PMD_DRV_LOG(DEBUG, "Discarding stale response\n"); 2641a859223SAllain Legacy 2651a859223SAllain Legacy rte_memcpy(avp->sync_addr, request, sizeof(*request)); 2661a859223SAllain Legacy count = avp_fifo_put(avp->req_q, &avp->host_sync_addr, 1); 2671a859223SAllain Legacy if (count < 1) { 2681a859223SAllain Legacy PMD_DRV_LOG(ERR, "Cannot send request %u to host\n", 2691a859223SAllain Legacy request->req_id); 2701a859223SAllain Legacy ret = -EBUSY; 2711a859223SAllain Legacy goto done; 2721a859223SAllain Legacy } 2731a859223SAllain Legacy 2741a859223SAllain Legacy while (retry--) { 2751a859223SAllain Legacy /* wait for a response */ 2761a859223SAllain Legacy usleep(AVP_REQUEST_DELAY_USECS); 2771a859223SAllain Legacy 2781a859223SAllain Legacy count = avp_fifo_count(avp->resp_q); 2791a859223SAllain Legacy if (count >= 1) { 2801a859223SAllain Legacy /* response received */ 2811a859223SAllain Legacy break; 2821a859223SAllain Legacy } 2831a859223SAllain Legacy 2841a859223SAllain Legacy if ((count < 1) && (retry == 0)) { 2851a859223SAllain Legacy PMD_DRV_LOG(ERR, "Timeout while waiting for a response for %u\n", 2861a859223SAllain Legacy request->req_id); 2871a859223SAllain Legacy ret = -ETIME; 2881a859223SAllain Legacy goto done; 2891a859223SAllain Legacy } 2901a859223SAllain Legacy } 2911a859223SAllain Legacy 2921a859223SAllain Legacy /* retrieve the response */ 2931a859223SAllain Legacy count = avp_fifo_get(avp->resp_q, (void **)&resp_addr, 1); 2941a859223SAllain Legacy if ((count != 1) || (resp_addr != avp->host_sync_addr)) { 2951a859223SAllain Legacy PMD_DRV_LOG(ERR, "Invalid response from host, count=%u resp=%p host_sync_addr=%p\n", 2961a859223SAllain Legacy count, resp_addr, avp->host_sync_addr); 2971a859223SAllain Legacy ret = -ENODATA; 2981a859223SAllain Legacy goto done; 2991a859223SAllain Legacy } 3001a859223SAllain Legacy 3011a859223SAllain Legacy /* copy to user buffer */ 3021a859223SAllain Legacy rte_memcpy(request, avp->sync_addr, sizeof(*request)); 3031a859223SAllain Legacy ret = 0; 3041a859223SAllain Legacy 3051a859223SAllain Legacy PMD_DRV_LOG(DEBUG, "Result %d received for request %u\n", 3061a859223SAllain Legacy request->result, request->req_id); 3071a859223SAllain Legacy 3081a859223SAllain Legacy done: 3091a859223SAllain Legacy return ret; 3101a859223SAllain Legacy } 3111a859223SAllain Legacy 3121a859223SAllain Legacy static int 3131a859223SAllain Legacy avp_dev_ctrl_set_config(struct rte_eth_dev *eth_dev, 3141a859223SAllain Legacy struct rte_avp_device_config *config) 3151a859223SAllain Legacy { 3161a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 3171a859223SAllain Legacy struct rte_avp_request request; 3181a859223SAllain Legacy int ret; 3191a859223SAllain Legacy 3201a859223SAllain Legacy /* setup a configure request */ 3211a859223SAllain Legacy memset(&request, 0, sizeof(request)); 3221a859223SAllain Legacy request.req_id = RTE_AVP_REQ_CFG_DEVICE; 3231a859223SAllain Legacy memcpy(&request.config, config, sizeof(request.config)); 3241a859223SAllain Legacy 3251a859223SAllain Legacy ret = avp_dev_process_request(avp, &request); 3261a859223SAllain Legacy 3271a859223SAllain Legacy return ret == 0 ? request.result : ret; 3281a859223SAllain Legacy } 3291a859223SAllain Legacy 33050db69fdSAllain Legacy /* translate from host mbuf virtual address to guest virtual address */ 33150db69fdSAllain Legacy static inline void * 33250db69fdSAllain Legacy avp_dev_translate_buffer(struct avp_dev *avp, void *host_mbuf_address) 33350db69fdSAllain Legacy { 33450db69fdSAllain Legacy return RTE_PTR_ADD(RTE_PTR_SUB(host_mbuf_address, 33550db69fdSAllain Legacy (uintptr_t)avp->host_mbuf_addr), 33650db69fdSAllain Legacy (uintptr_t)avp->mbuf_addr); 33750db69fdSAllain Legacy } 33850db69fdSAllain Legacy 339c0ad5842SAllain Legacy /* translate from host physical address to guest virtual address */ 340c0ad5842SAllain Legacy static void * 341c0ad5842SAllain Legacy avp_dev_translate_address(struct rte_eth_dev *eth_dev, 342c0ad5842SAllain Legacy phys_addr_t host_phys_addr) 343c0ad5842SAllain Legacy { 344c0ad5842SAllain Legacy struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); 345c0ad5842SAllain Legacy struct rte_mem_resource *resource; 346c0ad5842SAllain Legacy struct rte_avp_memmap_info *info; 347c0ad5842SAllain Legacy struct rte_avp_memmap *map; 348c0ad5842SAllain Legacy off_t offset; 349c0ad5842SAllain Legacy void *addr; 350c0ad5842SAllain Legacy unsigned int i; 351c0ad5842SAllain Legacy 352c0ad5842SAllain Legacy addr = pci_dev->mem_resource[RTE_AVP_PCI_MEMORY_BAR].addr; 353c0ad5842SAllain Legacy resource = &pci_dev->mem_resource[RTE_AVP_PCI_MEMMAP_BAR]; 354c0ad5842SAllain Legacy info = (struct rte_avp_memmap_info *)resource->addr; 355c0ad5842SAllain Legacy 356c0ad5842SAllain Legacy offset = 0; 357c0ad5842SAllain Legacy for (i = 0; i < info->nb_maps; i++) { 358c0ad5842SAllain Legacy /* search all segments looking for a matching address */ 359c0ad5842SAllain Legacy map = &info->maps[i]; 360c0ad5842SAllain Legacy 361c0ad5842SAllain Legacy if ((host_phys_addr >= map->phys_addr) && 362c0ad5842SAllain Legacy (host_phys_addr < (map->phys_addr + map->length))) { 363c0ad5842SAllain Legacy /* address is within this segment */ 364c0ad5842SAllain Legacy offset += (host_phys_addr - map->phys_addr); 365c0ad5842SAllain Legacy addr = RTE_PTR_ADD(addr, offset); 366c0ad5842SAllain Legacy 367c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "Translating host physical 0x%" PRIx64 " to guest virtual 0x%p\n", 368c0ad5842SAllain Legacy host_phys_addr, addr); 369c0ad5842SAllain Legacy 370c0ad5842SAllain Legacy return addr; 371c0ad5842SAllain Legacy } 372c0ad5842SAllain Legacy offset += map->length; 373c0ad5842SAllain Legacy } 374c0ad5842SAllain Legacy 375c0ad5842SAllain Legacy return NULL; 376c0ad5842SAllain Legacy } 377c0ad5842SAllain Legacy 378c0ad5842SAllain Legacy /* verify that the incoming device version is compatible with our version */ 379c0ad5842SAllain Legacy static int 380c0ad5842SAllain Legacy avp_dev_version_check(uint32_t version) 381c0ad5842SAllain Legacy { 382c0ad5842SAllain Legacy uint32_t driver = RTE_AVP_STRIP_MINOR_VERSION(AVP_DPDK_DRIVER_VERSION); 383c0ad5842SAllain Legacy uint32_t device = RTE_AVP_STRIP_MINOR_VERSION(version); 384c0ad5842SAllain Legacy 385c0ad5842SAllain Legacy if (device <= driver) { 386c0ad5842SAllain Legacy /* the host driver version is less than or equal to ours */ 387c0ad5842SAllain Legacy return 0; 388c0ad5842SAllain Legacy } 389c0ad5842SAllain Legacy 390c0ad5842SAllain Legacy return 1; 391c0ad5842SAllain Legacy } 392c0ad5842SAllain Legacy 393c0ad5842SAllain Legacy /* verify that memory regions have expected version and validation markers */ 394c0ad5842SAllain Legacy static int 395c0ad5842SAllain Legacy avp_dev_check_regions(struct rte_eth_dev *eth_dev) 396c0ad5842SAllain Legacy { 397c0ad5842SAllain Legacy struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); 398c0ad5842SAllain Legacy struct rte_avp_memmap_info *memmap; 399c0ad5842SAllain Legacy struct rte_avp_device_info *info; 400c0ad5842SAllain Legacy struct rte_mem_resource *resource; 401c0ad5842SAllain Legacy unsigned int i; 402c0ad5842SAllain Legacy 403c0ad5842SAllain Legacy /* Dump resource info for debug */ 404c0ad5842SAllain Legacy for (i = 0; i < PCI_MAX_RESOURCE; i++) { 405c0ad5842SAllain Legacy resource = &pci_dev->mem_resource[i]; 406c0ad5842SAllain Legacy if ((resource->phys_addr == 0) || (resource->len == 0)) 407c0ad5842SAllain Legacy continue; 408c0ad5842SAllain Legacy 409c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "resource[%u]: phys=0x%" PRIx64 " len=%" PRIu64 " addr=%p\n", 410c0ad5842SAllain Legacy i, resource->phys_addr, 411c0ad5842SAllain Legacy resource->len, resource->addr); 412c0ad5842SAllain Legacy 413c0ad5842SAllain Legacy switch (i) { 414c0ad5842SAllain Legacy case RTE_AVP_PCI_MEMMAP_BAR: 415c0ad5842SAllain Legacy memmap = (struct rte_avp_memmap_info *)resource->addr; 416c0ad5842SAllain Legacy if ((memmap->magic != RTE_AVP_MEMMAP_MAGIC) || 417c0ad5842SAllain Legacy (memmap->version != RTE_AVP_MEMMAP_VERSION)) { 418c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Invalid memmap magic 0x%08x and version %u\n", 419c0ad5842SAllain Legacy memmap->magic, memmap->version); 420c0ad5842SAllain Legacy return -EINVAL; 421c0ad5842SAllain Legacy } 422c0ad5842SAllain Legacy break; 423c0ad5842SAllain Legacy 424c0ad5842SAllain Legacy case RTE_AVP_PCI_DEVICE_BAR: 425c0ad5842SAllain Legacy info = (struct rte_avp_device_info *)resource->addr; 426c0ad5842SAllain Legacy if ((info->magic != RTE_AVP_DEVICE_MAGIC) || 427c0ad5842SAllain Legacy avp_dev_version_check(info->version)) { 428c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Invalid device info magic 0x%08x or version 0x%08x > 0x%08x\n", 429c0ad5842SAllain Legacy info->magic, info->version, 430c0ad5842SAllain Legacy AVP_DPDK_DRIVER_VERSION); 431c0ad5842SAllain Legacy return -EINVAL; 432c0ad5842SAllain Legacy } 433c0ad5842SAllain Legacy break; 434c0ad5842SAllain Legacy 435c0ad5842SAllain Legacy case RTE_AVP_PCI_MEMORY_BAR: 436c0ad5842SAllain Legacy case RTE_AVP_PCI_MMIO_BAR: 437c0ad5842SAllain Legacy if (resource->addr == NULL) { 438c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Missing address space for BAR%u\n", 439c0ad5842SAllain Legacy i); 440c0ad5842SAllain Legacy return -EINVAL; 441c0ad5842SAllain Legacy } 442c0ad5842SAllain Legacy break; 443c0ad5842SAllain Legacy 444c0ad5842SAllain Legacy case RTE_AVP_PCI_MSIX_BAR: 445c0ad5842SAllain Legacy default: 446c0ad5842SAllain Legacy /* no validation required */ 447c0ad5842SAllain Legacy break; 448c0ad5842SAllain Legacy } 449c0ad5842SAllain Legacy } 450c0ad5842SAllain Legacy 451c0ad5842SAllain Legacy return 0; 452c0ad5842SAllain Legacy } 453c0ad5842SAllain Legacy 4541a859223SAllain Legacy static void 455cce4367fSAllain Legacy _avp_set_rx_queue_mappings(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id) 456cce4367fSAllain Legacy { 457cce4367fSAllain Legacy struct avp_dev *avp = 458cce4367fSAllain Legacy AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 459cce4367fSAllain Legacy struct avp_queue *rxq; 460cce4367fSAllain Legacy uint16_t queue_count; 461cce4367fSAllain Legacy uint16_t remainder; 462cce4367fSAllain Legacy 463cce4367fSAllain Legacy rxq = (struct avp_queue *)eth_dev->data->rx_queues[rx_queue_id]; 464cce4367fSAllain Legacy 465cce4367fSAllain Legacy /* 466cce4367fSAllain Legacy * Must map all AVP fifos as evenly as possible between the configured 467cce4367fSAllain Legacy * device queues. Each device queue will service a subset of the AVP 468cce4367fSAllain Legacy * fifos. If there is an odd number of device queues the first set of 469cce4367fSAllain Legacy * device queues will get the extra AVP fifos. 470cce4367fSAllain Legacy */ 471cce4367fSAllain Legacy queue_count = avp->num_rx_queues / eth_dev->data->nb_rx_queues; 472cce4367fSAllain Legacy remainder = avp->num_rx_queues % eth_dev->data->nb_rx_queues; 473cce4367fSAllain Legacy if (rx_queue_id < remainder) { 474cce4367fSAllain Legacy /* these queues must service one extra FIFO */ 475cce4367fSAllain Legacy rxq->queue_base = rx_queue_id * (queue_count + 1); 476cce4367fSAllain Legacy rxq->queue_limit = rxq->queue_base + (queue_count + 1) - 1; 477cce4367fSAllain Legacy } else { 478cce4367fSAllain Legacy /* these queues service the regular number of FIFO */ 479cce4367fSAllain Legacy rxq->queue_base = ((remainder * (queue_count + 1)) + 480cce4367fSAllain Legacy ((rx_queue_id - remainder) * queue_count)); 481cce4367fSAllain Legacy rxq->queue_limit = rxq->queue_base + queue_count - 1; 482cce4367fSAllain Legacy } 483cce4367fSAllain Legacy 484cce4367fSAllain Legacy PMD_DRV_LOG(DEBUG, "rxq %u at %p base %u limit %u\n", 485cce4367fSAllain Legacy rx_queue_id, rxq, rxq->queue_base, rxq->queue_limit); 486cce4367fSAllain Legacy 487cce4367fSAllain Legacy rxq->queue_id = rxq->queue_base; 488cce4367fSAllain Legacy } 489cce4367fSAllain Legacy 490cce4367fSAllain Legacy static void 4911a859223SAllain Legacy _avp_set_queue_counts(struct rte_eth_dev *eth_dev) 4921a859223SAllain Legacy { 4931a859223SAllain Legacy struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); 4941a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 4951a859223SAllain Legacy struct rte_avp_device_info *host_info; 4961a859223SAllain Legacy void *addr; 4971a859223SAllain Legacy 4981a859223SAllain Legacy addr = pci_dev->mem_resource[RTE_AVP_PCI_DEVICE_BAR].addr; 4991a859223SAllain Legacy host_info = (struct rte_avp_device_info *)addr; 5001a859223SAllain Legacy 5011a859223SAllain Legacy /* 5021a859223SAllain Legacy * the transmit direction is not negotiated beyond respecting the max 5031a859223SAllain Legacy * number of queues because the host can handle arbitrary guest tx 5041a859223SAllain Legacy * queues (host rx queues). 5051a859223SAllain Legacy */ 5061a859223SAllain Legacy avp->num_tx_queues = eth_dev->data->nb_tx_queues; 5071a859223SAllain Legacy 5081a859223SAllain Legacy /* 5091a859223SAllain Legacy * the receive direction is more restrictive. The host requires a 5101a859223SAllain Legacy * minimum number of guest rx queues (host tx queues) therefore 5111a859223SAllain Legacy * negotiate a value that is at least as large as the host minimum 5121a859223SAllain Legacy * requirement. If the host and guest values are not identical then a 5131a859223SAllain Legacy * mapping will be established in the receive_queue_setup function. 5141a859223SAllain Legacy */ 5151a859223SAllain Legacy avp->num_rx_queues = RTE_MAX(host_info->min_rx_queues, 5161a859223SAllain Legacy eth_dev->data->nb_rx_queues); 5171a859223SAllain Legacy 5181a859223SAllain Legacy PMD_DRV_LOG(DEBUG, "Requesting %u Tx and %u Rx queues from host\n", 5191a859223SAllain Legacy avp->num_tx_queues, avp->num_rx_queues); 5201a859223SAllain Legacy } 5211a859223SAllain Legacy 522c0ad5842SAllain Legacy /* 523c0ad5842SAllain Legacy * create a AVP device using the supplied device info by first translating it 524c0ad5842SAllain Legacy * to guest address space(s). 525c0ad5842SAllain Legacy */ 526c0ad5842SAllain Legacy static int 527c0ad5842SAllain Legacy avp_dev_create(struct rte_pci_device *pci_dev, 528c0ad5842SAllain Legacy struct rte_eth_dev *eth_dev) 529c0ad5842SAllain Legacy { 530c0ad5842SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 531c0ad5842SAllain Legacy struct rte_avp_device_info *host_info; 532c0ad5842SAllain Legacy struct rte_mem_resource *resource; 533c0ad5842SAllain Legacy unsigned int i; 534c0ad5842SAllain Legacy 535c0ad5842SAllain Legacy resource = &pci_dev->mem_resource[RTE_AVP_PCI_DEVICE_BAR]; 536c0ad5842SAllain Legacy if (resource->addr == NULL) { 537c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "BAR%u is not mapped\n", 538c0ad5842SAllain Legacy RTE_AVP_PCI_DEVICE_BAR); 539c0ad5842SAllain Legacy return -EFAULT; 540c0ad5842SAllain Legacy } 541c0ad5842SAllain Legacy host_info = (struct rte_avp_device_info *)resource->addr; 542c0ad5842SAllain Legacy 543c0ad5842SAllain Legacy if ((host_info->magic != RTE_AVP_DEVICE_MAGIC) || 544c0ad5842SAllain Legacy avp_dev_version_check(host_info->version)) { 545c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Invalid AVP PCI device, magic 0x%08x version 0x%08x > 0x%08x\n", 546c0ad5842SAllain Legacy host_info->magic, host_info->version, 547c0ad5842SAllain Legacy AVP_DPDK_DRIVER_VERSION); 548c0ad5842SAllain Legacy return -EINVAL; 549c0ad5842SAllain Legacy } 550c0ad5842SAllain Legacy 551c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host device is v%u.%u.%u\n", 552c0ad5842SAllain Legacy RTE_AVP_GET_RELEASE_VERSION(host_info->version), 553c0ad5842SAllain Legacy RTE_AVP_GET_MAJOR_VERSION(host_info->version), 554c0ad5842SAllain Legacy RTE_AVP_GET_MINOR_VERSION(host_info->version)); 555c0ad5842SAllain Legacy 556c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host supports %u to %u TX queue(s)\n", 557c0ad5842SAllain Legacy host_info->min_tx_queues, host_info->max_tx_queues); 558c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host supports %u to %u RX queue(s)\n", 559c0ad5842SAllain Legacy host_info->min_rx_queues, host_info->max_rx_queues); 560c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host supports features 0x%08x\n", 561c0ad5842SAllain Legacy host_info->features); 562c0ad5842SAllain Legacy 563c0ad5842SAllain Legacy if (avp->magic != AVP_ETHDEV_MAGIC) { 564c0ad5842SAllain Legacy /* 565c0ad5842SAllain Legacy * First time initialization (i.e., not during a VM 566c0ad5842SAllain Legacy * migration) 567c0ad5842SAllain Legacy */ 568c0ad5842SAllain Legacy memset(avp, 0, sizeof(*avp)); 569c0ad5842SAllain Legacy avp->magic = AVP_ETHDEV_MAGIC; 570c0ad5842SAllain Legacy avp->dev_data = eth_dev->data; 571c0ad5842SAllain Legacy avp->port_id = eth_dev->data->port_id; 572c0ad5842SAllain Legacy avp->host_mbuf_size = host_info->mbuf_size; 573c0ad5842SAllain Legacy avp->host_features = host_info->features; 574c0ad5842SAllain Legacy memcpy(&avp->ethaddr.addr_bytes[0], 575c0ad5842SAllain Legacy host_info->ethaddr, ETHER_ADDR_LEN); 576c0ad5842SAllain Legacy /* adjust max values to not exceed our max */ 577c0ad5842SAllain Legacy avp->max_tx_queues = 578c0ad5842SAllain Legacy RTE_MIN(host_info->max_tx_queues, RTE_AVP_MAX_QUEUES); 579c0ad5842SAllain Legacy avp->max_rx_queues = 580c0ad5842SAllain Legacy RTE_MIN(host_info->max_rx_queues, RTE_AVP_MAX_QUEUES); 581c0ad5842SAllain Legacy } else { 582c0ad5842SAllain Legacy /* Re-attaching during migration */ 583c0ad5842SAllain Legacy 584c0ad5842SAllain Legacy /* TODO... requires validation of host values */ 585c0ad5842SAllain Legacy if ((host_info->features & avp->features) != avp->features) { 586c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "AVP host features mismatched; 0x%08x, host=0x%08x\n", 587c0ad5842SAllain Legacy avp->features, host_info->features); 588c0ad5842SAllain Legacy /* this should not be possible; continue for now */ 589c0ad5842SAllain Legacy } 590c0ad5842SAllain Legacy } 591c0ad5842SAllain Legacy 592c0ad5842SAllain Legacy /* the device id is allowed to change over migrations */ 593c0ad5842SAllain Legacy avp->device_id = host_info->device_id; 594c0ad5842SAllain Legacy 595c0ad5842SAllain Legacy /* translate incoming host addresses to guest address space */ 596c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP first host tx queue at 0x%" PRIx64 "\n", 597c0ad5842SAllain Legacy host_info->tx_phys); 598c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP first host alloc queue at 0x%" PRIx64 "\n", 599c0ad5842SAllain Legacy host_info->alloc_phys); 600c0ad5842SAllain Legacy for (i = 0; i < avp->max_tx_queues; i++) { 601c0ad5842SAllain Legacy avp->tx_q[i] = avp_dev_translate_address(eth_dev, 602c0ad5842SAllain Legacy host_info->tx_phys + (i * host_info->tx_size)); 603c0ad5842SAllain Legacy 604c0ad5842SAllain Legacy avp->alloc_q[i] = avp_dev_translate_address(eth_dev, 605c0ad5842SAllain Legacy host_info->alloc_phys + (i * host_info->alloc_size)); 606c0ad5842SAllain Legacy } 607c0ad5842SAllain Legacy 608c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP first host rx queue at 0x%" PRIx64 "\n", 609c0ad5842SAllain Legacy host_info->rx_phys); 610c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP first host free queue at 0x%" PRIx64 "\n", 611c0ad5842SAllain Legacy host_info->free_phys); 612c0ad5842SAllain Legacy for (i = 0; i < avp->max_rx_queues; i++) { 613c0ad5842SAllain Legacy avp->rx_q[i] = avp_dev_translate_address(eth_dev, 614c0ad5842SAllain Legacy host_info->rx_phys + (i * host_info->rx_size)); 615c0ad5842SAllain Legacy avp->free_q[i] = avp_dev_translate_address(eth_dev, 616c0ad5842SAllain Legacy host_info->free_phys + (i * host_info->free_size)); 617c0ad5842SAllain Legacy } 618c0ad5842SAllain Legacy 619c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host request queue at 0x%" PRIx64 "\n", 620c0ad5842SAllain Legacy host_info->req_phys); 621c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host response queue at 0x%" PRIx64 "\n", 622c0ad5842SAllain Legacy host_info->resp_phys); 623c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host sync address at 0x%" PRIx64 "\n", 624c0ad5842SAllain Legacy host_info->sync_phys); 625c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host mbuf address at 0x%" PRIx64 "\n", 626c0ad5842SAllain Legacy host_info->mbuf_phys); 627c0ad5842SAllain Legacy avp->req_q = avp_dev_translate_address(eth_dev, host_info->req_phys); 628c0ad5842SAllain Legacy avp->resp_q = avp_dev_translate_address(eth_dev, host_info->resp_phys); 629c0ad5842SAllain Legacy avp->sync_addr = 630c0ad5842SAllain Legacy avp_dev_translate_address(eth_dev, host_info->sync_phys); 631c0ad5842SAllain Legacy avp->mbuf_addr = 632c0ad5842SAllain Legacy avp_dev_translate_address(eth_dev, host_info->mbuf_phys); 633c0ad5842SAllain Legacy 634c0ad5842SAllain Legacy /* 635c0ad5842SAllain Legacy * store the host mbuf virtual address so that we can calculate 636c0ad5842SAllain Legacy * relative offsets for each mbuf as they are processed 637c0ad5842SAllain Legacy */ 638c0ad5842SAllain Legacy avp->host_mbuf_addr = host_info->mbuf_va; 639c0ad5842SAllain Legacy avp->host_sync_addr = host_info->sync_va; 640c0ad5842SAllain Legacy 641c0ad5842SAllain Legacy /* 642c0ad5842SAllain Legacy * store the maximum packet length that is supported by the host. 643c0ad5842SAllain Legacy */ 644c0ad5842SAllain Legacy avp->max_rx_pkt_len = host_info->max_rx_pkt_len; 645c0ad5842SAllain Legacy PMD_DRV_LOG(DEBUG, "AVP host max receive packet length is %u\n", 646c0ad5842SAllain Legacy host_info->max_rx_pkt_len); 647c0ad5842SAllain Legacy 648c0ad5842SAllain Legacy return 0; 649c0ad5842SAllain Legacy } 650c0ad5842SAllain Legacy 651c0ad5842SAllain Legacy /* 652908072e9SAllain Legacy * This function is based on probe() function in avp_pci.c 653908072e9SAllain Legacy * It returns 0 on success. 654908072e9SAllain Legacy */ 655908072e9SAllain Legacy static int 656908072e9SAllain Legacy eth_avp_dev_init(struct rte_eth_dev *eth_dev) 657908072e9SAllain Legacy { 658c0ad5842SAllain Legacy struct avp_dev *avp = 659c0ad5842SAllain Legacy AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 660908072e9SAllain Legacy struct rte_pci_device *pci_dev; 661c0ad5842SAllain Legacy int ret; 662908072e9SAllain Legacy 663908072e9SAllain Legacy pci_dev = AVP_DEV_TO_PCI(eth_dev); 6641a859223SAllain Legacy eth_dev->dev_ops = &avp_eth_dev_ops; 66550db69fdSAllain Legacy eth_dev->rx_pkt_burst = &avp_recv_pkts; 666295abce2SAllain Legacy eth_dev->tx_pkt_burst = &avp_xmit_pkts; 667908072e9SAllain Legacy 668908072e9SAllain Legacy if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 669908072e9SAllain Legacy /* 670908072e9SAllain Legacy * no setup required on secondary processes. All data is saved 671908072e9SAllain Legacy * in dev_private by the primary process. All resource should 672908072e9SAllain Legacy * be mapped to the same virtual address so all pointers should 673908072e9SAllain Legacy * be valid. 674908072e9SAllain Legacy */ 67550db69fdSAllain Legacy if (eth_dev->data->scattered_rx) { 67650db69fdSAllain Legacy PMD_DRV_LOG(NOTICE, "AVP device configured for chained mbufs\n"); 67750db69fdSAllain Legacy eth_dev->rx_pkt_burst = avp_recv_scattered_pkts; 678295abce2SAllain Legacy eth_dev->tx_pkt_burst = avp_xmit_scattered_pkts; 67950db69fdSAllain Legacy } 680908072e9SAllain Legacy return 0; 681908072e9SAllain Legacy } 682908072e9SAllain Legacy 683908072e9SAllain Legacy rte_eth_copy_pci_info(eth_dev, pci_dev); 684908072e9SAllain Legacy 685908072e9SAllain Legacy eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE; 686908072e9SAllain Legacy 687c0ad5842SAllain Legacy /* Check BAR resources */ 688c0ad5842SAllain Legacy ret = avp_dev_check_regions(eth_dev); 689c0ad5842SAllain Legacy if (ret < 0) { 690c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Failed to validate BAR resources, ret=%d\n", 691c0ad5842SAllain Legacy ret); 692c0ad5842SAllain Legacy return ret; 693c0ad5842SAllain Legacy } 694c0ad5842SAllain Legacy 695c0ad5842SAllain Legacy /* Handle each subtype */ 696c0ad5842SAllain Legacy ret = avp_dev_create(pci_dev, eth_dev); 697c0ad5842SAllain Legacy if (ret < 0) { 698c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Failed to create device, ret=%d\n", ret); 699c0ad5842SAllain Legacy return ret; 700c0ad5842SAllain Legacy } 701c0ad5842SAllain Legacy 702c0ad5842SAllain Legacy /* Allocate memory for storing MAC addresses */ 703c0ad5842SAllain Legacy eth_dev->data->mac_addrs = rte_zmalloc("avp_ethdev", ETHER_ADDR_LEN, 0); 704c0ad5842SAllain Legacy if (eth_dev->data->mac_addrs == NULL) { 705c0ad5842SAllain Legacy PMD_DRV_LOG(ERR, "Failed to allocate %d bytes needed to store MAC addresses\n", 706c0ad5842SAllain Legacy ETHER_ADDR_LEN); 707c0ad5842SAllain Legacy return -ENOMEM; 708c0ad5842SAllain Legacy } 709c0ad5842SAllain Legacy 710c0ad5842SAllain Legacy /* Get a mac from device config */ 711c0ad5842SAllain Legacy ether_addr_copy(&avp->ethaddr, ð_dev->data->mac_addrs[0]); 712c0ad5842SAllain Legacy 713908072e9SAllain Legacy return 0; 714908072e9SAllain Legacy } 715908072e9SAllain Legacy 716908072e9SAllain Legacy static int 717908072e9SAllain Legacy eth_avp_dev_uninit(struct rte_eth_dev *eth_dev) 718908072e9SAllain Legacy { 719908072e9SAllain Legacy if (rte_eal_process_type() != RTE_PROC_PRIMARY) 720908072e9SAllain Legacy return -EPERM; 721908072e9SAllain Legacy 722908072e9SAllain Legacy if (eth_dev->data == NULL) 723908072e9SAllain Legacy return 0; 724908072e9SAllain Legacy 725c0ad5842SAllain Legacy if (eth_dev->data->mac_addrs != NULL) { 726c0ad5842SAllain Legacy rte_free(eth_dev->data->mac_addrs); 727c0ad5842SAllain Legacy eth_dev->data->mac_addrs = NULL; 728c0ad5842SAllain Legacy } 729c0ad5842SAllain Legacy 730908072e9SAllain Legacy return 0; 731908072e9SAllain Legacy } 732908072e9SAllain Legacy 733908072e9SAllain Legacy 734908072e9SAllain Legacy static struct eth_driver rte_avp_pmd = { 735908072e9SAllain Legacy { 736908072e9SAllain Legacy .id_table = pci_id_avp_map, 737908072e9SAllain Legacy .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 738908072e9SAllain Legacy .probe = rte_eth_dev_pci_probe, 739908072e9SAllain Legacy .remove = rte_eth_dev_pci_remove, 740908072e9SAllain Legacy }, 741908072e9SAllain Legacy .eth_dev_init = eth_avp_dev_init, 742908072e9SAllain Legacy .eth_dev_uninit = eth_avp_dev_uninit, 743908072e9SAllain Legacy .dev_private_size = sizeof(struct avp_adapter), 744908072e9SAllain Legacy }; 745908072e9SAllain Legacy 7461a859223SAllain Legacy static int 74750db69fdSAllain Legacy avp_dev_enable_scattered(struct rte_eth_dev *eth_dev, 74850db69fdSAllain Legacy struct avp_dev *avp) 74950db69fdSAllain Legacy { 75050db69fdSAllain Legacy unsigned int max_rx_pkt_len; 75150db69fdSAllain Legacy 75250db69fdSAllain Legacy max_rx_pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len; 75350db69fdSAllain Legacy 75450db69fdSAllain Legacy if ((max_rx_pkt_len > avp->guest_mbuf_size) || 75550db69fdSAllain Legacy (max_rx_pkt_len > avp->host_mbuf_size)) { 75650db69fdSAllain Legacy /* 75750db69fdSAllain Legacy * If the guest MTU is greater than either the host or guest 75850db69fdSAllain Legacy * buffers then chained mbufs have to be enabled in the TX 75950db69fdSAllain Legacy * direction. It is assumed that the application will not need 76050db69fdSAllain Legacy * to send packets larger than their max_rx_pkt_len (MRU). 76150db69fdSAllain Legacy */ 76250db69fdSAllain Legacy return 1; 76350db69fdSAllain Legacy } 76450db69fdSAllain Legacy 76550db69fdSAllain Legacy if ((avp->max_rx_pkt_len > avp->guest_mbuf_size) || 76650db69fdSAllain Legacy (avp->max_rx_pkt_len > avp->host_mbuf_size)) { 76750db69fdSAllain Legacy /* 76850db69fdSAllain Legacy * If the host MRU is greater than its own mbuf size or the 76950db69fdSAllain Legacy * guest mbuf size then chained mbufs have to be enabled in the 77050db69fdSAllain Legacy * RX direction. 77150db69fdSAllain Legacy */ 77250db69fdSAllain Legacy return 1; 77350db69fdSAllain Legacy } 77450db69fdSAllain Legacy 77550db69fdSAllain Legacy return 0; 77650db69fdSAllain Legacy } 77750db69fdSAllain Legacy 77850db69fdSAllain Legacy static int 779cce4367fSAllain Legacy avp_dev_rx_queue_setup(struct rte_eth_dev *eth_dev, 780cce4367fSAllain Legacy uint16_t rx_queue_id, 781cce4367fSAllain Legacy uint16_t nb_rx_desc, 782cce4367fSAllain Legacy unsigned int socket_id, 783cce4367fSAllain Legacy const struct rte_eth_rxconf *rx_conf, 784cce4367fSAllain Legacy struct rte_mempool *pool) 785cce4367fSAllain Legacy { 786cce4367fSAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 787cce4367fSAllain Legacy struct rte_pktmbuf_pool_private *mbp_priv; 788cce4367fSAllain Legacy struct avp_queue *rxq; 789cce4367fSAllain Legacy 790cce4367fSAllain Legacy if (rx_queue_id >= eth_dev->data->nb_rx_queues) { 791cce4367fSAllain Legacy PMD_DRV_LOG(ERR, "RX queue id is out of range: rx_queue_id=%u, nb_rx_queues=%u\n", 792cce4367fSAllain Legacy rx_queue_id, eth_dev->data->nb_rx_queues); 793cce4367fSAllain Legacy return -EINVAL; 794cce4367fSAllain Legacy } 795cce4367fSAllain Legacy 796cce4367fSAllain Legacy /* Save mbuf pool pointer */ 797cce4367fSAllain Legacy avp->pool = pool; 798cce4367fSAllain Legacy 799cce4367fSAllain Legacy /* Save the local mbuf size */ 800cce4367fSAllain Legacy mbp_priv = rte_mempool_get_priv(pool); 801cce4367fSAllain Legacy avp->guest_mbuf_size = (uint16_t)(mbp_priv->mbuf_data_room_size); 802cce4367fSAllain Legacy avp->guest_mbuf_size -= RTE_PKTMBUF_HEADROOM; 803cce4367fSAllain Legacy 80450db69fdSAllain Legacy if (avp_dev_enable_scattered(eth_dev, avp)) { 80550db69fdSAllain Legacy if (!eth_dev->data->scattered_rx) { 80650db69fdSAllain Legacy PMD_DRV_LOG(NOTICE, "AVP device configured for chained mbufs\n"); 80750db69fdSAllain Legacy eth_dev->data->scattered_rx = 1; 80850db69fdSAllain Legacy eth_dev->rx_pkt_burst = avp_recv_scattered_pkts; 809295abce2SAllain Legacy eth_dev->tx_pkt_burst = avp_xmit_scattered_pkts; 81050db69fdSAllain Legacy } 81150db69fdSAllain Legacy } 81250db69fdSAllain Legacy 813cce4367fSAllain Legacy PMD_DRV_LOG(DEBUG, "AVP max_rx_pkt_len=(%u,%u) mbuf_size=(%u,%u)\n", 814cce4367fSAllain Legacy avp->max_rx_pkt_len, 815cce4367fSAllain Legacy eth_dev->data->dev_conf.rxmode.max_rx_pkt_len, 816cce4367fSAllain Legacy avp->host_mbuf_size, 817cce4367fSAllain Legacy avp->guest_mbuf_size); 818cce4367fSAllain Legacy 819cce4367fSAllain Legacy /* allocate a queue object */ 820cce4367fSAllain Legacy rxq = rte_zmalloc_socket("ethdev RX queue", sizeof(struct avp_queue), 821cce4367fSAllain Legacy RTE_CACHE_LINE_SIZE, socket_id); 822cce4367fSAllain Legacy if (rxq == NULL) { 823cce4367fSAllain Legacy PMD_DRV_LOG(ERR, "Failed to allocate new Rx queue object\n"); 824cce4367fSAllain Legacy return -ENOMEM; 825cce4367fSAllain Legacy } 826cce4367fSAllain Legacy 827cce4367fSAllain Legacy /* save back pointers to AVP and Ethernet devices */ 828cce4367fSAllain Legacy rxq->avp = avp; 829cce4367fSAllain Legacy rxq->dev_data = eth_dev->data; 830cce4367fSAllain Legacy eth_dev->data->rx_queues[rx_queue_id] = (void *)rxq; 831cce4367fSAllain Legacy 832cce4367fSAllain Legacy /* setup the queue receive mapping for the current queue. */ 833cce4367fSAllain Legacy _avp_set_rx_queue_mappings(eth_dev, rx_queue_id); 834cce4367fSAllain Legacy 835cce4367fSAllain Legacy PMD_DRV_LOG(DEBUG, "Rx queue %u setup at %p\n", rx_queue_id, rxq); 836cce4367fSAllain Legacy 837cce4367fSAllain Legacy (void)nb_rx_desc; 838cce4367fSAllain Legacy (void)rx_conf; 839cce4367fSAllain Legacy return 0; 840cce4367fSAllain Legacy } 841cce4367fSAllain Legacy 842cce4367fSAllain Legacy static int 843cce4367fSAllain Legacy avp_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, 844cce4367fSAllain Legacy uint16_t tx_queue_id, 845cce4367fSAllain Legacy uint16_t nb_tx_desc, 846cce4367fSAllain Legacy unsigned int socket_id, 847cce4367fSAllain Legacy const struct rte_eth_txconf *tx_conf) 848cce4367fSAllain Legacy { 849cce4367fSAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 850cce4367fSAllain Legacy struct avp_queue *txq; 851cce4367fSAllain Legacy 852cce4367fSAllain Legacy if (tx_queue_id >= eth_dev->data->nb_tx_queues) { 853cce4367fSAllain Legacy PMD_DRV_LOG(ERR, "TX queue id is out of range: tx_queue_id=%u, nb_tx_queues=%u\n", 854cce4367fSAllain Legacy tx_queue_id, eth_dev->data->nb_tx_queues); 855cce4367fSAllain Legacy return -EINVAL; 856cce4367fSAllain Legacy } 857cce4367fSAllain Legacy 858cce4367fSAllain Legacy /* allocate a queue object */ 859cce4367fSAllain Legacy txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct avp_queue), 860cce4367fSAllain Legacy RTE_CACHE_LINE_SIZE, socket_id); 861cce4367fSAllain Legacy if (txq == NULL) { 862cce4367fSAllain Legacy PMD_DRV_LOG(ERR, "Failed to allocate new Tx queue object\n"); 863cce4367fSAllain Legacy return -ENOMEM; 864cce4367fSAllain Legacy } 865cce4367fSAllain Legacy 866cce4367fSAllain Legacy /* only the configured set of transmit queues are used */ 867cce4367fSAllain Legacy txq->queue_id = tx_queue_id; 868cce4367fSAllain Legacy txq->queue_base = tx_queue_id; 869cce4367fSAllain Legacy txq->queue_limit = tx_queue_id; 870cce4367fSAllain Legacy 871cce4367fSAllain Legacy /* save back pointers to AVP and Ethernet devices */ 872cce4367fSAllain Legacy txq->avp = avp; 873cce4367fSAllain Legacy txq->dev_data = eth_dev->data; 874cce4367fSAllain Legacy eth_dev->data->tx_queues[tx_queue_id] = (void *)txq; 875cce4367fSAllain Legacy 876cce4367fSAllain Legacy PMD_DRV_LOG(DEBUG, "Tx queue %u setup at %p\n", tx_queue_id, txq); 877cce4367fSAllain Legacy 878cce4367fSAllain Legacy (void)nb_tx_desc; 879cce4367fSAllain Legacy (void)tx_conf; 880cce4367fSAllain Legacy return 0; 881cce4367fSAllain Legacy } 882cce4367fSAllain Legacy 88350db69fdSAllain Legacy static inline int 88450db69fdSAllain Legacy _avp_cmp_ether_addr(struct ether_addr *a, struct ether_addr *b) 88550db69fdSAllain Legacy { 88650db69fdSAllain Legacy uint16_t *_a = (uint16_t *)&a->addr_bytes[0]; 88750db69fdSAllain Legacy uint16_t *_b = (uint16_t *)&b->addr_bytes[0]; 88850db69fdSAllain Legacy return (_a[0] ^ _b[0]) | (_a[1] ^ _b[1]) | (_a[2] ^ _b[2]); 88950db69fdSAllain Legacy } 89050db69fdSAllain Legacy 89150db69fdSAllain Legacy static inline int 89250db69fdSAllain Legacy _avp_mac_filter(struct avp_dev *avp, struct rte_mbuf *m) 89350db69fdSAllain Legacy { 89450db69fdSAllain Legacy struct ether_hdr *eth = rte_pktmbuf_mtod(m, struct ether_hdr *); 89550db69fdSAllain Legacy 89650db69fdSAllain Legacy if (likely(_avp_cmp_ether_addr(&avp->ethaddr, ð->d_addr) == 0)) { 89750db69fdSAllain Legacy /* allow all packets destined to our address */ 89850db69fdSAllain Legacy return 0; 89950db69fdSAllain Legacy } 90050db69fdSAllain Legacy 90150db69fdSAllain Legacy if (likely(is_broadcast_ether_addr(ð->d_addr))) { 90250db69fdSAllain Legacy /* allow all broadcast packets */ 90350db69fdSAllain Legacy return 0; 90450db69fdSAllain Legacy } 90550db69fdSAllain Legacy 90650db69fdSAllain Legacy if (likely(is_multicast_ether_addr(ð->d_addr))) { 90750db69fdSAllain Legacy /* allow all multicast packets */ 90850db69fdSAllain Legacy return 0; 90950db69fdSAllain Legacy } 91050db69fdSAllain Legacy 91150db69fdSAllain Legacy if (avp->flags & AVP_F_PROMISC) { 91250db69fdSAllain Legacy /* allow all packets when in promiscuous mode */ 91350db69fdSAllain Legacy return 0; 91450db69fdSAllain Legacy } 91550db69fdSAllain Legacy 91650db69fdSAllain Legacy return -1; 91750db69fdSAllain Legacy } 91850db69fdSAllain Legacy 91950db69fdSAllain Legacy #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS 92050db69fdSAllain Legacy static inline void 92150db69fdSAllain Legacy __avp_dev_buffer_sanity_check(struct avp_dev *avp, struct rte_avp_desc *buf) 92250db69fdSAllain Legacy { 92350db69fdSAllain Legacy struct rte_avp_desc *first_buf; 92450db69fdSAllain Legacy struct rte_avp_desc *pkt_buf; 92550db69fdSAllain Legacy unsigned int pkt_len; 92650db69fdSAllain Legacy unsigned int nb_segs; 92750db69fdSAllain Legacy void *pkt_data; 92850db69fdSAllain Legacy unsigned int i; 92950db69fdSAllain Legacy 93050db69fdSAllain Legacy first_buf = avp_dev_translate_buffer(avp, buf); 93150db69fdSAllain Legacy 93250db69fdSAllain Legacy i = 0; 93350db69fdSAllain Legacy pkt_len = 0; 93450db69fdSAllain Legacy nb_segs = first_buf->nb_segs; 93550db69fdSAllain Legacy do { 93650db69fdSAllain Legacy /* Adjust pointers for guest addressing */ 93750db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, buf); 93850db69fdSAllain Legacy if (pkt_buf == NULL) 93950db69fdSAllain Legacy rte_panic("bad buffer: segment %u has an invalid address %p\n", 94050db69fdSAllain Legacy i, buf); 94150db69fdSAllain Legacy pkt_data = avp_dev_translate_buffer(avp, pkt_buf->data); 94250db69fdSAllain Legacy if (pkt_data == NULL) 94350db69fdSAllain Legacy rte_panic("bad buffer: segment %u has a NULL data pointer\n", 94450db69fdSAllain Legacy i); 94550db69fdSAllain Legacy if (pkt_buf->data_len == 0) 94650db69fdSAllain Legacy rte_panic("bad buffer: segment %u has 0 data length\n", 94750db69fdSAllain Legacy i); 94850db69fdSAllain Legacy pkt_len += pkt_buf->data_len; 94950db69fdSAllain Legacy nb_segs--; 95050db69fdSAllain Legacy i++; 95150db69fdSAllain Legacy 95250db69fdSAllain Legacy } while (nb_segs && (buf = pkt_buf->next) != NULL); 95350db69fdSAllain Legacy 95450db69fdSAllain Legacy if (nb_segs != 0) 95550db69fdSAllain Legacy rte_panic("bad buffer: expected %u segments found %u\n", 95650db69fdSAllain Legacy first_buf->nb_segs, (first_buf->nb_segs - nb_segs)); 95750db69fdSAllain Legacy if (pkt_len != first_buf->pkt_len) 95850db69fdSAllain Legacy rte_panic("bad buffer: expected length %u found %u\n", 95950db69fdSAllain Legacy first_buf->pkt_len, pkt_len); 96050db69fdSAllain Legacy } 96150db69fdSAllain Legacy 96250db69fdSAllain Legacy #define avp_dev_buffer_sanity_check(a, b) \ 96350db69fdSAllain Legacy __avp_dev_buffer_sanity_check((a), (b)) 96450db69fdSAllain Legacy 96550db69fdSAllain Legacy #else /* RTE_LIBRTE_AVP_DEBUG_BUFFERS */ 96650db69fdSAllain Legacy 96750db69fdSAllain Legacy #define avp_dev_buffer_sanity_check(a, b) do {} while (0) 96850db69fdSAllain Legacy 96950db69fdSAllain Legacy #endif 97050db69fdSAllain Legacy 97150db69fdSAllain Legacy /* 97250db69fdSAllain Legacy * Copy a host buffer chain to a set of mbufs. This function assumes that 97350db69fdSAllain Legacy * there exactly the required number of mbufs to copy all source bytes. 97450db69fdSAllain Legacy */ 97550db69fdSAllain Legacy static inline struct rte_mbuf * 97650db69fdSAllain Legacy avp_dev_copy_from_buffers(struct avp_dev *avp, 97750db69fdSAllain Legacy struct rte_avp_desc *buf, 97850db69fdSAllain Legacy struct rte_mbuf **mbufs, 97950db69fdSAllain Legacy unsigned int count) 98050db69fdSAllain Legacy { 98150db69fdSAllain Legacy struct rte_mbuf *m_previous = NULL; 98250db69fdSAllain Legacy struct rte_avp_desc *pkt_buf; 98350db69fdSAllain Legacy unsigned int total_length = 0; 98450db69fdSAllain Legacy unsigned int copy_length; 98550db69fdSAllain Legacy unsigned int src_offset; 98650db69fdSAllain Legacy struct rte_mbuf *m; 98750db69fdSAllain Legacy uint16_t ol_flags; 98850db69fdSAllain Legacy uint16_t vlan_tci; 98950db69fdSAllain Legacy void *pkt_data; 99050db69fdSAllain Legacy unsigned int i; 99150db69fdSAllain Legacy 99250db69fdSAllain Legacy avp_dev_buffer_sanity_check(avp, buf); 99350db69fdSAllain Legacy 99450db69fdSAllain Legacy /* setup the first source buffer */ 99550db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, buf); 99650db69fdSAllain Legacy pkt_data = avp_dev_translate_buffer(avp, pkt_buf->data); 99750db69fdSAllain Legacy total_length = pkt_buf->pkt_len; 99850db69fdSAllain Legacy src_offset = 0; 99950db69fdSAllain Legacy 100050db69fdSAllain Legacy if (pkt_buf->ol_flags & RTE_AVP_RX_VLAN_PKT) { 100150db69fdSAllain Legacy ol_flags = PKT_RX_VLAN_PKT; 100250db69fdSAllain Legacy vlan_tci = pkt_buf->vlan_tci; 100350db69fdSAllain Legacy } else { 100450db69fdSAllain Legacy ol_flags = 0; 100550db69fdSAllain Legacy vlan_tci = 0; 100650db69fdSAllain Legacy } 100750db69fdSAllain Legacy 100850db69fdSAllain Legacy for (i = 0; (i < count) && (buf != NULL); i++) { 100950db69fdSAllain Legacy /* fill each destination buffer */ 101050db69fdSAllain Legacy m = mbufs[i]; 101150db69fdSAllain Legacy 101250db69fdSAllain Legacy if (m_previous != NULL) 101350db69fdSAllain Legacy m_previous->next = m; 101450db69fdSAllain Legacy 101550db69fdSAllain Legacy m_previous = m; 101650db69fdSAllain Legacy 101750db69fdSAllain Legacy do { 101850db69fdSAllain Legacy /* 101950db69fdSAllain Legacy * Copy as many source buffers as will fit in the 102050db69fdSAllain Legacy * destination buffer. 102150db69fdSAllain Legacy */ 102250db69fdSAllain Legacy copy_length = RTE_MIN((avp->guest_mbuf_size - 102350db69fdSAllain Legacy rte_pktmbuf_data_len(m)), 102450db69fdSAllain Legacy (pkt_buf->data_len - 102550db69fdSAllain Legacy src_offset)); 102650db69fdSAllain Legacy rte_memcpy(RTE_PTR_ADD(rte_pktmbuf_mtod(m, void *), 102750db69fdSAllain Legacy rte_pktmbuf_data_len(m)), 102850db69fdSAllain Legacy RTE_PTR_ADD(pkt_data, src_offset), 102950db69fdSAllain Legacy copy_length); 103050db69fdSAllain Legacy rte_pktmbuf_data_len(m) += copy_length; 103150db69fdSAllain Legacy src_offset += copy_length; 103250db69fdSAllain Legacy 103350db69fdSAllain Legacy if (likely(src_offset == pkt_buf->data_len)) { 103450db69fdSAllain Legacy /* need a new source buffer */ 103550db69fdSAllain Legacy buf = pkt_buf->next; 103650db69fdSAllain Legacy if (buf != NULL) { 103750db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer( 103850db69fdSAllain Legacy avp, buf); 103950db69fdSAllain Legacy pkt_data = avp_dev_translate_buffer( 104050db69fdSAllain Legacy avp, pkt_buf->data); 104150db69fdSAllain Legacy src_offset = 0; 104250db69fdSAllain Legacy } 104350db69fdSAllain Legacy } 104450db69fdSAllain Legacy 104550db69fdSAllain Legacy if (unlikely(rte_pktmbuf_data_len(m) == 104650db69fdSAllain Legacy avp->guest_mbuf_size)) { 104750db69fdSAllain Legacy /* need a new destination mbuf */ 104850db69fdSAllain Legacy break; 104950db69fdSAllain Legacy } 105050db69fdSAllain Legacy 105150db69fdSAllain Legacy } while (buf != NULL); 105250db69fdSAllain Legacy } 105350db69fdSAllain Legacy 105450db69fdSAllain Legacy m = mbufs[0]; 105550db69fdSAllain Legacy m->ol_flags = ol_flags; 105650db69fdSAllain Legacy m->nb_segs = count; 105750db69fdSAllain Legacy rte_pktmbuf_pkt_len(m) = total_length; 105850db69fdSAllain Legacy m->vlan_tci = vlan_tci; 105950db69fdSAllain Legacy 106050db69fdSAllain Legacy __rte_mbuf_sanity_check(m, 1); 106150db69fdSAllain Legacy 106250db69fdSAllain Legacy return m; 106350db69fdSAllain Legacy } 106450db69fdSAllain Legacy 106550db69fdSAllain Legacy static uint16_t 106650db69fdSAllain Legacy avp_recv_scattered_pkts(void *rx_queue, 106750db69fdSAllain Legacy struct rte_mbuf **rx_pkts, 106850db69fdSAllain Legacy uint16_t nb_pkts) 106950db69fdSAllain Legacy { 107050db69fdSAllain Legacy struct avp_queue *rxq = (struct avp_queue *)rx_queue; 107150db69fdSAllain Legacy struct rte_avp_desc *avp_bufs[AVP_MAX_RX_BURST]; 107250db69fdSAllain Legacy struct rte_mbuf *mbufs[RTE_AVP_MAX_MBUF_SEGMENTS]; 107350db69fdSAllain Legacy struct avp_dev *avp = rxq->avp; 107450db69fdSAllain Legacy struct rte_avp_desc *pkt_buf; 107550db69fdSAllain Legacy struct rte_avp_fifo *free_q; 107650db69fdSAllain Legacy struct rte_avp_fifo *rx_q; 107750db69fdSAllain Legacy struct rte_avp_desc *buf; 107850db69fdSAllain Legacy unsigned int count, avail, n; 107950db69fdSAllain Legacy unsigned int guest_mbuf_size; 108050db69fdSAllain Legacy struct rte_mbuf *m; 108150db69fdSAllain Legacy unsigned int required; 108250db69fdSAllain Legacy unsigned int buf_len; 108350db69fdSAllain Legacy unsigned int port_id; 108450db69fdSAllain Legacy unsigned int i; 108550db69fdSAllain Legacy 108650db69fdSAllain Legacy guest_mbuf_size = avp->guest_mbuf_size; 108750db69fdSAllain Legacy port_id = avp->port_id; 108850db69fdSAllain Legacy rx_q = avp->rx_q[rxq->queue_id]; 108950db69fdSAllain Legacy free_q = avp->free_q[rxq->queue_id]; 109050db69fdSAllain Legacy 109150db69fdSAllain Legacy /* setup next queue to service */ 109250db69fdSAllain Legacy rxq->queue_id = (rxq->queue_id < rxq->queue_limit) ? 109350db69fdSAllain Legacy (rxq->queue_id + 1) : rxq->queue_base; 109450db69fdSAllain Legacy 109550db69fdSAllain Legacy /* determine how many slots are available in the free queue */ 109650db69fdSAllain Legacy count = avp_fifo_free_count(free_q); 109750db69fdSAllain Legacy 109850db69fdSAllain Legacy /* determine how many packets are available in the rx queue */ 109950db69fdSAllain Legacy avail = avp_fifo_count(rx_q); 110050db69fdSAllain Legacy 110150db69fdSAllain Legacy /* determine how many packets can be received */ 110250db69fdSAllain Legacy count = RTE_MIN(count, avail); 110350db69fdSAllain Legacy count = RTE_MIN(count, nb_pkts); 110450db69fdSAllain Legacy count = RTE_MIN(count, (unsigned int)AVP_MAX_RX_BURST); 110550db69fdSAllain Legacy 110650db69fdSAllain Legacy if (unlikely(count == 0)) { 110750db69fdSAllain Legacy /* no free buffers, or no buffers on the rx queue */ 110850db69fdSAllain Legacy return 0; 110950db69fdSAllain Legacy } 111050db69fdSAllain Legacy 111150db69fdSAllain Legacy /* retrieve pending packets */ 111250db69fdSAllain Legacy n = avp_fifo_get(rx_q, (void **)&avp_bufs, count); 111350db69fdSAllain Legacy PMD_RX_LOG(DEBUG, "Receiving %u packets from Rx queue at %p\n", 111450db69fdSAllain Legacy count, rx_q); 111550db69fdSAllain Legacy 111650db69fdSAllain Legacy count = 0; 111750db69fdSAllain Legacy for (i = 0; i < n; i++) { 111850db69fdSAllain Legacy /* prefetch next entry while processing current one */ 111950db69fdSAllain Legacy if (i + 1 < n) { 112050db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, 112150db69fdSAllain Legacy avp_bufs[i + 1]); 112250db69fdSAllain Legacy rte_prefetch0(pkt_buf); 112350db69fdSAllain Legacy } 112450db69fdSAllain Legacy buf = avp_bufs[i]; 112550db69fdSAllain Legacy 112650db69fdSAllain Legacy /* Peek into the first buffer to determine the total length */ 112750db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, buf); 112850db69fdSAllain Legacy buf_len = pkt_buf->pkt_len; 112950db69fdSAllain Legacy 113050db69fdSAllain Legacy /* Allocate enough mbufs to receive the entire packet */ 113150db69fdSAllain Legacy required = (buf_len + guest_mbuf_size - 1) / guest_mbuf_size; 113250db69fdSAllain Legacy if (rte_pktmbuf_alloc_bulk(avp->pool, mbufs, required)) { 113350db69fdSAllain Legacy rxq->dev_data->rx_mbuf_alloc_failed++; 113450db69fdSAllain Legacy continue; 113550db69fdSAllain Legacy } 113650db69fdSAllain Legacy 113750db69fdSAllain Legacy /* Copy the data from the buffers to our mbufs */ 113850db69fdSAllain Legacy m = avp_dev_copy_from_buffers(avp, buf, mbufs, required); 113950db69fdSAllain Legacy 114050db69fdSAllain Legacy /* finalize mbuf */ 114150db69fdSAllain Legacy m->port = port_id; 114250db69fdSAllain Legacy 114350db69fdSAllain Legacy if (_avp_mac_filter(avp, m) != 0) { 114450db69fdSAllain Legacy /* silently discard packets not destined to our MAC */ 114550db69fdSAllain Legacy rte_pktmbuf_free(m); 114650db69fdSAllain Legacy continue; 114750db69fdSAllain Legacy } 114850db69fdSAllain Legacy 114950db69fdSAllain Legacy /* return new mbuf to caller */ 115050db69fdSAllain Legacy rx_pkts[count++] = m; 115150db69fdSAllain Legacy rxq->bytes += buf_len; 115250db69fdSAllain Legacy } 115350db69fdSAllain Legacy 115450db69fdSAllain Legacy rxq->packets += count; 115550db69fdSAllain Legacy 115650db69fdSAllain Legacy /* return the buffers to the free queue */ 115750db69fdSAllain Legacy avp_fifo_put(free_q, (void **)&avp_bufs[0], n); 115850db69fdSAllain Legacy 115950db69fdSAllain Legacy return count; 116050db69fdSAllain Legacy } 116150db69fdSAllain Legacy 116250db69fdSAllain Legacy 116350db69fdSAllain Legacy static uint16_t 116450db69fdSAllain Legacy avp_recv_pkts(void *rx_queue, 116550db69fdSAllain Legacy struct rte_mbuf **rx_pkts, 116650db69fdSAllain Legacy uint16_t nb_pkts) 116750db69fdSAllain Legacy { 116850db69fdSAllain Legacy struct avp_queue *rxq = (struct avp_queue *)rx_queue; 116950db69fdSAllain Legacy struct rte_avp_desc *avp_bufs[AVP_MAX_RX_BURST]; 117050db69fdSAllain Legacy struct avp_dev *avp = rxq->avp; 117150db69fdSAllain Legacy struct rte_avp_desc *pkt_buf; 117250db69fdSAllain Legacy struct rte_avp_fifo *free_q; 117350db69fdSAllain Legacy struct rte_avp_fifo *rx_q; 117450db69fdSAllain Legacy unsigned int count, avail, n; 117550db69fdSAllain Legacy unsigned int pkt_len; 117650db69fdSAllain Legacy struct rte_mbuf *m; 117750db69fdSAllain Legacy char *pkt_data; 117850db69fdSAllain Legacy unsigned int i; 117950db69fdSAllain Legacy 118050db69fdSAllain Legacy rx_q = avp->rx_q[rxq->queue_id]; 118150db69fdSAllain Legacy free_q = avp->free_q[rxq->queue_id]; 118250db69fdSAllain Legacy 118350db69fdSAllain Legacy /* setup next queue to service */ 118450db69fdSAllain Legacy rxq->queue_id = (rxq->queue_id < rxq->queue_limit) ? 118550db69fdSAllain Legacy (rxq->queue_id + 1) : rxq->queue_base; 118650db69fdSAllain Legacy 118750db69fdSAllain Legacy /* determine how many slots are available in the free queue */ 118850db69fdSAllain Legacy count = avp_fifo_free_count(free_q); 118950db69fdSAllain Legacy 119050db69fdSAllain Legacy /* determine how many packets are available in the rx queue */ 119150db69fdSAllain Legacy avail = avp_fifo_count(rx_q); 119250db69fdSAllain Legacy 119350db69fdSAllain Legacy /* determine how many packets can be received */ 119450db69fdSAllain Legacy count = RTE_MIN(count, avail); 119550db69fdSAllain Legacy count = RTE_MIN(count, nb_pkts); 119650db69fdSAllain Legacy count = RTE_MIN(count, (unsigned int)AVP_MAX_RX_BURST); 119750db69fdSAllain Legacy 119850db69fdSAllain Legacy if (unlikely(count == 0)) { 119950db69fdSAllain Legacy /* no free buffers, or no buffers on the rx queue */ 120050db69fdSAllain Legacy return 0; 120150db69fdSAllain Legacy } 120250db69fdSAllain Legacy 120350db69fdSAllain Legacy /* retrieve pending packets */ 120450db69fdSAllain Legacy n = avp_fifo_get(rx_q, (void **)&avp_bufs, count); 120550db69fdSAllain Legacy PMD_RX_LOG(DEBUG, "Receiving %u packets from Rx queue at %p\n", 120650db69fdSAllain Legacy count, rx_q); 120750db69fdSAllain Legacy 120850db69fdSAllain Legacy count = 0; 120950db69fdSAllain Legacy for (i = 0; i < n; i++) { 121050db69fdSAllain Legacy /* prefetch next entry while processing current one */ 121150db69fdSAllain Legacy if (i < n - 1) { 121250db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, 121350db69fdSAllain Legacy avp_bufs[i + 1]); 121450db69fdSAllain Legacy rte_prefetch0(pkt_buf); 121550db69fdSAllain Legacy } 121650db69fdSAllain Legacy 121750db69fdSAllain Legacy /* Adjust host pointers for guest addressing */ 121850db69fdSAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, avp_bufs[i]); 121950db69fdSAllain Legacy pkt_data = avp_dev_translate_buffer(avp, pkt_buf->data); 122050db69fdSAllain Legacy pkt_len = pkt_buf->pkt_len; 122150db69fdSAllain Legacy 122250db69fdSAllain Legacy if (unlikely((pkt_len > avp->guest_mbuf_size) || 122350db69fdSAllain Legacy (pkt_buf->nb_segs > 1))) { 122450db69fdSAllain Legacy /* 122550db69fdSAllain Legacy * application should be using the scattered receive 122650db69fdSAllain Legacy * function 122750db69fdSAllain Legacy */ 122850db69fdSAllain Legacy rxq->errors++; 122950db69fdSAllain Legacy continue; 123050db69fdSAllain Legacy } 123150db69fdSAllain Legacy 123250db69fdSAllain Legacy /* process each packet to be transmitted */ 123350db69fdSAllain Legacy m = rte_pktmbuf_alloc(avp->pool); 123450db69fdSAllain Legacy if (unlikely(m == NULL)) { 123550db69fdSAllain Legacy rxq->dev_data->rx_mbuf_alloc_failed++; 123650db69fdSAllain Legacy continue; 123750db69fdSAllain Legacy } 123850db69fdSAllain Legacy 123950db69fdSAllain Legacy /* copy data out of the host buffer to our buffer */ 124050db69fdSAllain Legacy m->data_off = RTE_PKTMBUF_HEADROOM; 124150db69fdSAllain Legacy rte_memcpy(rte_pktmbuf_mtod(m, void *), pkt_data, pkt_len); 124250db69fdSAllain Legacy 124350db69fdSAllain Legacy /* initialize the local mbuf */ 124450db69fdSAllain Legacy rte_pktmbuf_data_len(m) = pkt_len; 124550db69fdSAllain Legacy rte_pktmbuf_pkt_len(m) = pkt_len; 124650db69fdSAllain Legacy m->port = avp->port_id; 124750db69fdSAllain Legacy 124850db69fdSAllain Legacy if (pkt_buf->ol_flags & RTE_AVP_RX_VLAN_PKT) { 124950db69fdSAllain Legacy m->ol_flags = PKT_RX_VLAN_PKT; 125050db69fdSAllain Legacy m->vlan_tci = pkt_buf->vlan_tci; 125150db69fdSAllain Legacy } 125250db69fdSAllain Legacy 125350db69fdSAllain Legacy if (_avp_mac_filter(avp, m) != 0) { 125450db69fdSAllain Legacy /* silently discard packets not destined to our MAC */ 125550db69fdSAllain Legacy rte_pktmbuf_free(m); 125650db69fdSAllain Legacy continue; 125750db69fdSAllain Legacy } 125850db69fdSAllain Legacy 125950db69fdSAllain Legacy /* return new mbuf to caller */ 126050db69fdSAllain Legacy rx_pkts[count++] = m; 126150db69fdSAllain Legacy rxq->bytes += pkt_len; 126250db69fdSAllain Legacy } 126350db69fdSAllain Legacy 126450db69fdSAllain Legacy rxq->packets += count; 126550db69fdSAllain Legacy 126650db69fdSAllain Legacy /* return the buffers to the free queue */ 126750db69fdSAllain Legacy avp_fifo_put(free_q, (void **)&avp_bufs[0], n); 126850db69fdSAllain Legacy 126950db69fdSAllain Legacy return count; 127050db69fdSAllain Legacy } 127150db69fdSAllain Legacy 1272295abce2SAllain Legacy /* 1273295abce2SAllain Legacy * Copy a chained mbuf to a set of host buffers. This function assumes that 1274295abce2SAllain Legacy * there are sufficient destination buffers to contain the entire source 1275295abce2SAllain Legacy * packet. 1276295abce2SAllain Legacy */ 1277295abce2SAllain Legacy static inline uint16_t 1278295abce2SAllain Legacy avp_dev_copy_to_buffers(struct avp_dev *avp, 1279295abce2SAllain Legacy struct rte_mbuf *mbuf, 1280295abce2SAllain Legacy struct rte_avp_desc **buffers, 1281295abce2SAllain Legacy unsigned int count) 1282295abce2SAllain Legacy { 1283295abce2SAllain Legacy struct rte_avp_desc *previous_buf = NULL; 1284295abce2SAllain Legacy struct rte_avp_desc *first_buf = NULL; 1285295abce2SAllain Legacy struct rte_avp_desc *pkt_buf; 1286295abce2SAllain Legacy struct rte_avp_desc *buf; 1287295abce2SAllain Legacy size_t total_length; 1288295abce2SAllain Legacy struct rte_mbuf *m; 1289295abce2SAllain Legacy size_t copy_length; 1290295abce2SAllain Legacy size_t src_offset; 1291295abce2SAllain Legacy char *pkt_data; 1292295abce2SAllain Legacy unsigned int i; 1293295abce2SAllain Legacy 1294295abce2SAllain Legacy __rte_mbuf_sanity_check(mbuf, 1); 1295295abce2SAllain Legacy 1296295abce2SAllain Legacy m = mbuf; 1297295abce2SAllain Legacy src_offset = 0; 1298295abce2SAllain Legacy total_length = rte_pktmbuf_pkt_len(m); 1299295abce2SAllain Legacy for (i = 0; (i < count) && (m != NULL); i++) { 1300295abce2SAllain Legacy /* fill each destination buffer */ 1301295abce2SAllain Legacy buf = buffers[i]; 1302295abce2SAllain Legacy 1303295abce2SAllain Legacy if (i < count - 1) { 1304295abce2SAllain Legacy /* prefetch next entry while processing this one */ 1305295abce2SAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, buffers[i + 1]); 1306295abce2SAllain Legacy rte_prefetch0(pkt_buf); 1307295abce2SAllain Legacy } 1308295abce2SAllain Legacy 1309295abce2SAllain Legacy /* Adjust pointers for guest addressing */ 1310295abce2SAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, buf); 1311295abce2SAllain Legacy pkt_data = avp_dev_translate_buffer(avp, pkt_buf->data); 1312295abce2SAllain Legacy 1313295abce2SAllain Legacy /* setup the buffer chain */ 1314295abce2SAllain Legacy if (previous_buf != NULL) 1315295abce2SAllain Legacy previous_buf->next = buf; 1316295abce2SAllain Legacy else 1317295abce2SAllain Legacy first_buf = pkt_buf; 1318295abce2SAllain Legacy 1319295abce2SAllain Legacy previous_buf = pkt_buf; 1320295abce2SAllain Legacy 1321295abce2SAllain Legacy do { 1322295abce2SAllain Legacy /* 1323295abce2SAllain Legacy * copy as many source mbuf segments as will fit in the 1324295abce2SAllain Legacy * destination buffer. 1325295abce2SAllain Legacy */ 1326295abce2SAllain Legacy copy_length = RTE_MIN((avp->host_mbuf_size - 1327295abce2SAllain Legacy pkt_buf->data_len), 1328295abce2SAllain Legacy (rte_pktmbuf_data_len(m) - 1329295abce2SAllain Legacy src_offset)); 1330295abce2SAllain Legacy rte_memcpy(RTE_PTR_ADD(pkt_data, pkt_buf->data_len), 1331295abce2SAllain Legacy RTE_PTR_ADD(rte_pktmbuf_mtod(m, void *), 1332295abce2SAllain Legacy src_offset), 1333295abce2SAllain Legacy copy_length); 1334295abce2SAllain Legacy pkt_buf->data_len += copy_length; 1335295abce2SAllain Legacy src_offset += copy_length; 1336295abce2SAllain Legacy 1337295abce2SAllain Legacy if (likely(src_offset == rte_pktmbuf_data_len(m))) { 1338295abce2SAllain Legacy /* need a new source buffer */ 1339295abce2SAllain Legacy m = m->next; 1340295abce2SAllain Legacy src_offset = 0; 1341295abce2SAllain Legacy } 1342295abce2SAllain Legacy 1343295abce2SAllain Legacy if (unlikely(pkt_buf->data_len == 1344295abce2SAllain Legacy avp->host_mbuf_size)) { 1345295abce2SAllain Legacy /* need a new destination buffer */ 1346295abce2SAllain Legacy break; 1347295abce2SAllain Legacy } 1348295abce2SAllain Legacy 1349295abce2SAllain Legacy } while (m != NULL); 1350295abce2SAllain Legacy } 1351295abce2SAllain Legacy 1352295abce2SAllain Legacy first_buf->nb_segs = count; 1353295abce2SAllain Legacy first_buf->pkt_len = total_length; 1354295abce2SAllain Legacy 1355295abce2SAllain Legacy if (mbuf->ol_flags & PKT_TX_VLAN_PKT) { 1356295abce2SAllain Legacy first_buf->ol_flags |= RTE_AVP_TX_VLAN_PKT; 1357295abce2SAllain Legacy first_buf->vlan_tci = mbuf->vlan_tci; 1358295abce2SAllain Legacy } 1359295abce2SAllain Legacy 1360295abce2SAllain Legacy avp_dev_buffer_sanity_check(avp, buffers[0]); 1361295abce2SAllain Legacy 1362295abce2SAllain Legacy return total_length; 1363295abce2SAllain Legacy } 1364295abce2SAllain Legacy 1365295abce2SAllain Legacy 1366295abce2SAllain Legacy static uint16_t 1367295abce2SAllain Legacy avp_xmit_scattered_pkts(void *tx_queue, 1368295abce2SAllain Legacy struct rte_mbuf **tx_pkts, 1369295abce2SAllain Legacy uint16_t nb_pkts) 1370295abce2SAllain Legacy { 1371295abce2SAllain Legacy struct rte_avp_desc *avp_bufs[(AVP_MAX_TX_BURST * 1372295abce2SAllain Legacy RTE_AVP_MAX_MBUF_SEGMENTS)]; 1373295abce2SAllain Legacy struct avp_queue *txq = (struct avp_queue *)tx_queue; 1374295abce2SAllain Legacy struct rte_avp_desc *tx_bufs[AVP_MAX_TX_BURST]; 1375295abce2SAllain Legacy struct avp_dev *avp = txq->avp; 1376295abce2SAllain Legacy struct rte_avp_fifo *alloc_q; 1377295abce2SAllain Legacy struct rte_avp_fifo *tx_q; 1378295abce2SAllain Legacy unsigned int count, avail, n; 1379295abce2SAllain Legacy unsigned int orig_nb_pkts; 1380295abce2SAllain Legacy struct rte_mbuf *m; 1381295abce2SAllain Legacy unsigned int required; 1382295abce2SAllain Legacy unsigned int segments; 1383295abce2SAllain Legacy unsigned int tx_bytes; 1384295abce2SAllain Legacy unsigned int i; 1385295abce2SAllain Legacy 1386295abce2SAllain Legacy orig_nb_pkts = nb_pkts; 1387295abce2SAllain Legacy tx_q = avp->tx_q[txq->queue_id]; 1388295abce2SAllain Legacy alloc_q = avp->alloc_q[txq->queue_id]; 1389295abce2SAllain Legacy 1390295abce2SAllain Legacy /* limit the number of transmitted packets to the max burst size */ 1391295abce2SAllain Legacy if (unlikely(nb_pkts > AVP_MAX_TX_BURST)) 1392295abce2SAllain Legacy nb_pkts = AVP_MAX_TX_BURST; 1393295abce2SAllain Legacy 1394295abce2SAllain Legacy /* determine how many buffers are available to copy into */ 1395295abce2SAllain Legacy avail = avp_fifo_count(alloc_q); 1396295abce2SAllain Legacy if (unlikely(avail > (AVP_MAX_TX_BURST * 1397295abce2SAllain Legacy RTE_AVP_MAX_MBUF_SEGMENTS))) 1398295abce2SAllain Legacy avail = AVP_MAX_TX_BURST * RTE_AVP_MAX_MBUF_SEGMENTS; 1399295abce2SAllain Legacy 1400295abce2SAllain Legacy /* determine how many slots are available in the transmit queue */ 1401295abce2SAllain Legacy count = avp_fifo_free_count(tx_q); 1402295abce2SAllain Legacy 1403295abce2SAllain Legacy /* determine how many packets can be sent */ 1404295abce2SAllain Legacy nb_pkts = RTE_MIN(count, nb_pkts); 1405295abce2SAllain Legacy 1406295abce2SAllain Legacy /* determine how many packets will fit in the available buffers */ 1407295abce2SAllain Legacy count = 0; 1408295abce2SAllain Legacy segments = 0; 1409295abce2SAllain Legacy for (i = 0; i < nb_pkts; i++) { 1410295abce2SAllain Legacy m = tx_pkts[i]; 1411295abce2SAllain Legacy if (likely(i < (unsigned int)nb_pkts - 1)) { 1412295abce2SAllain Legacy /* prefetch next entry while processing this one */ 1413295abce2SAllain Legacy rte_prefetch0(tx_pkts[i + 1]); 1414295abce2SAllain Legacy } 1415295abce2SAllain Legacy required = (rte_pktmbuf_pkt_len(m) + avp->host_mbuf_size - 1) / 1416295abce2SAllain Legacy avp->host_mbuf_size; 1417295abce2SAllain Legacy 1418295abce2SAllain Legacy if (unlikely((required == 0) || 1419295abce2SAllain Legacy (required > RTE_AVP_MAX_MBUF_SEGMENTS))) 1420295abce2SAllain Legacy break; 1421295abce2SAllain Legacy else if (unlikely(required + segments > avail)) 1422295abce2SAllain Legacy break; 1423295abce2SAllain Legacy segments += required; 1424295abce2SAllain Legacy count++; 1425295abce2SAllain Legacy } 1426295abce2SAllain Legacy nb_pkts = count; 1427295abce2SAllain Legacy 1428295abce2SAllain Legacy if (unlikely(nb_pkts == 0)) { 1429295abce2SAllain Legacy /* no available buffers, or no space on the tx queue */ 1430295abce2SAllain Legacy txq->errors += orig_nb_pkts; 1431295abce2SAllain Legacy return 0; 1432295abce2SAllain Legacy } 1433295abce2SAllain Legacy 1434295abce2SAllain Legacy PMD_TX_LOG(DEBUG, "Sending %u packets on Tx queue at %p\n", 1435295abce2SAllain Legacy nb_pkts, tx_q); 1436295abce2SAllain Legacy 1437295abce2SAllain Legacy /* retrieve sufficient send buffers */ 1438295abce2SAllain Legacy n = avp_fifo_get(alloc_q, (void **)&avp_bufs, segments); 1439295abce2SAllain Legacy if (unlikely(n != segments)) { 1440295abce2SAllain Legacy PMD_TX_LOG(DEBUG, "Failed to allocate buffers " 1441295abce2SAllain Legacy "n=%u, segments=%u, orig=%u\n", 1442295abce2SAllain Legacy n, segments, orig_nb_pkts); 1443295abce2SAllain Legacy txq->errors += orig_nb_pkts; 1444295abce2SAllain Legacy return 0; 1445295abce2SAllain Legacy } 1446295abce2SAllain Legacy 1447295abce2SAllain Legacy tx_bytes = 0; 1448295abce2SAllain Legacy count = 0; 1449295abce2SAllain Legacy for (i = 0; i < nb_pkts; i++) { 1450295abce2SAllain Legacy /* process each packet to be transmitted */ 1451295abce2SAllain Legacy m = tx_pkts[i]; 1452295abce2SAllain Legacy 1453295abce2SAllain Legacy /* determine how many buffers are required for this packet */ 1454295abce2SAllain Legacy required = (rte_pktmbuf_pkt_len(m) + avp->host_mbuf_size - 1) / 1455295abce2SAllain Legacy avp->host_mbuf_size; 1456295abce2SAllain Legacy 1457295abce2SAllain Legacy tx_bytes += avp_dev_copy_to_buffers(avp, m, 1458295abce2SAllain Legacy &avp_bufs[count], required); 1459295abce2SAllain Legacy tx_bufs[i] = avp_bufs[count]; 1460295abce2SAllain Legacy count += required; 1461295abce2SAllain Legacy 1462295abce2SAllain Legacy /* free the original mbuf */ 1463295abce2SAllain Legacy rte_pktmbuf_free(m); 1464295abce2SAllain Legacy } 1465295abce2SAllain Legacy 1466295abce2SAllain Legacy txq->packets += nb_pkts; 1467295abce2SAllain Legacy txq->bytes += tx_bytes; 1468295abce2SAllain Legacy 1469295abce2SAllain Legacy #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS 1470295abce2SAllain Legacy for (i = 0; i < nb_pkts; i++) 1471295abce2SAllain Legacy avp_dev_buffer_sanity_check(avp, tx_bufs[i]); 1472295abce2SAllain Legacy #endif 1473295abce2SAllain Legacy 1474295abce2SAllain Legacy /* send the packets */ 1475295abce2SAllain Legacy n = avp_fifo_put(tx_q, (void **)&tx_bufs[0], nb_pkts); 1476295abce2SAllain Legacy if (unlikely(n != orig_nb_pkts)) 1477295abce2SAllain Legacy txq->errors += (orig_nb_pkts - n); 1478295abce2SAllain Legacy 1479295abce2SAllain Legacy return n; 1480295abce2SAllain Legacy } 1481295abce2SAllain Legacy 1482295abce2SAllain Legacy 1483295abce2SAllain Legacy static uint16_t 1484295abce2SAllain Legacy avp_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 1485295abce2SAllain Legacy { 1486295abce2SAllain Legacy struct avp_queue *txq = (struct avp_queue *)tx_queue; 1487295abce2SAllain Legacy struct rte_avp_desc *avp_bufs[AVP_MAX_TX_BURST]; 1488295abce2SAllain Legacy struct avp_dev *avp = txq->avp; 1489295abce2SAllain Legacy struct rte_avp_desc *pkt_buf; 1490295abce2SAllain Legacy struct rte_avp_fifo *alloc_q; 1491295abce2SAllain Legacy struct rte_avp_fifo *tx_q; 1492295abce2SAllain Legacy unsigned int count, avail, n; 1493295abce2SAllain Legacy struct rte_mbuf *m; 1494295abce2SAllain Legacy unsigned int pkt_len; 1495295abce2SAllain Legacy unsigned int tx_bytes; 1496295abce2SAllain Legacy char *pkt_data; 1497295abce2SAllain Legacy unsigned int i; 1498295abce2SAllain Legacy 1499295abce2SAllain Legacy tx_q = avp->tx_q[txq->queue_id]; 1500295abce2SAllain Legacy alloc_q = avp->alloc_q[txq->queue_id]; 1501295abce2SAllain Legacy 1502295abce2SAllain Legacy /* limit the number of transmitted packets to the max burst size */ 1503295abce2SAllain Legacy if (unlikely(nb_pkts > AVP_MAX_TX_BURST)) 1504295abce2SAllain Legacy nb_pkts = AVP_MAX_TX_BURST; 1505295abce2SAllain Legacy 1506295abce2SAllain Legacy /* determine how many buffers are available to copy into */ 1507295abce2SAllain Legacy avail = avp_fifo_count(alloc_q); 1508295abce2SAllain Legacy 1509295abce2SAllain Legacy /* determine how many slots are available in the transmit queue */ 1510295abce2SAllain Legacy count = avp_fifo_free_count(tx_q); 1511295abce2SAllain Legacy 1512295abce2SAllain Legacy /* determine how many packets can be sent */ 1513295abce2SAllain Legacy count = RTE_MIN(count, avail); 1514295abce2SAllain Legacy count = RTE_MIN(count, nb_pkts); 1515295abce2SAllain Legacy 1516295abce2SAllain Legacy if (unlikely(count == 0)) { 1517295abce2SAllain Legacy /* no available buffers, or no space on the tx queue */ 1518295abce2SAllain Legacy txq->errors += nb_pkts; 1519295abce2SAllain Legacy return 0; 1520295abce2SAllain Legacy } 1521295abce2SAllain Legacy 1522295abce2SAllain Legacy PMD_TX_LOG(DEBUG, "Sending %u packets on Tx queue at %p\n", 1523295abce2SAllain Legacy count, tx_q); 1524295abce2SAllain Legacy 1525295abce2SAllain Legacy /* retrieve sufficient send buffers */ 1526295abce2SAllain Legacy n = avp_fifo_get(alloc_q, (void **)&avp_bufs, count); 1527295abce2SAllain Legacy if (unlikely(n != count)) { 1528295abce2SAllain Legacy txq->errors++; 1529295abce2SAllain Legacy return 0; 1530295abce2SAllain Legacy } 1531295abce2SAllain Legacy 1532295abce2SAllain Legacy tx_bytes = 0; 1533295abce2SAllain Legacy for (i = 0; i < count; i++) { 1534295abce2SAllain Legacy /* prefetch next entry while processing the current one */ 1535295abce2SAllain Legacy if (i < count - 1) { 1536295abce2SAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, 1537295abce2SAllain Legacy avp_bufs[i + 1]); 1538295abce2SAllain Legacy rte_prefetch0(pkt_buf); 1539295abce2SAllain Legacy } 1540295abce2SAllain Legacy 1541295abce2SAllain Legacy /* process each packet to be transmitted */ 1542295abce2SAllain Legacy m = tx_pkts[i]; 1543295abce2SAllain Legacy 1544295abce2SAllain Legacy /* Adjust pointers for guest addressing */ 1545295abce2SAllain Legacy pkt_buf = avp_dev_translate_buffer(avp, avp_bufs[i]); 1546295abce2SAllain Legacy pkt_data = avp_dev_translate_buffer(avp, pkt_buf->data); 1547295abce2SAllain Legacy pkt_len = rte_pktmbuf_pkt_len(m); 1548295abce2SAllain Legacy 1549295abce2SAllain Legacy if (unlikely((pkt_len > avp->guest_mbuf_size) || 1550295abce2SAllain Legacy (pkt_len > avp->host_mbuf_size))) { 1551295abce2SAllain Legacy /* 1552295abce2SAllain Legacy * application should be using the scattered transmit 1553295abce2SAllain Legacy * function; send it truncated to avoid the performance 1554295abce2SAllain Legacy * hit of having to manage returning the already 1555295abce2SAllain Legacy * allocated buffer to the free list. This should not 1556295abce2SAllain Legacy * happen since the application should have set the 1557295abce2SAllain Legacy * max_rx_pkt_len based on its MTU and it should be 1558295abce2SAllain Legacy * policing its own packet sizes. 1559295abce2SAllain Legacy */ 1560295abce2SAllain Legacy txq->errors++; 1561295abce2SAllain Legacy pkt_len = RTE_MIN(avp->guest_mbuf_size, 1562295abce2SAllain Legacy avp->host_mbuf_size); 1563295abce2SAllain Legacy } 1564295abce2SAllain Legacy 1565295abce2SAllain Legacy /* copy data out of our mbuf and into the AVP buffer */ 1566295abce2SAllain Legacy rte_memcpy(pkt_data, rte_pktmbuf_mtod(m, void *), pkt_len); 1567295abce2SAllain Legacy pkt_buf->pkt_len = pkt_len; 1568295abce2SAllain Legacy pkt_buf->data_len = pkt_len; 1569295abce2SAllain Legacy pkt_buf->nb_segs = 1; 1570295abce2SAllain Legacy pkt_buf->next = NULL; 1571295abce2SAllain Legacy 1572295abce2SAllain Legacy if (m->ol_flags & PKT_TX_VLAN_PKT) { 1573295abce2SAllain Legacy pkt_buf->ol_flags |= RTE_AVP_TX_VLAN_PKT; 1574295abce2SAllain Legacy pkt_buf->vlan_tci = m->vlan_tci; 1575295abce2SAllain Legacy } 1576295abce2SAllain Legacy 1577295abce2SAllain Legacy tx_bytes += pkt_len; 1578295abce2SAllain Legacy 1579295abce2SAllain Legacy /* free the original mbuf */ 1580295abce2SAllain Legacy rte_pktmbuf_free(m); 1581295abce2SAllain Legacy } 1582295abce2SAllain Legacy 1583295abce2SAllain Legacy txq->packets += count; 1584295abce2SAllain Legacy txq->bytes += tx_bytes; 1585295abce2SAllain Legacy 1586295abce2SAllain Legacy /* send the packets */ 1587295abce2SAllain Legacy n = avp_fifo_put(tx_q, (void **)&avp_bufs[0], count); 1588295abce2SAllain Legacy 1589295abce2SAllain Legacy return n; 1590295abce2SAllain Legacy } 1591295abce2SAllain Legacy 1592cce4367fSAllain Legacy static void 1593cce4367fSAllain Legacy avp_dev_rx_queue_release(void *rx_queue) 1594cce4367fSAllain Legacy { 1595cce4367fSAllain Legacy struct avp_queue *rxq = (struct avp_queue *)rx_queue; 1596cce4367fSAllain Legacy struct avp_dev *avp = rxq->avp; 1597cce4367fSAllain Legacy struct rte_eth_dev_data *data = avp->dev_data; 1598cce4367fSAllain Legacy unsigned int i; 1599cce4367fSAllain Legacy 1600cce4367fSAllain Legacy for (i = 0; i < avp->num_rx_queues; i++) { 1601cce4367fSAllain Legacy if (data->rx_queues[i] == rxq) 1602cce4367fSAllain Legacy data->rx_queues[i] = NULL; 1603cce4367fSAllain Legacy } 1604cce4367fSAllain Legacy } 1605cce4367fSAllain Legacy 1606cce4367fSAllain Legacy static void 1607cce4367fSAllain Legacy avp_dev_tx_queue_release(void *tx_queue) 1608cce4367fSAllain Legacy { 1609cce4367fSAllain Legacy struct avp_queue *txq = (struct avp_queue *)tx_queue; 1610cce4367fSAllain Legacy struct avp_dev *avp = txq->avp; 1611cce4367fSAllain Legacy struct rte_eth_dev_data *data = avp->dev_data; 1612cce4367fSAllain Legacy unsigned int i; 1613cce4367fSAllain Legacy 1614cce4367fSAllain Legacy for (i = 0; i < avp->num_tx_queues; i++) { 1615cce4367fSAllain Legacy if (data->tx_queues[i] == txq) 1616cce4367fSAllain Legacy data->tx_queues[i] = NULL; 1617cce4367fSAllain Legacy } 1618cce4367fSAllain Legacy } 1619cce4367fSAllain Legacy 1620cce4367fSAllain Legacy static int 16211a859223SAllain Legacy avp_dev_configure(struct rte_eth_dev *eth_dev) 16221a859223SAllain Legacy { 16231a859223SAllain Legacy struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); 16241a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 16251a859223SAllain Legacy struct rte_avp_device_info *host_info; 16261a859223SAllain Legacy struct rte_avp_device_config config; 16271a859223SAllain Legacy int mask = 0; 16281a859223SAllain Legacy void *addr; 16291a859223SAllain Legacy int ret; 16301a859223SAllain Legacy 16311a859223SAllain Legacy addr = pci_dev->mem_resource[RTE_AVP_PCI_DEVICE_BAR].addr; 16321a859223SAllain Legacy host_info = (struct rte_avp_device_info *)addr; 16331a859223SAllain Legacy 16341a859223SAllain Legacy /* Setup required number of queues */ 16351a859223SAllain Legacy _avp_set_queue_counts(eth_dev); 16361a859223SAllain Legacy 16371a859223SAllain Legacy mask = (ETH_VLAN_STRIP_MASK | 16381a859223SAllain Legacy ETH_VLAN_FILTER_MASK | 16391a859223SAllain Legacy ETH_VLAN_EXTEND_MASK); 16401a859223SAllain Legacy avp_vlan_offload_set(eth_dev, mask); 16411a859223SAllain Legacy 16421a859223SAllain Legacy /* update device config */ 16431a859223SAllain Legacy memset(&config, 0, sizeof(config)); 16441a859223SAllain Legacy config.device_id = host_info->device_id; 16451a859223SAllain Legacy config.driver_type = RTE_AVP_DRIVER_TYPE_DPDK; 16461a859223SAllain Legacy config.driver_version = AVP_DPDK_DRIVER_VERSION; 16471a859223SAllain Legacy config.features = avp->features; 16481a859223SAllain Legacy config.num_tx_queues = avp->num_tx_queues; 16491a859223SAllain Legacy config.num_rx_queues = avp->num_rx_queues; 16501a859223SAllain Legacy 16511a859223SAllain Legacy ret = avp_dev_ctrl_set_config(eth_dev, &config); 16521a859223SAllain Legacy if (ret < 0) { 16531a859223SAllain Legacy PMD_DRV_LOG(ERR, "Config request failed by host, ret=%d\n", 16541a859223SAllain Legacy ret); 16551a859223SAllain Legacy goto unlock; 16561a859223SAllain Legacy } 16571a859223SAllain Legacy 16581a859223SAllain Legacy avp->flags |= AVP_F_CONFIGURED; 16591a859223SAllain Legacy ret = 0; 16601a859223SAllain Legacy 16611a859223SAllain Legacy unlock: 16621a859223SAllain Legacy return ret; 16631a859223SAllain Legacy } 16641a859223SAllain Legacy 16651a859223SAllain Legacy 16661a859223SAllain Legacy static int 16671a859223SAllain Legacy avp_dev_link_update(struct rte_eth_dev *eth_dev, 16681a859223SAllain Legacy __rte_unused int wait_to_complete) 16691a859223SAllain Legacy { 16701a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 16711a859223SAllain Legacy struct rte_eth_link *link = ð_dev->data->dev_link; 16721a859223SAllain Legacy 16731a859223SAllain Legacy link->link_speed = ETH_SPEED_NUM_10G; 16741a859223SAllain Legacy link->link_duplex = ETH_LINK_FULL_DUPLEX; 16751a859223SAllain Legacy link->link_status = !!(avp->flags & AVP_F_LINKUP); 16761a859223SAllain Legacy 16771a859223SAllain Legacy return -1; 16781a859223SAllain Legacy } 16791a859223SAllain Legacy 16801a859223SAllain Legacy 16811a859223SAllain Legacy static void 16821a859223SAllain Legacy avp_dev_info_get(struct rte_eth_dev *eth_dev, 16831a859223SAllain Legacy struct rte_eth_dev_info *dev_info) 16841a859223SAllain Legacy { 16851a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 16861a859223SAllain Legacy 16871a859223SAllain Legacy dev_info->driver_name = "rte_avp_pmd"; 16881a859223SAllain Legacy dev_info->pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 16891a859223SAllain Legacy dev_info->max_rx_queues = avp->max_rx_queues; 16901a859223SAllain Legacy dev_info->max_tx_queues = avp->max_tx_queues; 16911a859223SAllain Legacy dev_info->min_rx_bufsize = AVP_MIN_RX_BUFSIZE; 16921a859223SAllain Legacy dev_info->max_rx_pktlen = avp->max_rx_pkt_len; 16931a859223SAllain Legacy dev_info->max_mac_addrs = AVP_MAX_MAC_ADDRS; 16941a859223SAllain Legacy if (avp->host_features & RTE_AVP_FEATURE_VLAN_OFFLOAD) { 16951a859223SAllain Legacy dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP; 16961a859223SAllain Legacy dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT; 16971a859223SAllain Legacy } 16981a859223SAllain Legacy } 16991a859223SAllain Legacy 17001a859223SAllain Legacy static void 17011a859223SAllain Legacy avp_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) 17021a859223SAllain Legacy { 17031a859223SAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 17041a859223SAllain Legacy 17051a859223SAllain Legacy if (mask & ETH_VLAN_STRIP_MASK) { 17061a859223SAllain Legacy if (avp->host_features & RTE_AVP_FEATURE_VLAN_OFFLOAD) { 17071a859223SAllain Legacy if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip) 17081a859223SAllain Legacy avp->features |= RTE_AVP_FEATURE_VLAN_OFFLOAD; 17091a859223SAllain Legacy else 17101a859223SAllain Legacy avp->features &= ~RTE_AVP_FEATURE_VLAN_OFFLOAD; 17111a859223SAllain Legacy } else { 17121a859223SAllain Legacy PMD_DRV_LOG(ERR, "VLAN strip offload not supported\n"); 17131a859223SAllain Legacy } 17141a859223SAllain Legacy } 17151a859223SAllain Legacy 17161a859223SAllain Legacy if (mask & ETH_VLAN_FILTER_MASK) { 17171a859223SAllain Legacy if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter) 17181a859223SAllain Legacy PMD_DRV_LOG(ERR, "VLAN filter offload not supported\n"); 17191a859223SAllain Legacy } 17201a859223SAllain Legacy 17211a859223SAllain Legacy if (mask & ETH_VLAN_EXTEND_MASK) { 17221a859223SAllain Legacy if (eth_dev->data->dev_conf.rxmode.hw_vlan_extend) 17231a859223SAllain Legacy PMD_DRV_LOG(ERR, "VLAN extend offload not supported\n"); 17241a859223SAllain Legacy } 17251a859223SAllain Legacy } 17261a859223SAllain Legacy 1727*5a5abe2dSAllain Legacy static void 1728*5a5abe2dSAllain Legacy avp_dev_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats) 1729*5a5abe2dSAllain Legacy { 1730*5a5abe2dSAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 1731*5a5abe2dSAllain Legacy unsigned int i; 1732*5a5abe2dSAllain Legacy 1733*5a5abe2dSAllain Legacy for (i = 0; i < avp->num_rx_queues; i++) { 1734*5a5abe2dSAllain Legacy struct avp_queue *rxq = avp->dev_data->rx_queues[i]; 1735*5a5abe2dSAllain Legacy 1736*5a5abe2dSAllain Legacy if (rxq) { 1737*5a5abe2dSAllain Legacy stats->ipackets += rxq->packets; 1738*5a5abe2dSAllain Legacy stats->ibytes += rxq->bytes; 1739*5a5abe2dSAllain Legacy stats->ierrors += rxq->errors; 1740*5a5abe2dSAllain Legacy 1741*5a5abe2dSAllain Legacy stats->q_ipackets[i] += rxq->packets; 1742*5a5abe2dSAllain Legacy stats->q_ibytes[i] += rxq->bytes; 1743*5a5abe2dSAllain Legacy stats->q_errors[i] += rxq->errors; 1744*5a5abe2dSAllain Legacy } 1745*5a5abe2dSAllain Legacy } 1746*5a5abe2dSAllain Legacy 1747*5a5abe2dSAllain Legacy for (i = 0; i < avp->num_tx_queues; i++) { 1748*5a5abe2dSAllain Legacy struct avp_queue *txq = avp->dev_data->tx_queues[i]; 1749*5a5abe2dSAllain Legacy 1750*5a5abe2dSAllain Legacy if (txq) { 1751*5a5abe2dSAllain Legacy stats->opackets += txq->packets; 1752*5a5abe2dSAllain Legacy stats->obytes += txq->bytes; 1753*5a5abe2dSAllain Legacy stats->oerrors += txq->errors; 1754*5a5abe2dSAllain Legacy 1755*5a5abe2dSAllain Legacy stats->q_opackets[i] += txq->packets; 1756*5a5abe2dSAllain Legacy stats->q_obytes[i] += txq->bytes; 1757*5a5abe2dSAllain Legacy stats->q_errors[i] += txq->errors; 1758*5a5abe2dSAllain Legacy } 1759*5a5abe2dSAllain Legacy } 1760*5a5abe2dSAllain Legacy } 1761*5a5abe2dSAllain Legacy 1762*5a5abe2dSAllain Legacy static void 1763*5a5abe2dSAllain Legacy avp_dev_stats_reset(struct rte_eth_dev *eth_dev) 1764*5a5abe2dSAllain Legacy { 1765*5a5abe2dSAllain Legacy struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); 1766*5a5abe2dSAllain Legacy unsigned int i; 1767*5a5abe2dSAllain Legacy 1768*5a5abe2dSAllain Legacy for (i = 0; i < avp->num_rx_queues; i++) { 1769*5a5abe2dSAllain Legacy struct avp_queue *rxq = avp->dev_data->rx_queues[i]; 1770*5a5abe2dSAllain Legacy 1771*5a5abe2dSAllain Legacy if (rxq) { 1772*5a5abe2dSAllain Legacy rxq->bytes = 0; 1773*5a5abe2dSAllain Legacy rxq->packets = 0; 1774*5a5abe2dSAllain Legacy rxq->errors = 0; 1775*5a5abe2dSAllain Legacy } 1776*5a5abe2dSAllain Legacy } 1777*5a5abe2dSAllain Legacy 1778*5a5abe2dSAllain Legacy for (i = 0; i < avp->num_tx_queues; i++) { 1779*5a5abe2dSAllain Legacy struct avp_queue *txq = avp->dev_data->tx_queues[i]; 1780*5a5abe2dSAllain Legacy 1781*5a5abe2dSAllain Legacy if (txq) { 1782*5a5abe2dSAllain Legacy txq->bytes = 0; 1783*5a5abe2dSAllain Legacy txq->packets = 0; 1784*5a5abe2dSAllain Legacy txq->errors = 0; 1785*5a5abe2dSAllain Legacy } 1786*5a5abe2dSAllain Legacy } 1787*5a5abe2dSAllain Legacy } 1788*5a5abe2dSAllain Legacy 1789908072e9SAllain Legacy RTE_PMD_REGISTER_PCI(net_avp, rte_avp_pmd.pci_drv); 1790908072e9SAllain Legacy RTE_PMD_REGISTER_PCI_TABLE(net_avp, pci_id_avp_map); 1791