xref: /dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c (revision ceb1ccd5d50c1a89ba8bdd97cc199e7f07422b98)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/queue.h>
35 #include <stdio.h>
36 #include <errno.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <stdarg.h>
41 #include <fcntl.h>
42 #include <inttypes.h>
43 #include <rte_byteorder.h>
44 #include <rte_common.h>
45 #include <rte_cycles.h>
46 
47 #include <rte_interrupts.h>
48 #include <rte_log.h>
49 #include <rte_debug.h>
50 #include <rte_pci.h>
51 #include <rte_atomic.h>
52 #include <rte_branch_prediction.h>
53 #include <rte_memory.h>
54 #include <rte_memzone.h>
55 #include <rte_eal.h>
56 #include <rte_alarm.h>
57 #include <rte_ether.h>
58 #include <rte_ethdev.h>
59 #include <rte_atomic.h>
60 #include <rte_string_fns.h>
61 #include <rte_malloc.h>
62 #include <rte_dev.h>
63 
64 #include "base/vmxnet3_defs.h"
65 
66 #include "vmxnet3_ring.h"
67 #include "vmxnet3_logs.h"
68 #include "vmxnet3_ethdev.h"
69 
70 #define PROCESS_SYS_EVENTS 0
71 
72 static int eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev);
73 static int eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev);
74 static int vmxnet3_dev_configure(struct rte_eth_dev *dev);
75 static int vmxnet3_dev_start(struct rte_eth_dev *dev);
76 static void vmxnet3_dev_stop(struct rte_eth_dev *dev);
77 static void vmxnet3_dev_close(struct rte_eth_dev *dev);
78 static void vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set);
79 static void vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev);
80 static void vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev);
81 static void vmxnet3_dev_allmulticast_enable(struct rte_eth_dev *dev);
82 static void vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev);
83 static int vmxnet3_dev_link_update(struct rte_eth_dev *dev,
84 				int wait_to_complete);
85 static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
86 				struct rte_eth_stats *stats);
87 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
88 				struct rte_eth_dev_info *dev_info);
89 static const uint32_t *
90 vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
91 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
92 				       uint16_t vid, int on);
93 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
94 static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
95 				 struct ether_addr *mac_addr);
96 
97 #if PROCESS_SYS_EVENTS == 1
98 static void vmxnet3_process_events(struct vmxnet3_hw *);
99 #endif
100 /*
101  * The set of PCI devices this driver supports
102  */
103 static const struct rte_pci_id pci_id_vmxnet3_map[] = {
104 
105 #define RTE_PCI_DEV_ID_DECL_VMXNET3(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
106 #include "rte_pci_dev_ids.h"
107 
108 { .vendor_id = 0, /* sentinel */ },
109 };
110 
111 static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
112 	.dev_configure        = vmxnet3_dev_configure,
113 	.dev_start            = vmxnet3_dev_start,
114 	.dev_stop             = vmxnet3_dev_stop,
115 	.dev_close            = vmxnet3_dev_close,
116 	.promiscuous_enable   = vmxnet3_dev_promiscuous_enable,
117 	.promiscuous_disable  = vmxnet3_dev_promiscuous_disable,
118 	.allmulticast_enable  = vmxnet3_dev_allmulticast_enable,
119 	.allmulticast_disable = vmxnet3_dev_allmulticast_disable,
120 	.link_update          = vmxnet3_dev_link_update,
121 	.stats_get            = vmxnet3_dev_stats_get,
122 	.mac_addr_set	      = vmxnet3_mac_addr_set,
123 	.dev_infos_get        = vmxnet3_dev_info_get,
124 	.dev_supported_ptypes_get = vmxnet3_dev_supported_ptypes_get,
125 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
126 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
127 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
128 	.rx_queue_release     = vmxnet3_dev_rx_queue_release,
129 	.tx_queue_setup       = vmxnet3_dev_tx_queue_setup,
130 	.tx_queue_release     = vmxnet3_dev_tx_queue_release,
131 };
132 
133 static const struct rte_memzone *
134 gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
135 		const char *post_string, int socket_id, uint16_t align)
136 {
137 	char z_name[RTE_MEMZONE_NAMESIZE];
138 	const struct rte_memzone *mz;
139 
140 	snprintf(z_name, sizeof(z_name), "%s_%d_%s",
141 					dev->driver->pci_drv.name, dev->data->port_id, post_string);
142 
143 	mz = rte_memzone_lookup(z_name);
144 	if (mz)
145 		return mz;
146 
147 	return rte_memzone_reserve_aligned(z_name, size,
148 			socket_id, 0, align);
149 }
150 
151 /**
152  * Atomically reads the link status information from global
153  * structure rte_eth_dev.
154  *
155  * @param dev
156  *   - Pointer to the structure rte_eth_dev to read from.
157  *   - Pointer to the buffer to be saved with the link status.
158  *
159  * @return
160  *   - On success, zero.
161  *   - On failure, negative value.
162  */
163 
164 static int
165 vmxnet3_dev_atomic_read_link_status(struct rte_eth_dev *dev,
166 				    struct rte_eth_link *link)
167 {
168 	struct rte_eth_link *dst = link;
169 	struct rte_eth_link *src = &(dev->data->dev_link);
170 
171 	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
172 				*(uint64_t *)src) == 0)
173 		return -1;
174 
175 	return 0;
176 }
177 
178 /**
179  * Atomically writes the link status information into global
180  * structure rte_eth_dev.
181  *
182  * @param dev
183  *   - Pointer to the structure rte_eth_dev to write to.
184  *   - Pointer to the buffer to be saved with the link status.
185  *
186  * @return
187  *   - On success, zero.
188  *   - On failure, negative value.
189  */
190 static int
191 vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
192 				     struct rte_eth_link *link)
193 {
194 	struct rte_eth_link *dst = &(dev->data->dev_link);
195 	struct rte_eth_link *src = link;
196 
197 	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
198 					*(uint64_t *)src) == 0)
199 		return -1;
200 
201 	return 0;
202 }
203 
204 /*
205  * This function is based on vmxnet3_disable_intr()
206  */
207 static void
208 vmxnet3_disable_intr(struct vmxnet3_hw *hw)
209 {
210 	int i;
211 
212 	PMD_INIT_FUNC_TRACE();
213 
214 	hw->shared->devRead.intrConf.intrCtrl |= VMXNET3_IC_DISABLE_ALL;
215 	for (i = 0; i < VMXNET3_MAX_INTRS; i++)
216 			VMXNET3_WRITE_BAR0_REG(hw, VMXNET3_REG_IMR + i * 8, 1);
217 }
218 
219 /*
220  * It returns 0 on success.
221  */
222 static int
223 eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
224 {
225 	struct rte_pci_device *pci_dev;
226 	struct vmxnet3_hw *hw = eth_dev->data->dev_private;
227 	uint32_t mac_hi, mac_lo, ver;
228 
229 	PMD_INIT_FUNC_TRACE();
230 
231 	eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
232 	eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
233 	eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
234 	pci_dev = eth_dev->pci_dev;
235 
236 	/*
237 	 * for secondary processes, we don't initialize any further as primary
238 	 * has already done this work.
239 	 */
240 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
241 		return 0;
242 
243 	rte_eth_copy_pci_info(eth_dev, pci_dev);
244 
245 	/* Vendor and Device ID need to be set before init of shared code */
246 	hw->device_id = pci_dev->id.device_id;
247 	hw->vendor_id = pci_dev->id.vendor_id;
248 	hw->hw_addr0 = (void *)pci_dev->mem_resource[0].addr;
249 	hw->hw_addr1 = (void *)pci_dev->mem_resource[1].addr;
250 
251 	hw->num_rx_queues = 1;
252 	hw->num_tx_queues = 1;
253 	hw->bufs_per_pkt = 1;
254 
255 	/* Check h/w version compatibility with driver. */
256 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_VRRS);
257 	PMD_INIT_LOG(DEBUG, "Hardware version : %d", ver);
258 	if (ver & 0x1)
259 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS, 1);
260 	else {
261 		PMD_INIT_LOG(ERR, "Incompatible h/w version, should be 0x1");
262 		return -EIO;
263 	}
264 
265 	/* Check UPT version compatibility with driver. */
266 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_UVRS);
267 	PMD_INIT_LOG(DEBUG, "UPT hardware version : %d", ver);
268 	if (ver & 0x1)
269 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_UVRS, 1);
270 	else {
271 		PMD_INIT_LOG(ERR, "Incompatible UPT version.");
272 		return -EIO;
273 	}
274 
275 	/* Getting MAC Address */
276 	mac_lo = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_MACL);
277 	mac_hi = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_MACH);
278 	memcpy(hw->perm_addr  , &mac_lo, 4);
279 	memcpy(hw->perm_addr+4, &mac_hi, 2);
280 
281 	/* Allocate memory for storing MAC addresses */
282 	eth_dev->data->mac_addrs = rte_zmalloc("vmxnet3", ETHER_ADDR_LEN *
283 					       VMXNET3_MAX_MAC_ADDRS, 0);
284 	if (eth_dev->data->mac_addrs == NULL) {
285 		PMD_INIT_LOG(ERR,
286 			     "Failed to allocate %d bytes needed to store MAC addresses",
287 			     ETHER_ADDR_LEN * VMXNET3_MAX_MAC_ADDRS);
288 		return -ENOMEM;
289 	}
290 	/* Copy the permanent MAC address */
291 	ether_addr_copy((struct ether_addr *) hw->perm_addr,
292 			&eth_dev->data->mac_addrs[0]);
293 
294 	PMD_INIT_LOG(DEBUG, "MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
295 		     hw->perm_addr[0], hw->perm_addr[1], hw->perm_addr[2],
296 		     hw->perm_addr[3], hw->perm_addr[4], hw->perm_addr[5]);
297 
298 	/* Put device in Quiesce Mode */
299 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
300 
301 	/* allow untagged pkts */
302 	VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
303 
304 	return 0;
305 }
306 
307 static int
308 eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev)
309 {
310 	struct vmxnet3_hw *hw = eth_dev->data->dev_private;
311 
312 	PMD_INIT_FUNC_TRACE();
313 
314 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
315 		return 0;
316 
317 	if (hw->adapter_stopped == 0)
318 		vmxnet3_dev_close(eth_dev);
319 
320 	eth_dev->dev_ops = NULL;
321 	eth_dev->rx_pkt_burst = NULL;
322 	eth_dev->tx_pkt_burst = NULL;
323 
324 	rte_free(eth_dev->data->mac_addrs);
325 	eth_dev->data->mac_addrs = NULL;
326 
327 	return 0;
328 }
329 
330 static struct eth_driver rte_vmxnet3_pmd = {
331 	.pci_drv = {
332 		.name = "rte_vmxnet3_pmd",
333 		.id_table = pci_id_vmxnet3_map,
334 		.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
335 	},
336 	.eth_dev_init = eth_vmxnet3_dev_init,
337 	.eth_dev_uninit = eth_vmxnet3_dev_uninit,
338 	.dev_private_size = sizeof(struct vmxnet3_hw),
339 };
340 
341 /*
342  * Driver initialization routine.
343  * Invoked once at EAL init time.
344  * Register itself as the [Poll Mode] Driver of Virtual PCI VMXNET3 devices.
345  */
346 static int
347 rte_vmxnet3_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
348 {
349 	PMD_INIT_FUNC_TRACE();
350 
351 	rte_eth_driver_register(&rte_vmxnet3_pmd);
352 	return 0;
353 }
354 
355 static int
356 vmxnet3_dev_configure(struct rte_eth_dev *dev)
357 {
358 	const struct rte_memzone *mz;
359 	struct vmxnet3_hw *hw = dev->data->dev_private;
360 	size_t size;
361 
362 	PMD_INIT_FUNC_TRACE();
363 
364 	if (dev->data->nb_rx_queues > UINT8_MAX ||
365 	    dev->data->nb_tx_queues > UINT8_MAX)
366 		return -EINVAL;
367 
368 	size = dev->data->nb_rx_queues * sizeof(struct Vmxnet3_TxQueueDesc) +
369 		dev->data->nb_tx_queues * sizeof(struct Vmxnet3_RxQueueDesc);
370 
371 	if (size > UINT16_MAX)
372 		return -EINVAL;
373 
374 	hw->num_rx_queues = (uint8_t)dev->data->nb_rx_queues;
375 	hw->num_tx_queues = (uint8_t)dev->data->nb_tx_queues;
376 
377 	/*
378 	 * Allocate a memzone for Vmxnet3_DriverShared - Vmxnet3_DSDevRead
379 	 * on current socket
380 	 */
381 	mz = gpa_zone_reserve(dev, sizeof(struct Vmxnet3_DriverShared),
382 			      "shared", rte_socket_id(), 8);
383 
384 	if (mz == NULL) {
385 		PMD_INIT_LOG(ERR, "ERROR: Creating shared zone");
386 		return -ENOMEM;
387 	}
388 	memset(mz->addr, 0, mz->len);
389 
390 	hw->shared = mz->addr;
391 	hw->sharedPA = mz->phys_addr;
392 
393 	/*
394 	 * Allocate a memzone for Vmxnet3_RxQueueDesc - Vmxnet3_TxQueueDesc
395 	 * on current socket
396 	 */
397 	mz = gpa_zone_reserve(dev, size, "queuedesc",
398 			      rte_socket_id(), VMXNET3_QUEUE_DESC_ALIGN);
399 	if (mz == NULL) {
400 		PMD_INIT_LOG(ERR, "ERROR: Creating queue descriptors zone");
401 		return -ENOMEM;
402 	}
403 	memset(mz->addr, 0, mz->len);
404 
405 	hw->tqd_start = (Vmxnet3_TxQueueDesc *)mz->addr;
406 	hw->rqd_start = (Vmxnet3_RxQueueDesc *)(hw->tqd_start + hw->num_tx_queues);
407 
408 	hw->queueDescPA = mz->phys_addr;
409 	hw->queue_desc_len = (uint16_t)size;
410 
411 	if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
412 
413 		/* Allocate memory structure for UPT1_RSSConf and configure */
414 		mz = gpa_zone_reserve(dev, sizeof(struct VMXNET3_RSSConf), "rss_conf",
415 				      rte_socket_id(), RTE_CACHE_LINE_SIZE);
416 		if (mz == NULL) {
417 			PMD_INIT_LOG(ERR,
418 				     "ERROR: Creating rss_conf structure zone");
419 			return -ENOMEM;
420 		}
421 		memset(mz->addr, 0, mz->len);
422 
423 		hw->rss_conf = mz->addr;
424 		hw->rss_confPA = mz->phys_addr;
425 	}
426 
427 	return 0;
428 }
429 
430 static void
431 vmxnet3_write_mac(struct vmxnet3_hw *hw, const uint8_t *addr)
432 {
433 	uint32_t val;
434 
435 	PMD_INIT_LOG(DEBUG,
436 		     "Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
437 		     addr[0], addr[1], addr[2],
438 		     addr[3], addr[4], addr[5]);
439 
440 	val = *(const uint32_t *)addr;
441 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_MACL, val);
442 
443 	val = (addr[5] << 8) | addr[4];
444 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_MACH, val);
445 }
446 
447 static int
448 vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
449 {
450 	struct rte_eth_conf port_conf = dev->data->dev_conf;
451 	struct vmxnet3_hw *hw = dev->data->dev_private;
452 	uint32_t mtu = dev->data->mtu;
453 	Vmxnet3_DriverShared *shared = hw->shared;
454 	Vmxnet3_DSDevRead *devRead = &shared->devRead;
455 	uint32_t i;
456 	int ret;
457 
458 	shared->magic = VMXNET3_REV1_MAGIC;
459 	devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
460 
461 	/* Setting up Guest OS information */
462 	devRead->misc.driverInfo.gos.gosBits   = sizeof(void *) == 4 ?
463 		VMXNET3_GOS_BITS_32 :
464 		VMXNET3_GOS_BITS_64;
465 	devRead->misc.driverInfo.gos.gosType   = VMXNET3_GOS_TYPE_LINUX;
466 	devRead->misc.driverInfo.vmxnet3RevSpt = 1;
467 	devRead->misc.driverInfo.uptVerSpt     = 1;
468 
469 	devRead->misc.mtu = rte_le_to_cpu_32(mtu);
470 	devRead->misc.queueDescPA  = hw->queueDescPA;
471 	devRead->misc.queueDescLen = hw->queue_desc_len;
472 	devRead->misc.numTxQueues  = hw->num_tx_queues;
473 	devRead->misc.numRxQueues  = hw->num_rx_queues;
474 
475 	/*
476 	 * Set number of interrupts to 1
477 	 * PMD disables all the interrupts but this is MUST to activate device
478 	 * It needs at least one interrupt for link events to handle
479 	 * So we'll disable it later after device activation if needed
480 	 */
481 	devRead->intrConf.numIntrs = 1;
482 	devRead->intrConf.intrCtrl |= VMXNET3_IC_DISABLE_ALL;
483 
484 	for (i = 0; i < hw->num_tx_queues; i++) {
485 		Vmxnet3_TxQueueDesc *tqd = &hw->tqd_start[i];
486 		vmxnet3_tx_queue_t *txq  = dev->data->tx_queues[i];
487 
488 		tqd->ctrl.txNumDeferred  = 0;
489 		tqd->ctrl.txThreshold    = 1;
490 		tqd->conf.txRingBasePA   = txq->cmd_ring.basePA;
491 		tqd->conf.compRingBasePA = txq->comp_ring.basePA;
492 		tqd->conf.dataRingBasePA = txq->data_ring.basePA;
493 
494 		tqd->conf.txRingSize   = txq->cmd_ring.size;
495 		tqd->conf.compRingSize = txq->comp_ring.size;
496 		tqd->conf.dataRingSize = txq->data_ring.size;
497 		tqd->conf.intrIdx      = txq->comp_ring.intr_idx;
498 		tqd->status.stopped    = TRUE;
499 		tqd->status.error      = 0;
500 		memset(&tqd->stats, 0, sizeof(tqd->stats));
501 	}
502 
503 	for (i = 0; i < hw->num_rx_queues; i++) {
504 		Vmxnet3_RxQueueDesc *rqd  = &hw->rqd_start[i];
505 		vmxnet3_rx_queue_t *rxq   = dev->data->rx_queues[i];
506 
507 		rqd->conf.rxRingBasePA[0] = rxq->cmd_ring[0].basePA;
508 		rqd->conf.rxRingBasePA[1] = rxq->cmd_ring[1].basePA;
509 		rqd->conf.compRingBasePA  = rxq->comp_ring.basePA;
510 
511 		rqd->conf.rxRingSize[0]   = rxq->cmd_ring[0].size;
512 		rqd->conf.rxRingSize[1]   = rxq->cmd_ring[1].size;
513 		rqd->conf.compRingSize    = rxq->comp_ring.size;
514 		rqd->conf.intrIdx         = rxq->comp_ring.intr_idx;
515 		rqd->status.stopped       = TRUE;
516 		rqd->status.error         = 0;
517 		memset(&rqd->stats, 0, sizeof(rqd->stats));
518 	}
519 
520 	/* RxMode set to 0 of VMXNET3_RXM_xxx */
521 	devRead->rxFilterConf.rxMode = 0;
522 
523 	/* Setting up feature flags */
524 	if (dev->data->dev_conf.rxmode.hw_ip_checksum)
525 		devRead->misc.uptFeatures |= VMXNET3_F_RXCSUM;
526 
527 	if (port_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
528 		ret = vmxnet3_rss_configure(dev);
529 		if (ret != VMXNET3_SUCCESS)
530 			return ret;
531 
532 		devRead->misc.uptFeatures |= VMXNET3_F_RSS;
533 		devRead->rssConfDesc.confVer = 1;
534 		devRead->rssConfDesc.confLen = sizeof(struct VMXNET3_RSSConf);
535 		devRead->rssConfDesc.confPA  = hw->rss_confPA;
536 	}
537 
538 	vmxnet3_dev_vlan_offload_set(dev,
539 			     ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK);
540 
541 	vmxnet3_write_mac(hw, hw->perm_addr);
542 
543 	return VMXNET3_SUCCESS;
544 }
545 
546 /*
547  * Configure device link speed and setup link.
548  * Must be called after eth_vmxnet3_dev_init. Other wise it might fail
549  * It returns 0 on success.
550  */
551 static int
552 vmxnet3_dev_start(struct rte_eth_dev *dev)
553 {
554 	int status, ret;
555 	struct vmxnet3_hw *hw = dev->data->dev_private;
556 
557 	PMD_INIT_FUNC_TRACE();
558 
559 	ret = vmxnet3_setup_driver_shared(dev);
560 	if (ret != VMXNET3_SUCCESS)
561 		return ret;
562 
563 	/* Exchange shared data with device */
564 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAL,
565 			       VMXNET3_GET_ADDR_LO(hw->sharedPA));
566 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAH,
567 			       VMXNET3_GET_ADDR_HI(hw->sharedPA));
568 
569 	/* Activate device by register write */
570 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
571 	status = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
572 
573 	if (status != 0) {
574 		PMD_INIT_LOG(ERR, "Device activation: UNSUCCESSFUL");
575 		return -1;
576 	}
577 
578 	/* Disable interrupts */
579 	vmxnet3_disable_intr(hw);
580 
581 	/*
582 	 * Load RX queues with blank mbufs and update next2fill index for device
583 	 * Update RxMode of the device
584 	 */
585 	ret = vmxnet3_dev_rxtx_init(dev);
586 	if (ret != VMXNET3_SUCCESS) {
587 		PMD_INIT_LOG(ERR, "Device receive init: UNSUCCESSFUL");
588 		return ret;
589 	}
590 
591 	/* Setting proper Rx Mode and issue Rx Mode Update command */
592 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_UCAST | VMXNET3_RXM_BCAST, 1);
593 
594 	/*
595 	 * Don't need to handle events for now
596 	 */
597 #if PROCESS_SYS_EVENTS == 1
598 	events = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_ECR);
599 	PMD_INIT_LOG(DEBUG, "Reading events: 0x%X", events);
600 	vmxnet3_process_events(hw);
601 #endif
602 	return status;
603 }
604 
605 /*
606  * Stop device: disable rx and tx functions to allow for reconfiguring.
607  */
608 static void
609 vmxnet3_dev_stop(struct rte_eth_dev *dev)
610 {
611 	struct rte_eth_link link;
612 	struct vmxnet3_hw *hw = dev->data->dev_private;
613 
614 	PMD_INIT_FUNC_TRACE();
615 
616 	if (hw->adapter_stopped == 1) {
617 		PMD_INIT_LOG(DEBUG, "Device already closed.");
618 		return;
619 	}
620 
621 	/* disable interrupts */
622 	vmxnet3_disable_intr(hw);
623 
624 	/* quiesce the device first */
625 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
626 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAL, 0);
627 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAH, 0);
628 
629 	/* reset the device */
630 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
631 	PMD_INIT_LOG(DEBUG, "Device reset.");
632 	hw->adapter_stopped = 0;
633 
634 	vmxnet3_dev_clear_queues(dev);
635 
636 	/* Clear recorded link status */
637 	memset(&link, 0, sizeof(link));
638 	vmxnet3_dev_atomic_write_link_status(dev, &link);
639 }
640 
641 /*
642  * Reset and stop device.
643  */
644 static void
645 vmxnet3_dev_close(struct rte_eth_dev *dev)
646 {
647 	struct vmxnet3_hw *hw = dev->data->dev_private;
648 
649 	PMD_INIT_FUNC_TRACE();
650 
651 	vmxnet3_dev_stop(dev);
652 	hw->adapter_stopped = 1;
653 }
654 
655 static void
656 vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
657 {
658 	unsigned int i;
659 	struct vmxnet3_hw *hw = dev->data->dev_private;
660 
661 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
662 
663 	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_TX_QUEUES);
664 	for (i = 0; i < hw->num_tx_queues; i++) {
665 		struct UPT1_TxStats *txStats = &hw->tqd_start[i].stats;
666 
667 		stats->q_opackets[i] = txStats->ucastPktsTxOK +
668 			txStats->mcastPktsTxOK +
669 			txStats->bcastPktsTxOK;
670 		stats->q_obytes[i] = txStats->ucastBytesTxOK +
671 			txStats->mcastBytesTxOK +
672 			txStats->bcastBytesTxOK;
673 
674 		stats->opackets += stats->q_opackets[i];
675 		stats->obytes += stats->q_obytes[i];
676 		stats->oerrors += txStats->pktsTxError +
677 			txStats->pktsTxDiscard;
678 	}
679 
680 	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_RX_QUEUES);
681 	for (i = 0; i < hw->num_rx_queues; i++) {
682 		struct UPT1_RxStats *rxStats = &hw->rqd_start[i].stats;
683 
684 		stats->q_ipackets[i] = rxStats->ucastPktsRxOK +
685 			rxStats->mcastPktsRxOK +
686 			rxStats->bcastPktsRxOK;
687 
688 		stats->q_ibytes[i] = rxStats->ucastBytesRxOK +
689 			rxStats->mcastBytesRxOK +
690 			rxStats->bcastBytesRxOK;
691 
692 		stats->ipackets += stats->q_ipackets[i];
693 		stats->ibytes += stats->q_ibytes[i];
694 
695 		stats->q_errors[i] = rxStats->pktsRxError;
696 		stats->ierrors += rxStats->pktsRxError;
697 		stats->imcasts += rxStats->mcastPktsRxOK;
698 		stats->rx_nombuf += rxStats->pktsRxOutOfBuf;
699 	}
700 }
701 
702 static void
703 vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev,
704 		     struct rte_eth_dev_info *dev_info)
705 {
706 	dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
707 	dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
708 	dev_info->min_rx_bufsize = 1518 + RTE_PKTMBUF_HEADROOM;
709 	dev_info->max_rx_pktlen = 16384; /* includes CRC, cf MAXFRS register */
710 	dev_info->max_mac_addrs = VMXNET3_MAX_MAC_ADDRS;
711 
712 	dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
713 	dev_info->flow_type_rss_offloads = VMXNET3_RSS_OFFLOAD_ALL;
714 
715 	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
716 		.nb_max = VMXNET3_RX_RING_MAX_SIZE,
717 		.nb_min = VMXNET3_DEF_RX_RING_SIZE,
718 		.nb_align = 1,
719 	};
720 
721 	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
722 		.nb_max = VMXNET3_TX_RING_MAX_SIZE,
723 		.nb_min = VMXNET3_DEF_TX_RING_SIZE,
724 		.nb_align = 1,
725 	};
726 
727 	dev_info->rx_offload_capa =
728 		DEV_RX_OFFLOAD_VLAN_STRIP |
729 		DEV_RX_OFFLOAD_UDP_CKSUM |
730 		DEV_RX_OFFLOAD_TCP_CKSUM;
731 
732 	dev_info->tx_offload_capa =
733 		DEV_TX_OFFLOAD_VLAN_INSERT |
734 		DEV_TX_OFFLOAD_TCP_CKSUM |
735 		DEV_TX_OFFLOAD_UDP_CKSUM |
736 		DEV_TX_OFFLOAD_TCP_TSO;
737 }
738 
739 static const uint32_t *
740 vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
741 {
742 	static const uint32_t ptypes[] = {
743 		RTE_PTYPE_L3_IPV4_EXT,
744 		RTE_PTYPE_L3_IPV4,
745 		RTE_PTYPE_UNKNOWN
746 	};
747 
748 	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
749 		return ptypes;
750 	return NULL;
751 }
752 
753 static void
754 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
755 {
756 	struct vmxnet3_hw *hw = dev->data->dev_private;
757 
758 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
759 }
760 
761 /* return 0 means link status changed, -1 means not changed */
762 static int
763 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
764 {
765 	struct vmxnet3_hw *hw = dev->data->dev_private;
766 	struct rte_eth_link old, link;
767 	uint32_t ret;
768 
769 	if (dev->data->dev_started == 0)
770 		return -1; /* Link status doesn't change for stopped dev */
771 
772 	memset(&link, 0, sizeof(link));
773 	vmxnet3_dev_atomic_read_link_status(dev, &old);
774 
775 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
776 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
777 
778 	if (ret & 0x1) {
779 		link.link_status = 1;
780 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
781 		link.link_speed = ETH_LINK_SPEED_10000;
782 	}
783 
784 	vmxnet3_dev_atomic_write_link_status(dev, &link);
785 
786 	return (old.link_status == link.link_status) ? -1 : 0;
787 }
788 
789 /* Updating rxmode through Vmxnet3_DriverShared structure in adapter */
790 static void
791 vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set) {
792 
793 	struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf;
794 
795 	if (set)
796 		rxConf->rxMode = rxConf->rxMode | feature;
797 	else
798 		rxConf->rxMode = rxConf->rxMode & (~feature);
799 
800 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_RX_MODE);
801 }
802 
803 /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
804 static void
805 vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
806 {
807 	struct vmxnet3_hw *hw = dev->data->dev_private;
808 	uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
809 
810 	memset(vf_table, 0, VMXNET3_VFT_TABLE_SIZE);
811 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 1);
812 
813 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
814 			       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
815 }
816 
817 /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
818 static void
819 vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
820 {
821 	struct vmxnet3_hw *hw = dev->data->dev_private;
822 	uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
823 
824 	memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE);
825 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0);
826 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
827 			       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
828 }
829 
830 /* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */
831 static void
832 vmxnet3_dev_allmulticast_enable(struct rte_eth_dev *dev)
833 {
834 	struct vmxnet3_hw *hw = dev->data->dev_private;
835 
836 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 1);
837 }
838 
839 /* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */
840 static void
841 vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev)
842 {
843 	struct vmxnet3_hw *hw = dev->data->dev_private;
844 
845 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 0);
846 }
847 
848 /* Enable/disable filter on vlan */
849 static int
850 vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on)
851 {
852 	struct vmxnet3_hw *hw = dev->data->dev_private;
853 	struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf;
854 	uint32_t *vf_table = rxConf->vfTable;
855 
856 	/* save state for restore */
857 	if (on)
858 		VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, vid);
859 	else
860 		VMXNET3_CLEAR_VFTABLE_ENTRY(hw->shadow_vfta, vid);
861 
862 	/* don't change active filter if in promiscuous mode */
863 	if (rxConf->rxMode & VMXNET3_RXM_PROMISC)
864 		return 0;
865 
866 	/* set in hardware */
867 	if (on)
868 		VMXNET3_SET_VFTABLE_ENTRY(vf_table, vid);
869 	else
870 		VMXNET3_CLEAR_VFTABLE_ENTRY(vf_table, vid);
871 
872 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
873 			       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
874 	return 0;
875 }
876 
877 static void
878 vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
879 {
880 	struct vmxnet3_hw *hw = dev->data->dev_private;
881 	Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
882 	uint32_t *vf_table = devRead->rxFilterConf.vfTable;
883 
884 	if (mask & ETH_VLAN_STRIP_MASK) {
885 		if (dev->data->dev_conf.rxmode.hw_vlan_strip)
886 			devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
887 		else
888 			devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
889 
890 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
891 				       VMXNET3_CMD_UPDATE_FEATURE);
892 	}
893 
894 	if (mask & ETH_VLAN_FILTER_MASK) {
895 		if (dev->data->dev_conf.rxmode.hw_vlan_filter)
896 			memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE);
897 		else
898 			memset(vf_table, 0xff, VMXNET3_VFT_TABLE_SIZE);
899 
900 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
901 				       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
902 	}
903 }
904 
905 #if PROCESS_SYS_EVENTS == 1
906 static void
907 vmxnet3_process_events(struct vmxnet3_hw *hw)
908 {
909 	uint32_t events = hw->shared->ecr;
910 
911 	if (!events) {
912 		PMD_INIT_LOG(ERR, "No events to process");
913 		return;
914 	}
915 
916 	/*
917 	 * ECR bits when written with 1b are cleared. Hence write
918 	 * events back to ECR so that the bits which were set will be reset.
919 	 */
920 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_ECR, events);
921 
922 	/* Check if link state has changed */
923 	if (events & VMXNET3_ECR_LINK)
924 		PMD_INIT_LOG(ERR,
925 			     "Process events in %s(): VMXNET3_ECR_LINK event", __func__);
926 
927 	/* Check if there is an error on xmit/recv queues */
928 	if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) {
929 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_QUEUE_STATUS);
930 
931 		if (hw->tqd_start->status.stopped)
932 			PMD_INIT_LOG(ERR, "tq error 0x%x",
933 				     hw->tqd_start->status.error);
934 
935 		if (hw->rqd_start->status.stopped)
936 			PMD_INIT_LOG(ERR, "rq error 0x%x",
937 				     hw->rqd_start->status.error);
938 
939 		/* Reset the device */
940 		/* Have to reset the device */
941 	}
942 
943 	if (events & VMXNET3_ECR_DIC)
944 		PMD_INIT_LOG(ERR, "Device implementation change event.");
945 
946 	if (events & VMXNET3_ECR_DEBUG)
947 		PMD_INIT_LOG(ERR, "Debug event generated by device.");
948 
949 }
950 #endif
951 
952 static struct rte_driver rte_vmxnet3_driver = {
953 	.type = PMD_PDEV,
954 	.init = rte_vmxnet3_pmd_init,
955 };
956 
957 PMD_REGISTER_DRIVER(rte_vmxnet3_driver);
958