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 (
576 vnm, vd->hw_if_index,
577 (vd->link_speed == UINT32_MAX) ? UINT32_MAX : vd->link_speed * 1000);
578 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
579 VNET_HW_INTERFACE_FLAG_LINK_UP);
583 vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
584 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
589 vmxnet3_queue_size_valid (u16 qsz)
591 if (qsz < 64 || qsz > 4096)
599 vmxnet3_tx_queue_num_valid (u16 num)
601 vlib_thread_main_t *tm = vlib_get_thread_main ();
603 if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
609 vmxnet3_rx_queue_num_valid (u16 num)
611 if (num > VMXNET3_RXQ_MAX)
617 vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
619 vnet_main_t *vnm = vnet_get_main ();
620 vmxnet3_main_t *vmxm = &vmxnet3_main;
621 vnet_eth_interface_registration_t eir = {};
623 vmxnet3_device_t *vd;
624 vlib_pci_dev_handle_t h;
625 vnet_hw_if_caps_change_t cc = {};
626 clib_error_t *error = 0;
630 if (args->txq_num == 0)
632 if (args->rxq_num == 0)
634 if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
636 args->rv = VNET_API_ERROR_INVALID_VALUE;
638 clib_error_return (error, "number of rx queues must be <= %u",
640 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
641 format_vlib_pci_addr, &args->addr,
642 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
646 if (!vmxnet3_tx_queue_num_valid (args->txq_num))
648 args->rv = VNET_API_ERROR_INVALID_VALUE;
650 clib_error_return (error,
651 "number of tx queues must be <= %u and <= number of "
652 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
653 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
654 format_vlib_pci_addr, &args->addr,
655 "number of tx queues must be <= %u and <= number of "
656 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
659 if (args->rxq_size == 0)
660 args->rxq_size = VMXNET3_NUM_RX_DESC;
661 if (args->txq_size == 0)
662 args->txq_size = VMXNET3_NUM_TX_DESC;
664 if (!vmxnet3_queue_size_valid (args->rxq_size) ||
665 !vmxnet3_queue_size_valid (args->txq_size))
667 args->rv = VNET_API_ERROR_INVALID_VALUE;
669 clib_error_return (error,
670 "queue size must be <= 4096, >= 64, "
671 "and multiples of 64");
672 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
673 format_vlib_pci_addr, &args->addr,
674 "queue size must be <= 4096, >= 64, and multiples of 64");
679 pool_foreach (vd, vmxm->devices) {
680 if (vd->pci_addr.as_u32 == args->addr.as_u32)
682 args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
684 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
685 &args->addr, "pci address in use");
686 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
687 format_vlib_pci_addr, &args->addr, "pci address in use");
695 error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
698 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
700 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
702 "error encountered on binding pci device");
703 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
704 format_vlib_pci_addr, &args->addr,
705 "error encountered on binding pci devicee");
711 vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
713 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
715 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
717 "error encountered on pci device open");
718 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
719 format_vlib_pci_addr, &args->addr,
720 "error encountered on pci device open");
725 * Do not use vmxnet3_log_error prior to this line since the macro
726 * references vd->pci_dev_handle
728 pool_get (vmxm->devices, vd);
729 vd->num_tx_queues = args->txq_num;
730 vd->num_rx_queues = args->rxq_num;
731 vd->dev_instance = vd - vmxm->devices;
732 vd->per_interface_next_index = ~0;
733 vd->pci_addr = args->addr;
735 if (args->enable_elog)
736 vd->flags |= VMXNET3_DEVICE_F_ELOG;
738 vd->pci_dev_handle = h;
739 vd->numa_node = vlib_pci_get_numa_node (vm, h);
740 vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
742 vlib_pci_set_private_data (vm, h, vd->dev_instance);
744 if ((error = vlib_pci_bus_master_enable (vm, h)))
746 vmxnet3_log_error (vd, "error encountered on pci bus master enable");
750 if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
752 vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
756 if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
758 vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
762 num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
763 if (num_intr < vd->num_rx_queues + 1)
765 vmxnet3_log_error (vd,
766 "No sufficient interrupt lines (%u) for rx queues",
769 clib_error_return (0,
770 "No sufficient interrupt lines (%u) for rx queues",
774 if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
775 &vmxnet3_rxq_irq_handler)))
777 vmxnet3_log_error (vd,
778 "error encountered on pci register msix handler 0");
782 if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
783 &vmxnet3_event_irq_handler)))
785 vmxnet3_log_error (vd,
786 "error encountered on pci register msix handler 1");
790 if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
792 vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
796 if ((error = vlib_pci_intr_enable (vm, h)))
798 vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
802 if ((error = vmxnet3_device_init (vm, vd, args)))
804 vmxnet3_log_error (vd, "error encountered on device init");
808 /* create interface */
809 eir.dev_class_index = vmxnet3_device_class.index;
810 eir.dev_instance = vd->dev_instance;
811 eir.address = vd->mac_addr;
812 eir.cb.flag_change = vmxnet3_flag_change;
813 vd->hw_if_index = vnet_eth_register_interface (vnm, &eir);
815 vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
816 vd->sw_if_index = sw->sw_if_index;
817 args->sw_if_index = sw->sw_if_index;
819 cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO |
820 VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
824 cc.val = VNET_HW_IF_CAP_INT_MODE;
826 vnet_hw_if_change_caps (vnm, vd->hw_if_index, &cc);
828 vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
829 /* Disable interrupts */
830 vmxnet3_disable_interrupt (vd);
831 vec_foreach_index (qid, vd->rxqs)
833 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
835 vmxnet3_per_thread_data_t *ptd;
837 qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
838 VNET_HW_IF_RXQ_THREAD_ANY);
839 fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
840 vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
841 rxq->queue_index = qi;
843 vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
844 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
846 ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
847 ptd->polling_q_count++;
849 rxq->buffer_pool_index =
850 vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
851 vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
852 vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
855 vec_foreach_index (qid, vd->txqs)
857 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
859 vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
861 for (u32 i = 0; i < vlib_get_n_threads (); i++)
863 u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
864 vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
866 vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
868 vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
869 vmxnet3_enable_interrupt (vd);
871 vnet_hw_interface_set_link_speed (
872 vnm, vd->hw_if_index,
873 (vd->link_speed == UINT32_MAX) ? UINT32_MAX : 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")