1*908072e9SAllain Legacy /* 2*908072e9SAllain Legacy * BSD LICENSE 3*908072e9SAllain Legacy * 4*908072e9SAllain Legacy * Copyright (c) 2013-2017, Wind River Systems, Inc. 5*908072e9SAllain Legacy * 6*908072e9SAllain Legacy * Redistribution and use in source and binary forms, with or without 7*908072e9SAllain Legacy * modification, are permitted provided that the following conditions are met: 8*908072e9SAllain Legacy * 9*908072e9SAllain Legacy * 1) Redistributions of source code must retain the above copyright notice, 10*908072e9SAllain Legacy * this list of conditions and the following disclaimer. 11*908072e9SAllain Legacy * 12*908072e9SAllain Legacy * 2) Redistributions in binary form must reproduce the above copyright notice, 13*908072e9SAllain Legacy * this list of conditions and the following disclaimer in the documentation 14*908072e9SAllain Legacy * and/or other materials provided with the distribution. 15*908072e9SAllain Legacy * 16*908072e9SAllain Legacy * 3) Neither the name of Wind River Systems nor the names of its contributors 17*908072e9SAllain Legacy * may be used to endorse or promote products derived from this software 18*908072e9SAllain Legacy * without specific prior written permission. 19*908072e9SAllain Legacy * 20*908072e9SAllain Legacy * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21*908072e9SAllain Legacy * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22*908072e9SAllain Legacy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23*908072e9SAllain Legacy * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24*908072e9SAllain Legacy * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25*908072e9SAllain Legacy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26*908072e9SAllain Legacy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27*908072e9SAllain Legacy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28*908072e9SAllain Legacy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29*908072e9SAllain Legacy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30*908072e9SAllain Legacy * POSSIBILITY OF SUCH DAMAGE. 31*908072e9SAllain Legacy */ 32*908072e9SAllain Legacy 33*908072e9SAllain Legacy #include <stdint.h> 34*908072e9SAllain Legacy #include <string.h> 35*908072e9SAllain Legacy #include <stdio.h> 36*908072e9SAllain Legacy #include <errno.h> 37*908072e9SAllain Legacy #include <unistd.h> 38*908072e9SAllain Legacy 39*908072e9SAllain Legacy #include <rte_ethdev.h> 40*908072e9SAllain Legacy #include <rte_memcpy.h> 41*908072e9SAllain Legacy #include <rte_string_fns.h> 42*908072e9SAllain Legacy #include <rte_memzone.h> 43*908072e9SAllain Legacy #include <rte_malloc.h> 44*908072e9SAllain Legacy #include <rte_atomic.h> 45*908072e9SAllain Legacy #include <rte_branch_prediction.h> 46*908072e9SAllain Legacy #include <rte_pci.h> 47*908072e9SAllain Legacy #include <rte_ether.h> 48*908072e9SAllain Legacy #include <rte_common.h> 49*908072e9SAllain Legacy #include <rte_cycles.h> 50*908072e9SAllain Legacy #include <rte_byteorder.h> 51*908072e9SAllain Legacy #include <rte_dev.h> 52*908072e9SAllain Legacy #include <rte_memory.h> 53*908072e9SAllain Legacy #include <rte_eal.h> 54*908072e9SAllain Legacy 55*908072e9SAllain Legacy #include "rte_avp_common.h" 56*908072e9SAllain Legacy #include "rte_avp_fifo.h" 57*908072e9SAllain Legacy 58*908072e9SAllain Legacy #include "avp_logs.h" 59*908072e9SAllain Legacy 60*908072e9SAllain Legacy 61*908072e9SAllain Legacy 62*908072e9SAllain Legacy #define AVP_DEV_TO_PCI(eth_dev) RTE_DEV_TO_PCI((eth_dev)->device) 63*908072e9SAllain Legacy 64*908072e9SAllain Legacy 65*908072e9SAllain Legacy #define AVP_MAX_MAC_ADDRS 1 66*908072e9SAllain Legacy #define AVP_MIN_RX_BUFSIZE ETHER_MIN_LEN 67*908072e9SAllain Legacy 68*908072e9SAllain Legacy 69*908072e9SAllain Legacy /* 70*908072e9SAllain Legacy * Defines the number of microseconds to wait before checking the response 71*908072e9SAllain Legacy * queue for completion. 72*908072e9SAllain Legacy */ 73*908072e9SAllain Legacy #define AVP_REQUEST_DELAY_USECS (5000) 74*908072e9SAllain Legacy 75*908072e9SAllain Legacy /* 76*908072e9SAllain Legacy * Defines the number times to check the response queue for completion before 77*908072e9SAllain Legacy * declaring a timeout. 78*908072e9SAllain Legacy */ 79*908072e9SAllain Legacy #define AVP_MAX_REQUEST_RETRY (100) 80*908072e9SAllain Legacy 81*908072e9SAllain Legacy /* Defines the current PCI driver version number */ 82*908072e9SAllain Legacy #define AVP_DPDK_DRIVER_VERSION RTE_AVP_CURRENT_GUEST_VERSION 83*908072e9SAllain Legacy 84*908072e9SAllain Legacy /* 85*908072e9SAllain Legacy * The set of PCI devices this driver supports 86*908072e9SAllain Legacy */ 87*908072e9SAllain Legacy static const struct rte_pci_id pci_id_avp_map[] = { 88*908072e9SAllain Legacy { .vendor_id = RTE_AVP_PCI_VENDOR_ID, 89*908072e9SAllain Legacy .device_id = RTE_AVP_PCI_DEVICE_ID, 90*908072e9SAllain Legacy .subsystem_vendor_id = RTE_AVP_PCI_SUB_VENDOR_ID, 91*908072e9SAllain Legacy .subsystem_device_id = RTE_AVP_PCI_SUB_DEVICE_ID, 92*908072e9SAllain Legacy .class_id = RTE_CLASS_ANY_ID, 93*908072e9SAllain Legacy }, 94*908072e9SAllain Legacy 95*908072e9SAllain Legacy { .vendor_id = 0, /* sentinel */ 96*908072e9SAllain Legacy }, 97*908072e9SAllain Legacy }; 98*908072e9SAllain Legacy 99*908072e9SAllain Legacy 100*908072e9SAllain Legacy /* 101*908072e9SAllain Legacy * Defines the AVP device attributes which are attached to an RTE ethernet 102*908072e9SAllain Legacy * device 103*908072e9SAllain Legacy */ 104*908072e9SAllain Legacy struct avp_dev { 105*908072e9SAllain Legacy uint32_t magic; /**< Memory validation marker */ 106*908072e9SAllain Legacy uint64_t device_id; /**< Unique system identifier */ 107*908072e9SAllain Legacy struct ether_addr ethaddr; /**< Host specified MAC address */ 108*908072e9SAllain Legacy struct rte_eth_dev_data *dev_data; 109*908072e9SAllain Legacy /**< Back pointer to ethernet device data */ 110*908072e9SAllain Legacy volatile uint32_t flags; /**< Device operational flags */ 111*908072e9SAllain Legacy uint8_t port_id; /**< Ethernet port identifier */ 112*908072e9SAllain Legacy struct rte_mempool *pool; /**< pkt mbuf mempool */ 113*908072e9SAllain Legacy unsigned int guest_mbuf_size; /**< local pool mbuf size */ 114*908072e9SAllain Legacy unsigned int host_mbuf_size; /**< host mbuf size */ 115*908072e9SAllain Legacy unsigned int max_rx_pkt_len; /**< maximum receive unit */ 116*908072e9SAllain Legacy uint32_t host_features; /**< Supported feature bitmap */ 117*908072e9SAllain Legacy uint32_t features; /**< Enabled feature bitmap */ 118*908072e9SAllain Legacy unsigned int num_tx_queues; /**< Negotiated number of transmit queues */ 119*908072e9SAllain Legacy unsigned int max_tx_queues; /**< Maximum number of transmit queues */ 120*908072e9SAllain Legacy unsigned int num_rx_queues; /**< Negotiated number of receive queues */ 121*908072e9SAllain Legacy unsigned int max_rx_queues; /**< Maximum number of receive queues */ 122*908072e9SAllain Legacy 123*908072e9SAllain Legacy struct rte_avp_fifo *tx_q[RTE_AVP_MAX_QUEUES]; /**< TX queue */ 124*908072e9SAllain Legacy struct rte_avp_fifo *rx_q[RTE_AVP_MAX_QUEUES]; /**< RX queue */ 125*908072e9SAllain Legacy struct rte_avp_fifo *alloc_q[RTE_AVP_MAX_QUEUES]; 126*908072e9SAllain Legacy /**< Allocated mbufs queue */ 127*908072e9SAllain Legacy struct rte_avp_fifo *free_q[RTE_AVP_MAX_QUEUES]; 128*908072e9SAllain Legacy /**< To be freed mbufs queue */ 129*908072e9SAllain Legacy 130*908072e9SAllain Legacy /* For request & response */ 131*908072e9SAllain Legacy struct rte_avp_fifo *req_q; /**< Request queue */ 132*908072e9SAllain Legacy struct rte_avp_fifo *resp_q; /**< Response queue */ 133*908072e9SAllain Legacy void *host_sync_addr; /**< (host) Req/Resp Mem address */ 134*908072e9SAllain Legacy void *sync_addr; /**< Req/Resp Mem address */ 135*908072e9SAllain Legacy void *host_mbuf_addr; /**< (host) MBUF pool start address */ 136*908072e9SAllain Legacy void *mbuf_addr; /**< MBUF pool start address */ 137*908072e9SAllain Legacy } __rte_cache_aligned; 138*908072e9SAllain Legacy 139*908072e9SAllain Legacy /* RTE ethernet private data */ 140*908072e9SAllain Legacy struct avp_adapter { 141*908072e9SAllain Legacy struct avp_dev avp; 142*908072e9SAllain Legacy } __rte_cache_aligned; 143*908072e9SAllain Legacy 144*908072e9SAllain Legacy /* Macro to cast the ethernet device private data to a AVP object */ 145*908072e9SAllain Legacy #define AVP_DEV_PRIVATE_TO_HW(adapter) \ 146*908072e9SAllain Legacy (&((struct avp_adapter *)adapter)->avp) 147*908072e9SAllain Legacy 148*908072e9SAllain Legacy /* 149*908072e9SAllain Legacy * This function is based on probe() function in avp_pci.c 150*908072e9SAllain Legacy * It returns 0 on success. 151*908072e9SAllain Legacy */ 152*908072e9SAllain Legacy static int 153*908072e9SAllain Legacy eth_avp_dev_init(struct rte_eth_dev *eth_dev) 154*908072e9SAllain Legacy { 155*908072e9SAllain Legacy struct rte_pci_device *pci_dev; 156*908072e9SAllain Legacy 157*908072e9SAllain Legacy pci_dev = AVP_DEV_TO_PCI(eth_dev); 158*908072e9SAllain Legacy 159*908072e9SAllain Legacy if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 160*908072e9SAllain Legacy /* 161*908072e9SAllain Legacy * no setup required on secondary processes. All data is saved 162*908072e9SAllain Legacy * in dev_private by the primary process. All resource should 163*908072e9SAllain Legacy * be mapped to the same virtual address so all pointers should 164*908072e9SAllain Legacy * be valid. 165*908072e9SAllain Legacy */ 166*908072e9SAllain Legacy return 0; 167*908072e9SAllain Legacy } 168*908072e9SAllain Legacy 169*908072e9SAllain Legacy rte_eth_copy_pci_info(eth_dev, pci_dev); 170*908072e9SAllain Legacy 171*908072e9SAllain Legacy eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE; 172*908072e9SAllain Legacy 173*908072e9SAllain Legacy return 0; 174*908072e9SAllain Legacy } 175*908072e9SAllain Legacy 176*908072e9SAllain Legacy static int 177*908072e9SAllain Legacy eth_avp_dev_uninit(struct rte_eth_dev *eth_dev) 178*908072e9SAllain Legacy { 179*908072e9SAllain Legacy if (rte_eal_process_type() != RTE_PROC_PRIMARY) 180*908072e9SAllain Legacy return -EPERM; 181*908072e9SAllain Legacy 182*908072e9SAllain Legacy if (eth_dev->data == NULL) 183*908072e9SAllain Legacy return 0; 184*908072e9SAllain Legacy 185*908072e9SAllain Legacy return 0; 186*908072e9SAllain Legacy } 187*908072e9SAllain Legacy 188*908072e9SAllain Legacy 189*908072e9SAllain Legacy static struct eth_driver rte_avp_pmd = { 190*908072e9SAllain Legacy { 191*908072e9SAllain Legacy .id_table = pci_id_avp_map, 192*908072e9SAllain Legacy .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 193*908072e9SAllain Legacy .probe = rte_eth_dev_pci_probe, 194*908072e9SAllain Legacy .remove = rte_eth_dev_pci_remove, 195*908072e9SAllain Legacy }, 196*908072e9SAllain Legacy .eth_dev_init = eth_avp_dev_init, 197*908072e9SAllain Legacy .eth_dev_uninit = eth_avp_dev_uninit, 198*908072e9SAllain Legacy .dev_private_size = sizeof(struct avp_adapter), 199*908072e9SAllain Legacy }; 200*908072e9SAllain Legacy 201*908072e9SAllain Legacy RTE_PMD_REGISTER_PCI(net_avp, rte_avp_pmd.pci_drv); 202*908072e9SAllain Legacy RTE_PMD_REGISTER_PCI_TABLE(net_avp, pci_id_avp_map); 203