xref: /dpdk/drivers/net/avp/avp_ethdev.c (revision 908072e9d0e6d94c0ca8bb9323ec6cb32d45966b)
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