2 * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
32 #include <ipxe/malloc.h>
33 #include <ipxe/profile.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/netdevice.h>
36 #include <ipxe/if_ether.h>
37 #include <ipxe/ethernet.h>
43 * VMware vmxnet3 virtual NIC driver
47 /** VM command profiler */
48 static struct profiler vmxnet3_vm_command_profiler __profiler =
49 { .name = "vmxnet3.vm_command" };
51 /** VM transmit profiler */
52 static struct profiler vmxnet3_vm_tx_profiler __profiler =
53 { .name = "vmxnet3.vm_tx" };
55 /** VM receive refill profiler */
56 static struct profiler vmxnet3_vm_refill_profiler __profiler =
57 { .name = "vmxnet3.vm_refill" };
59 /** VM event profiler */
60 static struct profiler vmxnet3_vm_event_profiler __profiler =
61 { .name = "vmxnet3.vm_event" };
66 * @v vmxnet vmxnet3 NIC
67 * @v command Command to issue
68 * @ret result Command result
70 static inline uint32_t vmxnet3_command ( struct vmxnet3_nic *vmxnet,
75 profile_start ( &vmxnet3_vm_command_profiler );
76 writel ( command, ( vmxnet->vd + VMXNET3_VD_CMD ) );
77 result = readl ( vmxnet->vd + VMXNET3_VD_CMD );
78 profile_stop ( &vmxnet3_vm_command_profiler );
79 profile_exclude ( &vmxnet3_vm_command_profiler );
87 * @v netdev Network device
89 * @ret rc Return status code
91 static int vmxnet3_transmit ( struct net_device *netdev,
92 struct io_buffer *iobuf ) {
93 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
94 struct vmxnet3_tx_desc *tx_desc;
95 unsigned int desc_idx;
96 unsigned int generation;
98 /* Check that we have a free transmit descriptor */
99 desc_idx = ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC );
100 generation = ( ( vmxnet->count.tx_prod & VMXNET3_NUM_TX_DESC ) ?
101 0 : cpu_to_le32 ( VMXNET3_TXF_GEN ) );
102 if ( vmxnet->tx_iobuf[desc_idx] ) {
103 DBGC ( vmxnet, "VMXNET3 %p out of transmit descriptors\n",
108 /* Increment producer counter */
109 vmxnet->count.tx_prod++;
111 /* Store I/O buffer for later completion */
112 vmxnet->tx_iobuf[desc_idx] = iobuf;
114 /* Populate transmit descriptor */
115 tx_desc = &vmxnet->dma->tx_desc[desc_idx];
116 tx_desc->address = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
117 tx_desc->flags[0] = ( generation | cpu_to_le32 ( iob_len ( iobuf ) ) );
118 tx_desc->flags[1] = cpu_to_le32 ( VMXNET3_TXF_CQ | VMXNET3_TXF_EOP );
120 /* Hand over descriptor to NIC */
122 profile_start ( &vmxnet3_vm_tx_profiler );
123 writel ( ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC ),
124 ( vmxnet->pt + VMXNET3_PT_TXPROD ) );
125 profile_stop ( &vmxnet3_vm_tx_profiler );
126 profile_exclude ( &vmxnet3_vm_tx_profiler );
132 * Poll for completed transmissions
134 * @v netdev Network device
136 static void vmxnet3_poll_tx ( struct net_device *netdev ) {
137 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
138 struct vmxnet3_tx_comp *tx_comp;
139 struct io_buffer *iobuf;
140 unsigned int comp_idx;
141 unsigned int desc_idx;
142 unsigned int generation;
146 /* Look for completed descriptors */
147 comp_idx = ( vmxnet->count.tx_cons % VMXNET3_NUM_TX_COMP );
148 generation = ( ( vmxnet->count.tx_cons & VMXNET3_NUM_TX_COMP ) ?
149 0 : cpu_to_le32 ( VMXNET3_TXCF_GEN ) );
150 tx_comp = &vmxnet->dma->tx_comp[comp_idx];
151 if ( generation != ( tx_comp->flags &
152 cpu_to_le32 ( VMXNET3_TXCF_GEN ) ) ) {
156 /* Increment consumer counter */
157 vmxnet->count.tx_cons++;
159 /* Locate corresponding transmit descriptor */
160 desc_idx = ( le32_to_cpu ( tx_comp->index ) %
161 VMXNET3_NUM_TX_DESC );
162 iobuf = vmxnet->tx_iobuf[desc_idx];
164 DBGC ( vmxnet, "VMXNET3 %p completed on empty transmit "
165 "buffer %#x/%#x\n", vmxnet, comp_idx, desc_idx );
166 netdev_tx_err ( netdev, NULL, -ENOTTY );
170 /* Remove I/O buffer from transmit queue */
171 vmxnet->tx_iobuf[desc_idx] = NULL;
173 /* Report transmission completion to network layer */
174 DBGC2 ( vmxnet, "VMXNET3 %p completed TX %#x/%#x (len %#zx)\n",
175 vmxnet, comp_idx, desc_idx, iob_len ( iobuf ) );
176 netdev_tx_complete ( netdev, iobuf );
181 * Flush any uncompleted transmit buffers
183 * @v netdev Network device
185 static void vmxnet3_flush_tx ( struct net_device *netdev ) {
186 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
189 for ( i = 0 ; i < VMXNET3_NUM_TX_DESC ; i++ ) {
190 if ( vmxnet->tx_iobuf[i] ) {
191 netdev_tx_complete_err ( netdev, vmxnet->tx_iobuf[i],
193 vmxnet->tx_iobuf[i] = NULL;
199 * Refill receive ring
201 * @v netdev Network device
203 static void vmxnet3_refill_rx ( struct net_device *netdev ) {
204 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
205 struct vmxnet3_rx_desc *rx_desc;
206 struct io_buffer *iobuf;
207 unsigned int orig_rx_prod = vmxnet->count.rx_prod;
208 unsigned int desc_idx;
209 unsigned int generation;
211 /* Fill receive ring to specified fill level */
212 while ( vmxnet->count.rx_fill < VMXNET3_RX_FILL ) {
214 /* Locate receive descriptor */
215 desc_idx = ( vmxnet->count.rx_prod % VMXNET3_NUM_RX_DESC );
216 generation = ( ( vmxnet->count.rx_prod & VMXNET3_NUM_RX_DESC ) ?
217 0 : cpu_to_le32 ( VMXNET3_RXF_GEN ) );
218 assert ( vmxnet->rx_iobuf[desc_idx] == NULL );
220 /* Allocate I/O buffer */
221 iobuf = alloc_iob ( VMXNET3_MTU + NET_IP_ALIGN );
223 /* Non-fatal low memory condition */
226 iob_reserve ( iobuf, NET_IP_ALIGN );
228 /* Increment producer counter and fill level */
229 vmxnet->count.rx_prod++;
230 vmxnet->count.rx_fill++;
232 /* Store I/O buffer for later completion */
233 vmxnet->rx_iobuf[desc_idx] = iobuf;
235 /* Populate receive descriptor */
236 rx_desc = &vmxnet->dma->rx_desc[desc_idx];
237 rx_desc->address = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
238 rx_desc->flags = ( generation | cpu_to_le32 ( VMXNET3_MTU ) );
242 /* Hand over any new descriptors to NIC */
243 if ( vmxnet->count.rx_prod != orig_rx_prod ) {
245 profile_start ( &vmxnet3_vm_refill_profiler );
246 writel ( ( vmxnet->count.rx_prod % VMXNET3_NUM_RX_DESC ),
247 ( vmxnet->pt + VMXNET3_PT_RXPROD ) );
248 profile_stop ( &vmxnet3_vm_refill_profiler );
249 profile_exclude ( &vmxnet3_vm_refill_profiler );
254 * Poll for received packets
256 * @v netdev Network device
258 static void vmxnet3_poll_rx ( struct net_device *netdev ) {
259 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
260 struct vmxnet3_rx_comp *rx_comp;
261 struct io_buffer *iobuf;
262 unsigned int comp_idx;
263 unsigned int desc_idx;
264 unsigned int generation;
269 /* Look for completed descriptors */
270 comp_idx = ( vmxnet->count.rx_cons % VMXNET3_NUM_RX_COMP );
271 generation = ( ( vmxnet->count.rx_cons & VMXNET3_NUM_RX_COMP ) ?
272 0 : cpu_to_le32 ( VMXNET3_RXCF_GEN ) );
273 rx_comp = &vmxnet->dma->rx_comp[comp_idx];
274 if ( generation != ( rx_comp->flags &
275 cpu_to_le32 ( VMXNET3_RXCF_GEN ) ) ) {
279 /* Increment consumer counter */
280 vmxnet->count.rx_cons++;
282 /* Locate corresponding receive descriptor */
283 desc_idx = ( le32_to_cpu ( rx_comp->index ) %
284 VMXNET3_NUM_RX_DESC );
285 iobuf = vmxnet->rx_iobuf[desc_idx];
287 DBGC ( vmxnet, "VMXNET3 %p completed on empty receive "
288 "buffer %#x/%#x\n", vmxnet, comp_idx, desc_idx );
289 netdev_rx_err ( netdev, NULL, -ENOTTY );
293 /* Remove I/O buffer from receive queue */
294 vmxnet->rx_iobuf[desc_idx] = NULL;
295 vmxnet->count.rx_fill--;
297 /* Deliver packet to network layer */
298 len = ( le32_to_cpu ( rx_comp->len ) &
299 ( VMXNET3_MAX_PACKET_LEN - 1 ) );
300 DBGC2 ( vmxnet, "VMXNET3 %p completed RX %#x/%#x (len %#zx)\n",
301 vmxnet, comp_idx, desc_idx, len );
302 iob_put ( iobuf, len );
303 netdev_rx ( netdev, iobuf );
308 * Flush any uncompleted receive buffers
310 * @v netdev Network device
312 static void vmxnet3_flush_rx ( struct net_device *netdev ) {
313 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
314 struct io_buffer *iobuf;
317 for ( i = 0 ; i < VMXNET3_NUM_RX_DESC ; i++ ) {
318 if ( ( iobuf = vmxnet->rx_iobuf[i] ) != NULL ) {
319 netdev_rx_err ( netdev, iobuf, -ECANCELED );
320 vmxnet->rx_iobuf[i] = NULL;
328 * @v netdev Network device
330 static void vmxnet3_check_link ( struct net_device *netdev ) {
331 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
334 unsigned int link_speed;
337 state = vmxnet3_command ( vmxnet, VMXNET3_CMD_GET_LINK );
338 link_up = ( state & 1 );
339 link_speed = ( state >> 16 );
341 /* Report link state to network device */
343 DBGC ( vmxnet, "VMXNET3 %p link is up at %d Mbps\n",
344 vmxnet, link_speed );
345 netdev_link_up ( netdev );
347 DBGC ( vmxnet, "VMXNET3 %p link is down\n", vmxnet );
348 netdev_link_down ( netdev );
355 * @v netdev Network device
357 static void vmxnet3_poll_events ( struct net_device *netdev ) {
358 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
361 /* Do nothing unless there are events to process */
362 if ( ! vmxnet->dma->shared.ecr )
364 events = le32_to_cpu ( vmxnet->dma->shared.ecr );
366 /* Acknowledge these events */
367 profile_start ( &vmxnet3_vm_event_profiler );
368 writel ( events, ( vmxnet->vd + VMXNET3_VD_ECR ) );
369 profile_stop ( &vmxnet3_vm_event_profiler );
370 profile_exclude ( &vmxnet3_vm_event_profiler );
372 /* Check for link state change */
373 if ( events & VMXNET3_ECR_LINK ) {
374 vmxnet3_check_link ( netdev );
375 events &= ~VMXNET3_ECR_LINK;
378 /* Check for queue errors */
379 if ( events & ( VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR ) ) {
380 vmxnet3_command ( vmxnet, VMXNET3_CMD_GET_QUEUE_STATUS );
381 DBGC ( vmxnet, "VMXNET3 %p queue error status (TX %08x, RX "
383 le32_to_cpu ( vmxnet->dma->queues.tx.status.error ),
384 le32_to_cpu ( vmxnet->dma->queues.rx.status.error ) );
385 /* Report errors to allow for visibility via "ifstat" */
386 if ( events & VMXNET3_ECR_TQERR )
387 netdev_tx_err ( netdev, NULL, -EPIPE );
388 if ( events & VMXNET3_ECR_RQERR )
389 netdev_rx_err ( netdev, NULL, -EPIPE );
390 events &= ~( VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR );
393 /* Check for unknown events */
395 DBGC ( vmxnet, "VMXNET3 %p unknown events %08x\n",
397 /* Report error to allow for visibility via "ifstat" */
398 netdev_rx_err ( netdev, NULL, -ENODEV );
403 * Poll network device
405 * @v netdev Network device
407 static void vmxnet3_poll ( struct net_device *netdev ) {
409 vmxnet3_poll_events ( netdev );
410 vmxnet3_poll_tx ( netdev );
411 vmxnet3_poll_rx ( netdev );
412 vmxnet3_refill_rx ( netdev );
416 * Enable/disable interrupts
418 * @v netdev Network device
419 * @v enable Interrupts should be enabled
421 static void vmxnet3_irq ( struct net_device *netdev, int enable ) {
422 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
424 DBGC ( vmxnet, "VMXNET3 %p %s IRQ not implemented\n",
425 vmxnet, ( enable ? "enable" : "disable" ) );
431 * @v vmxnet vmxnet3 NIC
432 * @v ll_addr Link-layer address to set
434 static void vmxnet3_set_ll_addr ( struct vmxnet3_nic *vmxnet,
435 const void *ll_addr ) {
439 } __attribute__ (( packed )) mac;
441 memset ( &mac, 0, sizeof ( mac ) );
442 memcpy ( &mac, ll_addr, ETH_ALEN );
443 writel ( cpu_to_le32 ( mac.low ), ( vmxnet->vd + VMXNET3_VD_MACL ) );
444 writel ( cpu_to_le32 ( mac.high ), ( vmxnet->vd + VMXNET3_VD_MACH ) );
450 * @v netdev Network device
451 * @ret rc Return status code
453 static int vmxnet3_open ( struct net_device *netdev ) {
454 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
455 struct vmxnet3_shared *shared;
456 struct vmxnet3_queues *queues;
462 /* Allocate DMA areas */
463 vmxnet->dma = malloc_dma ( sizeof ( *vmxnet->dma ), VMXNET3_DMA_ALIGN );
464 if ( ! vmxnet->dma ) {
465 DBGC ( vmxnet, "VMXNET3 %p could not allocate DMA area\n",
470 memset ( vmxnet->dma, 0, sizeof ( *vmxnet->dma ) );
472 /* Populate queue descriptors */
473 queues = &vmxnet->dma->queues;
474 queues->tx.cfg.desc_address =
475 cpu_to_le64 ( virt_to_bus ( &vmxnet->dma->tx_desc ) );
476 queues->tx.cfg.comp_address =
477 cpu_to_le64 ( virt_to_bus ( &vmxnet->dma->tx_comp ) );
478 queues->tx.cfg.num_desc = cpu_to_le32 ( VMXNET3_NUM_TX_DESC );
479 queues->tx.cfg.num_comp = cpu_to_le32 ( VMXNET3_NUM_TX_COMP );
480 queues->rx.cfg.desc_address[0] =
481 cpu_to_le64 ( virt_to_bus ( &vmxnet->dma->rx_desc ) );
482 queues->rx.cfg.comp_address =
483 cpu_to_le64 ( virt_to_bus ( &vmxnet->dma->rx_comp ) );
484 queues->rx.cfg.num_desc[0] = cpu_to_le32 ( VMXNET3_NUM_RX_DESC );
485 queues->rx.cfg.num_comp = cpu_to_le32 ( VMXNET3_NUM_RX_COMP );
486 queues_bus = virt_to_bus ( queues );
487 DBGC ( vmxnet, "VMXNET3 %p queue descriptors at %08llx+%zx\n",
488 vmxnet, queues_bus, sizeof ( *queues ) );
490 /* Populate shared area */
491 shared = &vmxnet->dma->shared;
492 shared->magic = cpu_to_le32 ( VMXNET3_SHARED_MAGIC );
493 shared->misc.version = cpu_to_le32 ( VMXNET3_VERSION_MAGIC );
494 shared->misc.version_support = cpu_to_le32 ( VMXNET3_VERSION_SELECT );
495 shared->misc.upt_version_support =
496 cpu_to_le32 ( VMXNET3_UPT_VERSION_SELECT );
497 shared->misc.queue_desc_address = cpu_to_le64 ( queues_bus );
498 shared->misc.queue_desc_len = cpu_to_le32 ( sizeof ( *queues ) );
499 shared->misc.mtu = cpu_to_le32 ( VMXNET3_MTU );
500 shared->misc.num_tx_queues = 1;
501 shared->misc.num_rx_queues = 1;
502 shared->interrupt.num_intrs = 1;
503 shared->interrupt.control = cpu_to_le32 ( VMXNET3_IC_DISABLE_ALL );
504 shared->rx_filter.mode = cpu_to_le32 ( VMXNET3_RXM_UCAST |
506 VMXNET3_RXM_ALL_MULTI );
507 shared_bus = virt_to_bus ( shared );
508 DBGC ( vmxnet, "VMXNET3 %p shared area at %08llx+%zx\n",
509 vmxnet, shared_bus, sizeof ( *shared ) );
512 memset ( &vmxnet->count, 0, sizeof ( vmxnet->count ) );
514 /* Set MAC address */
515 vmxnet3_set_ll_addr ( vmxnet, &netdev->ll_addr );
517 /* Pass shared area to device */
518 writel ( ( shared_bus >> 0 ), ( vmxnet->vd + VMXNET3_VD_DSAL ) );
519 writel ( ( shared_bus >> 32 ), ( vmxnet->vd + VMXNET3_VD_DSAH ) );
521 /* Activate device */
522 if ( ( status = vmxnet3_command ( vmxnet,
523 VMXNET3_CMD_ACTIVATE_DEV ) ) != 0 ) {
524 DBGC ( vmxnet, "VMXNET3 %p could not activate (status %#x)\n",
530 /* Fill receive ring */
531 vmxnet3_refill_rx ( netdev );
535 vmxnet3_command ( vmxnet, VMXNET3_CMD_QUIESCE_DEV );
536 vmxnet3_command ( vmxnet, VMXNET3_CMD_RESET_DEV );
538 vmxnet3_flush_tx ( netdev );
539 vmxnet3_flush_rx ( netdev );
540 free_dma ( vmxnet->dma, sizeof ( *vmxnet->dma ) );
548 * @v netdev Network device
550 static void vmxnet3_close ( struct net_device *netdev ) {
551 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
553 vmxnet3_command ( vmxnet, VMXNET3_CMD_QUIESCE_DEV );
554 vmxnet3_command ( vmxnet, VMXNET3_CMD_RESET_DEV );
555 vmxnet3_flush_tx ( netdev );
556 vmxnet3_flush_rx ( netdev );
557 free_dma ( vmxnet->dma, sizeof ( *vmxnet->dma ) );
560 /** vmxnet3 net device operations */
561 static struct net_device_operations vmxnet3_operations = {
562 .open = vmxnet3_open,
563 .close = vmxnet3_close,
564 .transmit = vmxnet3_transmit,
565 .poll = vmxnet3_poll,
572 * @v vmxnet vmxnet3 NIC
573 * @ret rc Return status code
575 static int vmxnet3_check_version ( struct vmxnet3_nic *vmxnet ) {
577 uint32_t upt_version;
580 version = readl ( vmxnet->vd + VMXNET3_VD_VRRS );
581 upt_version = readl ( vmxnet->vd + VMXNET3_VD_UVRS );
582 DBGC ( vmxnet, "VMXNET3 %p is version %d (UPT version %d)\n",
583 vmxnet, version, upt_version );
585 /* Inform NIC of driver version */
586 writel ( VMXNET3_VERSION_SELECT, ( vmxnet->vd + VMXNET3_VD_VRRS ) );
587 writel ( VMXNET3_UPT_VERSION_SELECT, ( vmxnet->vd + VMXNET3_VD_UVRS ) );
593 * Get permanent MAC address
595 * @v vmxnet vmxnet3 NIC
596 * @v hw_addr Hardware address to fill in
598 static void vmxnet3_get_hw_addr ( struct vmxnet3_nic *vmxnet, void *hw_addr ) {
602 } __attribute__ (( packed )) mac;
604 mac.low = le32_to_cpu ( vmxnet3_command ( vmxnet,
605 VMXNET3_CMD_GET_PERM_MAC_LO ) );
606 mac.high = le32_to_cpu ( vmxnet3_command ( vmxnet,
607 VMXNET3_CMD_GET_PERM_MAC_HI ) );
608 memcpy ( hw_addr, &mac, ETH_ALEN );
616 * @ret rc Return status code
618 static int vmxnet3_probe ( struct pci_device *pci ) {
619 struct net_device *netdev;
620 struct vmxnet3_nic *vmxnet;
623 /* Allocate network device */
624 netdev = alloc_etherdev ( sizeof ( *vmxnet ) );
627 goto err_alloc_etherdev;
629 netdev_init ( netdev, &vmxnet3_operations );
630 vmxnet = netdev_priv ( netdev );
631 pci_set_drvdata ( pci, netdev );
632 netdev->dev = &pci->dev;
633 memset ( vmxnet, 0, sizeof ( *vmxnet ) );
635 /* Fix up PCI device */
636 adjust_pci_device ( pci );
639 vmxnet->pt = ioremap ( pci_bar_start ( pci, VMXNET3_PT_BAR ),
641 if ( ! vmxnet->pt ) {
645 vmxnet->vd = ioremap ( pci_bar_start ( pci, VMXNET3_VD_BAR ),
647 if ( ! vmxnet->vd ) {
653 if ( ( rc = vmxnet3_check_version ( vmxnet ) ) != 0 )
654 goto err_check_version;
657 if ( ( rc = vmxnet3_command ( vmxnet, VMXNET3_CMD_RESET_DEV ) ) != 0 )
660 /* Read initial MAC address */
661 vmxnet3_get_hw_addr ( vmxnet, &netdev->hw_addr );
663 /* Register network device */
664 if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
665 DBGC ( vmxnet, "VMXNET3 %p could not register net device: "
666 "%s\n", vmxnet, strerror ( rc ) );
667 goto err_register_netdev;
670 /* Get initial link state */
671 vmxnet3_check_link ( netdev );
675 unregister_netdev ( netdev );
679 iounmap ( vmxnet->vd );
681 iounmap ( vmxnet->pt );
683 netdev_nullify ( netdev );
684 netdev_put ( netdev );
694 static void vmxnet3_remove ( struct pci_device *pci ) {
695 struct net_device *netdev = pci_get_drvdata ( pci );
696 struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
698 unregister_netdev ( netdev );
699 iounmap ( vmxnet->vd );
700 iounmap ( vmxnet->pt );
701 netdev_nullify ( netdev );
702 netdev_put ( netdev );
705 /** vmxnet3 PCI IDs */
706 static struct pci_device_id vmxnet3_nics[] = {
707 PCI_ROM ( 0x15ad, 0x07b0, "vmxnet3", "vmxnet3 virtual NIC", 0 ),
710 /** vmxnet3 PCI driver */
711 struct pci_driver vmxnet3_driver __pci_driver = {
713 .id_count = ( sizeof ( vmxnet3_nics ) / sizeof ( vmxnet3_nics[0] ) ),
714 .probe = vmxnet3_probe,
715 .remove = vmxnet3_remove,