2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <vppinfra/types.h>
17 #include <vlib/vlib.h>
18 #include <vlib/pci/pci.h>
19 #include <vnet/ethernet/ethernet.h>
20 #include <vnet/plugin/plugin.h>
21 #include <vpp/app/version.h>
22 #include <vnet/interface/rx_queue_funcs.h>
23 #include <vnet/interface/tx_queue_funcs.h>
24 #include <vmxnet3/vmxnet3.h>
26 #define PCI_VENDOR_ID_VMWARE 0x15ad
27 #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07b0
29 vmxnet3_main_t vmxnet3_main;
31 static pci_device_id_t vmxnet3_pci_device_ids[] = {
33 .vendor_id = PCI_VENDOR_ID_VMWARE,
34 .device_id = PCI_DEVICE_ID_VMWARE_VMXNET3},
39 vmxnet3_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
42 vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
43 vmxnet3_main_t *vmxm = &vmxnet3_main;
44 vmxnet3_device_t *vd = vec_elt_at_index (vmxm->devices, hi->dev_instance);
45 uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
47 if (vd->flags & VMXNET3_DEVICE_F_ERROR)
48 return clib_error_return (0, "device is in error state");
52 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
53 VNET_HW_INTERFACE_FLAG_LINK_UP);
54 vd->flags |= VMXNET3_DEVICE_F_ADMIN_UP;
58 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
59 vd->flags &= ~VMXNET3_DEVICE_F_ADMIN_UP;
65 vmxnet3_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid,
66 vnet_hw_if_rx_mode mode)
68 vmxnet3_main_t *vmxm = &vmxnet3_main;
69 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
70 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
71 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
72 vmxnet3_per_thread_data_t *ptd;
74 if (mode == rxq->mode)
76 if ((mode != VNET_HW_IF_RX_MODE_POLLING) &&
77 (mode != VNET_HW_IF_RX_MODE_INTERRUPT))
78 return clib_error_return (0, "Rx mode %U not supported",
79 format_vnet_hw_if_rx_mode, mode);
81 ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
82 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
83 ptd->polling_q_count++;
86 ASSERT (ptd->polling_q_count != 0);
87 ptd->polling_q_count--;
94 vmxnet3_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
97 vmxnet3_main_t *vmxm = &vmxnet3_main;
98 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
99 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
101 /* Shut off redirection */
102 if (node_index == ~0)
104 vd->per_interface_next_index = node_index;
108 vd->per_interface_next_index =
109 vlib_node_add_next (vlib_get_main (), vmxnet3_input_node.index,
114 vmxnet3_clear_hw_interface_counters (u32 instance)
116 vmxnet3_main_t *vmxm = &vmxnet3_main;
117 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, instance);
118 vmxnet3_tx_queue *tx = VMXNET3_TX_START (vd);
119 vmxnet3_rx_queue *rx = VMXNET3_RX_START (vd);
123 * Set the "last_cleared_stats" to the current stats, so that
124 * things appear to clear from a display perspective.
126 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
128 vec_foreach_index (qid, vd->txqs)
130 vmxnet3_tx_stats *txs = vec_elt_at_index (vd->tx_stats, qid);
131 clib_memcpy (txs, &tx->stats, sizeof (*txs));
134 vec_foreach_index (qid, vd->rxqs)
136 vmxnet3_rx_stats *rxs = vec_elt_at_index (vd->rx_stats, qid);
137 clib_memcpy (rxs, &rx->stats, sizeof (*rxs));
142 static char *vmxnet3_tx_func_error_strings[] = {
144 foreach_vmxnet3_tx_func_error
149 VNET_DEVICE_CLASS (vmxnet3_device_class,) =
151 .name = "VMXNET3 interface",
152 .format_device = format_vmxnet3_device,
153 .format_device_name = format_vmxnet3_device_name,
154 .admin_up_down_function = vmxnet3_interface_admin_up_down,
155 .clear_counters = vmxnet3_clear_hw_interface_counters,
156 .rx_mode_change_function = vmxnet3_interface_rx_mode_change,
157 .rx_redirect_to_node = vmxnet3_set_interface_next_node,
158 .tx_function_n_errors = VMXNET3_TX_N_ERROR,
159 .tx_function_error_strings = vmxnet3_tx_func_error_strings,
164 vmxnet3_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
170 vmxnet3_write_mac (vmxnet3_device_t * vd)
174 memcpy (&val, vd->mac_addr, 4);
175 vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACL, val);
178 memcpy (&val, vd->mac_addr + 4, 2);
179 vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACH, val);
182 static clib_error_t *
183 vmxnet3_provision_driver_shared (vlib_main_t * vm, vmxnet3_device_t * vd)
185 vmxnet3_shared *shared;
188 vmxnet3_tx_queue *tx = VMXNET3_TX_START (vd);
189 vmxnet3_rx_queue *rx = VMXNET3_RX_START (vd);
192 vlib_physmem_alloc_aligned_on_numa (vm, sizeof (*vd->driver_shared), 512,
194 if (vd->driver_shared == 0)
195 return vlib_physmem_last_error (vm);
197 clib_memset (vd->driver_shared, 0, sizeof (*vd->driver_shared));
199 vec_foreach_index (qid, vd->txqs)
201 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
203 tx->cfg.desc_address = vmxnet3_dma_addr (vm, vd, txq->tx_desc);
204 tx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, txq->tx_comp);
205 tx->cfg.num_desc = txq->size;
206 tx->cfg.num_comp = txq->size;
210 vec_foreach_index (qid, vd->rxqs)
212 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
214 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
216 rx->cfg.desc_address[rid] = vmxnet3_dma_addr (vm, vd,
218 rx->cfg.num_desc[rid] = rxq->size;
220 rx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, rxq->rx_comp);
221 rx->cfg.num_comp = rxq->size;
222 rx->cfg.intr_index = qid;
226 shared = vd->driver_shared;
227 shared->magic = VMXNET3_SHARED_MAGIC;
228 shared->misc.version = VMXNET3_VERSION_MAGIC;
229 if (sizeof (void *) == 4)
230 shared->misc.guest_info = VMXNET3_GOS_BITS_32;
232 shared->misc.guest_info = VMXNET3_GOS_BITS_64;
233 shared->misc.guest_info |= VMXNET3_GOS_TYPE_LINUX;
234 shared->misc.version_support = VMXNET3_VERSION_SELECT;
235 shared->misc.upt_features = VMXNET3_F_RXCSUM;
237 shared->misc.upt_features |= VMXNET3_F_LRO;
238 if (vd->num_rx_queues > 1)
240 shared->misc.upt_features |= VMXNET3_F_RSS;
241 shared->rss.version = 1;
242 shared->rss.address = vmxnet3_dma_addr (vm, vd, vd->rss);
243 shared->rss.length = sizeof (*vd->rss);
245 shared->misc.max_num_rx_sg = 0;
246 shared->misc.upt_version_support = VMXNET3_UPT_VERSION_SELECT;
247 shared->misc.queue_desc_address = vmxnet3_dma_addr (vm, vd, vd->queues);
248 shared->misc.queue_desc_len = sizeof (*tx) * vd->num_tx_queues +
249 sizeof (*rx) * vd->num_rx_queues;
250 shared->misc.mtu = VMXNET3_MTU;
251 shared->misc.num_tx_queues = vd->num_tx_queues;
252 shared->misc.num_rx_queues = vd->num_rx_queues;
253 shared->interrupt.num_intrs = vd->num_intrs;
254 shared->interrupt.event_intr_index = vd->num_rx_queues;
255 shared->interrupt.control = VMXNET3_IC_DISABLE_ALL;
256 shared->rx_filter.mode = VMXNET3_RXMODE_UCAST | VMXNET3_RXMODE_BCAST |
257 VMXNET3_RXMODE_ALL_MULTI | VMXNET3_RXMODE_PROMISC;
258 shared_dma = vmxnet3_dma_addr (vm, vd, shared);
260 vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAL, shared_dma);
261 vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAH, shared_dma >> 32);
267 vmxnet3_enable_interrupt (vmxnet3_device_t * vd)
270 vmxnet3_shared *shared = vd->driver_shared;
272 shared->interrupt.control &= ~VMXNET3_IC_DISABLE_ALL;
273 for (i = 0; i < vd->num_intrs; i++)
274 vmxnet3_reg_write (vd, 0, VMXNET3_REG_IMR + i * 8, 0);
278 vmxnet3_disable_interrupt (vmxnet3_device_t * vd)
281 vmxnet3_shared *shared = vd->driver_shared;
283 shared->interrupt.control |= VMXNET3_IC_DISABLE_ALL;
284 for (i = 0; i < vd->num_intrs; i++)
285 vmxnet3_reg_write (vd, 0, VMXNET3_REG_IMR + i * 8, 1);
288 static clib_error_t *
289 vmxnet3_rxq_init (vlib_main_t * vm, vmxnet3_device_t * vd, u16 qid, u16 qsz)
292 vmxnet3_rx_stats *rxs;
295 vec_validate (vd->rx_stats, qid);
296 rxs = vec_elt_at_index (vd->rx_stats, qid);
297 clib_memset (rxs, 0, sizeof (*rxs));
299 vec_validate_aligned (vd->rxqs, qid, CLIB_CACHE_LINE_BYTES);
300 rxq = vec_elt_at_index (vd->rxqs, qid);
301 clib_memset (rxq, 0, sizeof (*rxq));
303 rxq->mode = VNET_HW_IF_RX_MODE_POLLING;
304 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
306 rxq->rx_desc[rid] = vlib_physmem_alloc_aligned_on_numa
307 (vm, qsz * sizeof (*rxq->rx_desc[rid]), 512, vd->numa_node);
309 if (rxq->rx_desc[rid] == 0)
310 return vlib_physmem_last_error (vm);
312 clib_memset (rxq->rx_desc[rid], 0, qsz * sizeof (*rxq->rx_desc[rid]));
315 vlib_physmem_alloc_aligned_on_numa (vm, qsz * sizeof (*rxq->rx_comp), 512,
317 if (rxq->rx_comp == 0)
318 return vlib_physmem_last_error (vm);
320 clib_memset (rxq->rx_comp, 0, qsz * sizeof (*rxq->rx_comp));
321 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
323 vmxnet3_rx_ring *ring;
325 ring = &rxq->rx_ring[rid];
326 ring->gen = VMXNET3_RXF_GEN;
328 vec_validate_aligned (ring->bufs, rxq->size, CLIB_CACHE_LINE_BYTES);
330 rxq->rx_comp_ring.gen = VMXNET3_RXCF_GEN;
335 static clib_error_t *
336 vmxnet3_txq_init (vlib_main_t * vm, vmxnet3_device_t * vd, u16 qid, u16 qsz)
339 vmxnet3_tx_stats *txs;
342 vec_validate_aligned (vd->txqs, qid, CLIB_CACHE_LINE_BYTES);
343 txq = vec_elt_at_index (vd->txqs, qid);
344 clib_memset (txq, 0, sizeof (*txq));
345 clib_spinlock_init (&txq->lock);
347 vec_validate (vd->tx_stats, qid);
348 txs = vec_elt_at_index (vd->tx_stats, qid);
349 clib_memset (txs, 0, sizeof (*txs));
352 txq->reg_txprod = qid * 8 + VMXNET3_REG_TXPROD;
354 size = qsz * sizeof (*txq->tx_desc);
356 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
357 if (txq->tx_desc == 0)
358 return vlib_physmem_last_error (vm);
360 clib_memset (txq->tx_desc, 0, size);
362 size = qsz * sizeof (*txq->tx_comp);
364 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
365 if (txq->tx_comp == 0)
366 return vlib_physmem_last_error (vm);
368 clib_memset (txq->tx_comp, 0, size);
369 vec_validate_aligned (txq->tx_ring.bufs, txq->size, CLIB_CACHE_LINE_BYTES);
370 txq->tx_ring.gen = VMXNET3_TXF_GEN;
371 txq->tx_comp_ring.gen = VMXNET3_TXCF_GEN;
376 static const u8 vmxnet3_rss_key[VMXNET3_RSS_MAX_KEY_SZ] = {
377 0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac,
378 0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28,
379 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70,
380 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3,
381 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9,
384 static clib_error_t *
385 vmxnet3_rss_init (vlib_main_t * vm, vmxnet3_device_t * vd)
387 vmxnet3_rss_shared *rss;
388 size_t size = sizeof (*rss);
391 vd->rss = vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
393 return vlib_physmem_last_error (vm);
395 clib_memset (vd->rss, 0, size);
398 VMXNET3_RSS_HASH_TYPE_IPV4 | VMXNET3_RSS_HASH_TYPE_TCP_IPV4 |
399 VMXNET3_RSS_HASH_TYPE_IPV6 | VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
400 rss->hash_func = VMXNET3_RSS_HASH_FUNC_TOEPLITZ;
401 rss->hash_key_sz = VMXNET3_RSS_MAX_KEY_SZ;
402 rss->ind_table_sz = VMXNET3_RSS_MAX_IND_TABLE_SZ;
403 clib_memcpy (rss->hash_key, vmxnet3_rss_key, VMXNET3_RSS_MAX_KEY_SZ);
404 for (i = 0; i < rss->ind_table_sz; i++)
405 rss->ind_table[i] = i % vd->num_rx_queues;
410 static clib_error_t *
411 vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
412 vmxnet3_create_if_args_t * args)
414 clib_error_t *error = 0;
417 /* Quiesce the device */
418 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
419 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
422 error = clib_error_return (0, "error on quiescing device rc (%u)", ret);
426 /* Reset the device */
427 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
428 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
431 error = clib_error_return (0, "error on resetting device rc (%u)", ret);
435 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_VRRS);
436 vd->version = count_leading_zeros (ret);
437 vd->version = uword_bits - vd->version;
439 if (vd->version == 0)
441 error = clib_error_return (0, "unsupported hardware version %u",
446 /* cap support version to 3 */
447 vmxnet3_reg_write (vd, 1, VMXNET3_REG_VRRS,
448 1 << (clib_min (3, vd->version) - 1));
450 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_UVRS);
452 vmxnet3_reg_write (vd, 1, VMXNET3_REG_UVRS, 1);
455 error = clib_error_return (0, "unsupported upt version %u", ret);
459 /* GSO is only supported for version >= 3 */
460 if (args->enable_gso)
462 if (vd->version >= 3)
467 clib_error_return (0,
468 "GSO is not supported because hardware version"
469 " is %u. It must be >= 3", vd->version);
474 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
475 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
478 vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
479 vd->link_speed = ret >> 16;
482 vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
484 /* Get the mac address */
485 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
486 clib_memcpy (vd->mac_addr, &ret, 4);
487 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACH);
488 clib_memcpy (vd->mac_addr + 4, &ret, 2);
490 size = sizeof (vmxnet3_rx_queue) * vd->num_rx_queues +
491 sizeof (vmxnet3_tx_queue) * vd->num_tx_queues;
494 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
496 return vlib_physmem_last_error (vm);
498 clib_memset (vd->queues, 0, size);
500 if (vd->num_rx_queues > 1)
502 error = vmxnet3_rss_init (vm, vd);
507 for (i = 0; i < vd->num_rx_queues; i++)
509 error = vmxnet3_rxq_init (vm, vd, i, args->rxq_size);
514 for (i = 0; i < vd->num_tx_queues; i++)
516 error = vmxnet3_txq_init (vm, vd, i, args->txq_size);
521 error = vmxnet3_provision_driver_shared (vm, vd);
525 vmxnet3_write_mac (vd);
527 /* Activate device */
528 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
529 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
533 clib_error_return (0, "error on activating device rc (%u)", ret);
541 vmxnet3_rxq_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h, u16 line)
543 vnet_main_t *vnm = vnet_get_main ();
544 vmxnet3_main_t *vmxm = &vmxnet3_main;
545 uword pd = vlib_pci_get_private_data (vm, h);
546 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
548 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
550 if (vec_len (vd->rxqs) > qid && (rxq->mode != VNET_HW_IF_RX_MODE_POLLING))
552 vmxnet3_per_thread_data_t *ptd =
553 vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
554 if (ptd->polling_q_count == 0)
555 vnet_hw_if_rx_queue_set_int_pending (vnm, rxq->queue_index);
560 vmxnet3_event_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
563 vnet_main_t *vnm = vnet_get_main ();
564 vmxnet3_main_t *vmxm = &vmxnet3_main;
565 uword pd = vlib_pci_get_private_data (vm, h);
566 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
569 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
570 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
573 vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
574 vd->link_speed = ret >> 16;
575 vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
576 vd->link_speed * 1000);
577 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
578 VNET_HW_INTERFACE_FLAG_LINK_UP);
582 vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
583 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
588 vmxnet3_queue_size_valid (u16 qsz)
590 if (qsz < 64 || qsz > 4096)
598 vmxnet3_tx_queue_num_valid (u16 num)
600 vlib_thread_main_t *tm = vlib_get_thread_main ();
602 if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
608 vmxnet3_rx_queue_num_valid (u16 num)
610 if (num > VMXNET3_RXQ_MAX)
616 vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
618 vnet_main_t *vnm = vnet_get_main ();
619 vmxnet3_main_t *vmxm = &vmxnet3_main;
620 vmxnet3_device_t *vd;
621 vlib_pci_dev_handle_t h;
622 clib_error_t *error = 0;
626 if (args->txq_num == 0)
628 if (args->rxq_num == 0)
630 if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
632 args->rv = VNET_API_ERROR_INVALID_VALUE;
634 clib_error_return (error, "number of rx queues must be <= %u",
636 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
637 format_vlib_pci_addr, &args->addr,
638 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
642 if (!vmxnet3_tx_queue_num_valid (args->txq_num))
644 args->rv = VNET_API_ERROR_INVALID_VALUE;
646 clib_error_return (error,
647 "number of tx queues must be <= %u and <= number of "
648 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
649 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
650 format_vlib_pci_addr, &args->addr,
651 "number of tx queues must be <= %u and <= number of "
652 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
655 if (args->rxq_size == 0)
656 args->rxq_size = VMXNET3_NUM_RX_DESC;
657 if (args->txq_size == 0)
658 args->txq_size = VMXNET3_NUM_TX_DESC;
660 if (!vmxnet3_queue_size_valid (args->rxq_size) ||
661 !vmxnet3_queue_size_valid (args->txq_size))
663 args->rv = VNET_API_ERROR_INVALID_VALUE;
665 clib_error_return (error,
666 "queue size must be <= 4096, >= 64, "
667 "and multiples of 64");
668 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
669 format_vlib_pci_addr, &args->addr,
670 "queue size must be <= 4096, >= 64, and multiples of 64");
675 pool_foreach (vd, vmxm->devices) {
676 if (vd->pci_addr.as_u32 == args->addr.as_u32)
678 args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
680 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
681 &args->addr, "pci address in use");
682 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
683 format_vlib_pci_addr, &args->addr, "pci address in use");
691 error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
694 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
696 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
698 "error encountered on binding pci device");
699 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
700 format_vlib_pci_addr, &args->addr,
701 "error encountered on binding pci devicee");
707 vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
709 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
711 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
713 "error encountered on pci device open");
714 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
715 format_vlib_pci_addr, &args->addr,
716 "error encountered on pci device open");
721 * Do not use vmxnet3_log_error prior to this line since the macro
722 * references vd->pci_dev_handle
724 pool_get (vmxm->devices, vd);
725 vd->num_tx_queues = args->txq_num;
726 vd->num_rx_queues = args->rxq_num;
727 vd->dev_instance = vd - vmxm->devices;
728 vd->per_interface_next_index = ~0;
729 vd->pci_addr = args->addr;
731 if (args->enable_elog)
732 vd->flags |= VMXNET3_DEVICE_F_ELOG;
734 vd->pci_dev_handle = h;
735 vd->numa_node = vlib_pci_get_numa_node (vm, h);
736 vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
738 vlib_pci_set_private_data (vm, h, vd->dev_instance);
740 if ((error = vlib_pci_bus_master_enable (vm, h)))
742 vmxnet3_log_error (vd, "error encountered on pci bus master enable");
746 if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
748 vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
752 if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
754 vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
758 num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
759 if (num_intr < vd->num_rx_queues + 1)
761 vmxnet3_log_error (vd,
762 "No sufficient interrupt lines (%u) for rx queues",
765 clib_error_return (0,
766 "No sufficient interrupt lines (%u) for rx queues",
770 if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
771 &vmxnet3_rxq_irq_handler)))
773 vmxnet3_log_error (vd,
774 "error encountered on pci register msix handler 0");
778 if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
779 &vmxnet3_event_irq_handler)))
781 vmxnet3_log_error (vd,
782 "error encountered on pci register msix handler 1");
786 if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
788 vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
792 if ((error = vlib_pci_intr_enable (vm, h)))
794 vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
798 if ((error = vmxnet3_device_init (vm, vd, args)))
800 vmxnet3_log_error (vd, "error encountered on device init");
804 /* create interface */
805 error = ethernet_register_interface (vnm, vmxnet3_device_class.index,
806 vd->dev_instance, vd->mac_addr,
807 &vd->hw_if_index, vmxnet3_flag_change);
811 vmxnet3_log_error (vd,
812 "error encountered on ethernet register interface");
816 vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
817 vd->sw_if_index = sw->sw_if_index;
818 args->sw_if_index = sw->sw_if_index;
820 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vd->hw_if_index);
821 hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE;
824 hw->caps |= (VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
825 VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
826 VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM);
829 vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
830 /* Disable interrupts */
831 vmxnet3_disable_interrupt (vd);
832 vec_foreach_index (qid, vd->rxqs)
834 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
836 vmxnet3_per_thread_data_t *ptd;
838 qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
839 VNET_HW_IF_RXQ_THREAD_ANY);
840 fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
841 vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
842 rxq->queue_index = qi;
844 vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
845 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
847 ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
848 ptd->polling_q_count++;
850 rxq->buffer_pool_index =
851 vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
852 vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
853 vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
856 vec_foreach_index (qid, vd->txqs)
858 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
860 vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
862 for (u32 i = 0; i < vlib_get_n_threads (); i++)
864 u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
865 vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
867 vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
869 vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
870 vmxnet3_enable_interrupt (vd);
872 vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
873 vd->link_speed * 1000);
874 if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
875 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
876 VNET_HW_INTERFACE_FLAG_LINK_UP);
878 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
882 vmxnet3_delete_if (vm, vd);
883 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
888 vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * vd)
890 vnet_main_t *vnm = vnet_get_main ();
891 vmxnet3_main_t *vmxm = &vmxnet3_main;
895 /* Quiesce the device */
896 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
898 /* Reset the device */
899 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
903 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
904 ethernet_delete_interface (vnm, vd->hw_if_index);
907 vlib_pci_device_close (vm, vd->pci_dev_handle);
910 vec_foreach_index (i, vd->rxqs)
912 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
913 u16 mask = rxq->size - 1;
915 vmxnet3_per_thread_data_t *ptd =
916 vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
918 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
920 ASSERT (ptd->polling_q_count != 0);
921 ptd->polling_q_count--;
923 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
925 vmxnet3_rx_ring *ring;
927 ring = &rxq->rx_ring[rid];
928 desc_idx = (ring->consume + 1) & mask;
929 vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
931 vec_free (ring->bufs);
932 vlib_physmem_free (vm, rxq->rx_desc[rid]);
934 vlib_physmem_free (vm, rxq->rx_comp);
938 vec_free (vd->rx_stats);
941 vec_foreach_index (i, vd->txqs)
943 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
944 u16 mask = txq->size - 1;
947 desc_idx = txq->tx_ring.consume;
948 end_idx = txq->tx_ring.produce;
949 while (desc_idx != end_idx)
951 bi = txq->tx_ring.bufs[desc_idx];
952 vlib_buffer_free_no_next (vm, &bi, 1);
956 clib_spinlock_free (&txq->lock);
957 vec_free (txq->tx_ring.bufs);
958 vlib_physmem_free (vm, txq->tx_desc);
959 vlib_physmem_free (vm, txq->tx_comp);
963 vec_free (vd->tx_stats);
965 vlib_physmem_free (vm, vd->driver_shared);
966 vlib_physmem_free (vm, vd->queues);
967 vlib_physmem_free (vm, vd->rss);
969 clib_error_free (vd->error);
970 clib_memset (vd, 0, sizeof (*vd));
971 pool_put (vmxm->devices, vd);
976 * fd.io coding-style-patch-verification: ON
979 * eval: (c-set-style "gnu")