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 vnet_eth_interface_registration_t eir = {};
622 vmxnet3_device_t *vd;
623 vlib_pci_dev_handle_t h;
624 vnet_hw_if_caps_change_t cc = {};
625 clib_error_t *error = 0;
629 if (args->txq_num == 0)
631 if (args->rxq_num == 0)
633 if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
635 args->rv = VNET_API_ERROR_INVALID_VALUE;
637 clib_error_return (error, "number of rx queues must be <= %u",
639 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
640 format_vlib_pci_addr, &args->addr,
641 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
645 if (!vmxnet3_tx_queue_num_valid (args->txq_num))
647 args->rv = VNET_API_ERROR_INVALID_VALUE;
649 clib_error_return (error,
650 "number of tx queues must be <= %u and <= number of "
651 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
652 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
653 format_vlib_pci_addr, &args->addr,
654 "number of tx queues must be <= %u and <= number of "
655 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
658 if (args->rxq_size == 0)
659 args->rxq_size = VMXNET3_NUM_RX_DESC;
660 if (args->txq_size == 0)
661 args->txq_size = VMXNET3_NUM_TX_DESC;
663 if (!vmxnet3_queue_size_valid (args->rxq_size) ||
664 !vmxnet3_queue_size_valid (args->txq_size))
666 args->rv = VNET_API_ERROR_INVALID_VALUE;
668 clib_error_return (error,
669 "queue size must be <= 4096, >= 64, "
670 "and multiples of 64");
671 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
672 format_vlib_pci_addr, &args->addr,
673 "queue size must be <= 4096, >= 64, and multiples of 64");
678 pool_foreach (vd, vmxm->devices) {
679 if (vd->pci_addr.as_u32 == args->addr.as_u32)
681 args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
683 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
684 &args->addr, "pci address in use");
685 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
686 format_vlib_pci_addr, &args->addr, "pci address in use");
694 error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
697 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
699 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
701 "error encountered on binding pci device");
702 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
703 format_vlib_pci_addr, &args->addr,
704 "error encountered on binding pci devicee");
710 vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
712 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
714 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
716 "error encountered on pci device open");
717 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
718 format_vlib_pci_addr, &args->addr,
719 "error encountered on pci device open");
724 * Do not use vmxnet3_log_error prior to this line since the macro
725 * references vd->pci_dev_handle
727 pool_get (vmxm->devices, vd);
728 vd->num_tx_queues = args->txq_num;
729 vd->num_rx_queues = args->rxq_num;
730 vd->dev_instance = vd - vmxm->devices;
731 vd->per_interface_next_index = ~0;
732 vd->pci_addr = args->addr;
734 if (args->enable_elog)
735 vd->flags |= VMXNET3_DEVICE_F_ELOG;
737 vd->pci_dev_handle = h;
738 vd->numa_node = vlib_pci_get_numa_node (vm, h);
739 vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
741 vlib_pci_set_private_data (vm, h, vd->dev_instance);
743 if ((error = vlib_pci_bus_master_enable (vm, h)))
745 vmxnet3_log_error (vd, "error encountered on pci bus master enable");
749 if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
751 vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
755 if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
757 vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
761 num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
762 if (num_intr < vd->num_rx_queues + 1)
764 vmxnet3_log_error (vd,
765 "No sufficient interrupt lines (%u) for rx queues",
768 clib_error_return (0,
769 "No sufficient interrupt lines (%u) for rx queues",
773 if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
774 &vmxnet3_rxq_irq_handler)))
776 vmxnet3_log_error (vd,
777 "error encountered on pci register msix handler 0");
781 if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
782 &vmxnet3_event_irq_handler)))
784 vmxnet3_log_error (vd,
785 "error encountered on pci register msix handler 1");
789 if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
791 vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
795 if ((error = vlib_pci_intr_enable (vm, h)))
797 vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
801 if ((error = vmxnet3_device_init (vm, vd, args)))
803 vmxnet3_log_error (vd, "error encountered on device init");
807 /* create interface */
808 eir.dev_class_index = vmxnet3_device_class.index;
809 eir.dev_instance = vd->dev_instance;
810 eir.address = vd->mac_addr;
811 eir.cb.flag_change = vmxnet3_flag_change;
812 vd->hw_if_index = vnet_eth_register_interface (vnm, &eir);
814 vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
815 vd->sw_if_index = sw->sw_if_index;
816 args->sw_if_index = sw->sw_if_index;
818 cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO |
819 VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
823 cc.val = VNET_HW_IF_CAP_INT_MODE;
825 vnet_hw_if_change_caps (vnm, vd->hw_if_index, &cc);
827 vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
828 /* Disable interrupts */
829 vmxnet3_disable_interrupt (vd);
830 vec_foreach_index (qid, vd->rxqs)
832 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
834 vmxnet3_per_thread_data_t *ptd;
836 qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
837 VNET_HW_IF_RXQ_THREAD_ANY);
838 fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
839 vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
840 rxq->queue_index = qi;
842 vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
843 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
845 ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
846 ptd->polling_q_count++;
848 rxq->buffer_pool_index =
849 vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
850 vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
851 vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
854 vec_foreach_index (qid, vd->txqs)
856 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
858 vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
860 for (u32 i = 0; i < vlib_get_n_threads (); i++)
862 u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
863 vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
865 vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
867 vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
868 vmxnet3_enable_interrupt (vd);
870 vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
871 vd->link_speed * 1000);
872 if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
873 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
874 VNET_HW_INTERFACE_FLAG_LINK_UP);
876 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
880 vmxnet3_delete_if (vm, vd);
881 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
886 vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * vd)
888 vnet_main_t *vnm = vnet_get_main ();
889 vmxnet3_main_t *vmxm = &vmxnet3_main;
893 /* Quiesce the device */
894 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
896 /* Reset the device */
897 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
901 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
902 ethernet_delete_interface (vnm, vd->hw_if_index);
905 vlib_pci_device_close (vm, vd->pci_dev_handle);
908 vec_foreach_index (i, vd->rxqs)
910 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
911 u16 mask = rxq->size - 1;
913 vmxnet3_per_thread_data_t *ptd =
914 vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
916 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
918 ASSERT (ptd->polling_q_count != 0);
919 ptd->polling_q_count--;
921 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
923 vmxnet3_rx_ring *ring;
925 ring = &rxq->rx_ring[rid];
926 desc_idx = (ring->consume + 1) & mask;
927 vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
929 vec_free (ring->bufs);
930 vlib_physmem_free (vm, rxq->rx_desc[rid]);
932 vlib_physmem_free (vm, rxq->rx_comp);
936 vec_free (vd->rx_stats);
939 vec_foreach_index (i, vd->txqs)
941 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
942 u16 mask = txq->size - 1;
945 desc_idx = txq->tx_ring.consume;
946 end_idx = txq->tx_ring.produce;
947 while (desc_idx != end_idx)
949 bi = txq->tx_ring.bufs[desc_idx];
950 vlib_buffer_free_no_next (vm, &bi, 1);
954 clib_spinlock_free (&txq->lock);
955 vec_free (txq->tx_ring.bufs);
956 vlib_physmem_free (vm, txq->tx_desc);
957 vlib_physmem_free (vm, txq->tx_comp);
961 vec_free (vd->tx_stats);
963 vlib_physmem_free (vm, vd->driver_shared);
964 vlib_physmem_free (vm, vd->queues);
965 vlib_physmem_free (vm, vd->rss);
967 clib_error_free (vd->error);
968 clib_memset (vd, 0, sizeof (*vd));
969 pool_put (vmxm->devices, vd);
974 * fd.io coding-style-patch-verification: ON
977 * eval: (c-set-style "gnu")