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
148 VNET_DEVICE_CLASS (vmxnet3_device_class,) =
150 .name = "VMXNET3 interface",
151 .format_device = format_vmxnet3_device,
152 .format_device_name = format_vmxnet3_device_name,
153 .admin_up_down_function = vmxnet3_interface_admin_up_down,
154 .clear_counters = vmxnet3_clear_hw_interface_counters,
155 .rx_mode_change_function = vmxnet3_interface_rx_mode_change,
156 .rx_redirect_to_node = vmxnet3_set_interface_next_node,
157 .tx_function_n_errors = VMXNET3_TX_N_ERROR,
158 .tx_function_error_strings = vmxnet3_tx_func_error_strings,
162 vmxnet3_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
168 vmxnet3_write_mac (vmxnet3_device_t * vd)
172 memcpy (&val, vd->mac_addr, 4);
173 vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACL, val);
176 memcpy (&val, vd->mac_addr + 4, 2);
177 vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACH, val);
180 static clib_error_t *
181 vmxnet3_provision_driver_shared (vlib_main_t * vm, vmxnet3_device_t * vd)
183 vmxnet3_shared *shared;
186 vmxnet3_tx_queue *tx = VMXNET3_TX_START (vd);
187 vmxnet3_rx_queue *rx = VMXNET3_RX_START (vd);
190 vlib_physmem_alloc_aligned_on_numa (vm, sizeof (*vd->driver_shared), 512,
192 if (vd->driver_shared == 0)
193 return vlib_physmem_last_error (vm);
195 clib_memset (vd->driver_shared, 0, sizeof (*vd->driver_shared));
197 vec_foreach_index (qid, vd->txqs)
199 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
201 tx->cfg.desc_address = vmxnet3_dma_addr (vm, vd, txq->tx_desc);
202 tx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, txq->tx_comp);
203 tx->cfg.num_desc = txq->size;
204 tx->cfg.num_comp = txq->size;
208 vec_foreach_index (qid, vd->rxqs)
210 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
212 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
214 rx->cfg.desc_address[rid] = vmxnet3_dma_addr (vm, vd,
216 rx->cfg.num_desc[rid] = rxq->size;
218 rx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, rxq->rx_comp);
219 rx->cfg.num_comp = rxq->size;
220 rx->cfg.intr_index = qid;
224 shared = vd->driver_shared;
225 shared->magic = VMXNET3_SHARED_MAGIC;
226 shared->misc.version = VMXNET3_VERSION_MAGIC;
227 if (sizeof (void *) == 4)
228 shared->misc.guest_info = VMXNET3_GOS_BITS_32;
230 shared->misc.guest_info = VMXNET3_GOS_BITS_64;
231 shared->misc.guest_info |= VMXNET3_GOS_TYPE_LINUX;
232 shared->misc.version_support = VMXNET3_VERSION_SELECT;
233 shared->misc.upt_features = VMXNET3_F_RXCSUM;
235 shared->misc.upt_features |= VMXNET3_F_LRO;
236 if (vd->num_rx_queues > 1)
238 shared->misc.upt_features |= VMXNET3_F_RSS;
239 shared->rss.version = 1;
240 shared->rss.address = vmxnet3_dma_addr (vm, vd, vd->rss);
241 shared->rss.length = sizeof (*vd->rss);
243 shared->misc.max_num_rx_sg = 0;
244 shared->misc.upt_version_support = VMXNET3_UPT_VERSION_SELECT;
245 shared->misc.queue_desc_address = vmxnet3_dma_addr (vm, vd, vd->queues);
246 shared->misc.queue_desc_len = sizeof (*tx) * vd->num_tx_queues +
247 sizeof (*rx) * vd->num_rx_queues;
248 shared->misc.mtu = VMXNET3_MTU;
249 shared->misc.num_tx_queues = vd->num_tx_queues;
250 shared->misc.num_rx_queues = vd->num_rx_queues;
251 shared->interrupt.num_intrs = vd->num_intrs;
252 shared->interrupt.event_intr_index = vd->num_rx_queues;
253 shared->interrupt.control = VMXNET3_IC_DISABLE_ALL;
254 shared->rx_filter.mode = VMXNET3_RXMODE_UCAST | VMXNET3_RXMODE_BCAST |
255 VMXNET3_RXMODE_ALL_MULTI | VMXNET3_RXMODE_PROMISC;
256 shared_dma = vmxnet3_dma_addr (vm, vd, shared);
258 vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAL, shared_dma);
259 vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAH, shared_dma >> 32);
265 vmxnet3_enable_interrupt (vmxnet3_device_t * vd)
268 vmxnet3_shared *shared = vd->driver_shared;
270 shared->interrupt.control &= ~VMXNET3_IC_DISABLE_ALL;
271 for (i = 0; i < vd->num_intrs; i++)
272 vmxnet3_reg_write (vd, 0, VMXNET3_REG_IMR + i * 8, 0);
276 vmxnet3_disable_interrupt (vmxnet3_device_t * vd)
279 vmxnet3_shared *shared = vd->driver_shared;
281 shared->interrupt.control |= VMXNET3_IC_DISABLE_ALL;
282 for (i = 0; i < vd->num_intrs; i++)
283 vmxnet3_reg_write (vd, 0, VMXNET3_REG_IMR + i * 8, 1);
286 static clib_error_t *
287 vmxnet3_rxq_init (vlib_main_t * vm, vmxnet3_device_t * vd, u16 qid, u16 qsz)
290 vmxnet3_rx_stats *rxs;
293 vec_validate (vd->rx_stats, qid);
294 rxs = vec_elt_at_index (vd->rx_stats, qid);
295 clib_memset (rxs, 0, sizeof (*rxs));
297 vec_validate_aligned (vd->rxqs, qid, CLIB_CACHE_LINE_BYTES);
298 rxq = vec_elt_at_index (vd->rxqs, qid);
299 clib_memset (rxq, 0, sizeof (*rxq));
301 rxq->mode = VNET_HW_IF_RX_MODE_POLLING;
302 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
304 rxq->rx_desc[rid] = vlib_physmem_alloc_aligned_on_numa
305 (vm, qsz * sizeof (*rxq->rx_desc[rid]), 512, vd->numa_node);
307 if (rxq->rx_desc[rid] == 0)
308 return vlib_physmem_last_error (vm);
310 clib_memset (rxq->rx_desc[rid], 0, qsz * sizeof (*rxq->rx_desc[rid]));
313 vlib_physmem_alloc_aligned_on_numa (vm, qsz * sizeof (*rxq->rx_comp), 512,
315 if (rxq->rx_comp == 0)
316 return vlib_physmem_last_error (vm);
318 clib_memset (rxq->rx_comp, 0, qsz * sizeof (*rxq->rx_comp));
319 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
321 vmxnet3_rx_ring *ring;
323 ring = &rxq->rx_ring[rid];
324 ring->gen = VMXNET3_RXF_GEN;
326 vec_validate_aligned (ring->bufs, rxq->size, CLIB_CACHE_LINE_BYTES);
328 rxq->rx_comp_ring.gen = VMXNET3_RXCF_GEN;
333 static clib_error_t *
334 vmxnet3_txq_init (vlib_main_t * vm, vmxnet3_device_t * vd, u16 qid, u16 qsz)
337 vmxnet3_tx_stats *txs;
340 vec_validate_aligned (vd->txqs, qid, CLIB_CACHE_LINE_BYTES);
341 txq = vec_elt_at_index (vd->txqs, qid);
342 clib_memset (txq, 0, sizeof (*txq));
343 clib_spinlock_init (&txq->lock);
345 vec_validate (vd->tx_stats, qid);
346 txs = vec_elt_at_index (vd->tx_stats, qid);
347 clib_memset (txs, 0, sizeof (*txs));
350 txq->reg_txprod = qid * 8 + VMXNET3_REG_TXPROD;
352 size = qsz * sizeof (*txq->tx_desc);
354 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
355 if (txq->tx_desc == 0)
356 return vlib_physmem_last_error (vm);
358 clib_memset (txq->tx_desc, 0, size);
360 size = qsz * sizeof (*txq->tx_comp);
362 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
363 if (txq->tx_comp == 0)
364 return vlib_physmem_last_error (vm);
366 clib_memset (txq->tx_comp, 0, size);
367 vec_validate_aligned (txq->tx_ring.bufs, txq->size, CLIB_CACHE_LINE_BYTES);
368 txq->tx_ring.gen = VMXNET3_TXF_GEN;
369 txq->tx_comp_ring.gen = VMXNET3_TXCF_GEN;
374 static const u8 vmxnet3_rss_key[VMXNET3_RSS_MAX_KEY_SZ] = {
375 0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac,
376 0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28,
377 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70,
378 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3,
379 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9,
382 static clib_error_t *
383 vmxnet3_rss_init (vlib_main_t * vm, vmxnet3_device_t * vd)
385 vmxnet3_rss_shared *rss;
386 size_t size = sizeof (*rss);
389 vd->rss = vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
391 return vlib_physmem_last_error (vm);
393 clib_memset (vd->rss, 0, size);
396 VMXNET3_RSS_HASH_TYPE_IPV4 | VMXNET3_RSS_HASH_TYPE_TCP_IPV4 |
397 VMXNET3_RSS_HASH_TYPE_IPV6 | VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
398 rss->hash_func = VMXNET3_RSS_HASH_FUNC_TOEPLITZ;
399 rss->hash_key_sz = VMXNET3_RSS_MAX_KEY_SZ;
400 rss->ind_table_sz = VMXNET3_RSS_MAX_IND_TABLE_SZ;
401 clib_memcpy (rss->hash_key, vmxnet3_rss_key, VMXNET3_RSS_MAX_KEY_SZ);
402 for (i = 0; i < rss->ind_table_sz; i++)
403 rss->ind_table[i] = i % vd->num_rx_queues;
408 static clib_error_t *
409 vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
410 vmxnet3_create_if_args_t * args)
412 clib_error_t *error = 0;
415 /* Quiesce the device */
416 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
417 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
420 error = clib_error_return (0, "error on quiescing device rc (%u)", ret);
424 /* Reset the device */
425 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
426 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
429 error = clib_error_return (0, "error on resetting device rc (%u)", ret);
433 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_VRRS);
434 vd->version = count_leading_zeros (ret);
435 vd->version = uword_bits - vd->version;
437 if (vd->version == 0)
439 error = clib_error_return (0, "unsupported hardware version %u",
444 /* cap support version to 3 */
445 vmxnet3_reg_write (vd, 1, VMXNET3_REG_VRRS,
446 1 << (clib_min (3, vd->version) - 1));
448 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_UVRS);
450 vmxnet3_reg_write (vd, 1, VMXNET3_REG_UVRS, 1);
453 error = clib_error_return (0, "unsupported upt version %u", ret);
457 /* GSO is only supported for version >= 3 */
458 if (args->enable_gso)
460 if (vd->version >= 3)
465 clib_error_return (0,
466 "GSO is not supported because hardware version"
467 " is %u. It must be >= 3", vd->version);
472 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
473 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
476 vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
477 vd->link_speed = ret >> 16;
480 vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
482 /* Get the mac address */
483 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
484 clib_memcpy (vd->mac_addr, &ret, 4);
485 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACH);
486 clib_memcpy (vd->mac_addr + 4, &ret, 2);
488 size = sizeof (vmxnet3_rx_queue) * vd->num_rx_queues +
489 sizeof (vmxnet3_tx_queue) * vd->num_tx_queues;
492 vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
494 return vlib_physmem_last_error (vm);
496 clib_memset (vd->queues, 0, size);
498 if (vd->num_rx_queues > 1)
500 error = vmxnet3_rss_init (vm, vd);
505 for (i = 0; i < vd->num_rx_queues; i++)
507 error = vmxnet3_rxq_init (vm, vd, i, args->rxq_size);
512 for (i = 0; i < vd->num_tx_queues; i++)
514 error = vmxnet3_txq_init (vm, vd, i, args->txq_size);
519 error = vmxnet3_provision_driver_shared (vm, vd);
523 vmxnet3_write_mac (vd);
525 /* Activate device */
526 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
527 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
531 clib_error_return (0, "error on activating device rc (%u)", ret);
539 vmxnet3_rxq_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h, u16 line)
541 vnet_main_t *vnm = vnet_get_main ();
542 vmxnet3_main_t *vmxm = &vmxnet3_main;
543 uword pd = vlib_pci_get_private_data (vm, h);
544 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
546 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
548 if (vec_len (vd->rxqs) > qid && (rxq->mode != VNET_HW_IF_RX_MODE_POLLING))
550 vmxnet3_per_thread_data_t *ptd =
551 vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
552 if (ptd->polling_q_count == 0)
553 vnet_hw_if_rx_queue_set_int_pending (vnm, rxq->queue_index);
558 vmxnet3_event_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
561 vnet_main_t *vnm = vnet_get_main ();
562 vmxnet3_main_t *vmxm = &vmxnet3_main;
563 uword pd = vlib_pci_get_private_data (vm, h);
564 vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
567 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
568 ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
571 vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
572 vd->link_speed = ret >> 16;
573 vnet_hw_interface_set_link_speed (
574 vnm, vd->hw_if_index,
575 (vd->link_speed == UINT32_MAX) ? UINT32_MAX : vd->link_speed * 1000);
576 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
577 VNET_HW_INTERFACE_FLAG_LINK_UP);
581 vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
582 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
587 vmxnet3_queue_size_valid (u16 qsz)
589 if (qsz < 64 || qsz > 4096)
597 vmxnet3_tx_queue_num_valid (u16 num)
599 vlib_thread_main_t *tm = vlib_get_thread_main ();
601 if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
607 vmxnet3_rx_queue_num_valid (u16 num)
609 if (num > VMXNET3_RXQ_MAX)
615 vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
617 vnet_main_t *vnm = vnet_get_main ();
618 vmxnet3_main_t *vmxm = &vmxnet3_main;
619 vnet_eth_interface_registration_t eir = {};
621 vmxnet3_device_t *vd;
622 vlib_pci_dev_handle_t h;
623 vnet_hw_if_caps_change_t cc = {};
624 clib_error_t *error = 0;
628 if (args->txq_num == 0)
630 if (args->rxq_num == 0)
632 if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
634 args->rv = VNET_API_ERROR_INVALID_VALUE;
636 clib_error_return (error, "number of rx queues must be <= %u",
638 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
639 format_vlib_pci_addr, &args->addr,
640 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
644 if (!vmxnet3_tx_queue_num_valid (args->txq_num))
646 args->rv = VNET_API_ERROR_INVALID_VALUE;
648 clib_error_return (error,
649 "number of tx queues must be <= %u and <= number of "
650 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
651 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
652 format_vlib_pci_addr, &args->addr,
653 "number of tx queues must be <= %u and <= number of "
654 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
657 if (args->rxq_size == 0)
658 args->rxq_size = VMXNET3_NUM_RX_DESC;
659 if (args->txq_size == 0)
660 args->txq_size = VMXNET3_NUM_TX_DESC;
662 if (!vmxnet3_queue_size_valid (args->rxq_size) ||
663 !vmxnet3_queue_size_valid (args->txq_size))
665 args->rv = VNET_API_ERROR_INVALID_VALUE;
667 clib_error_return (error,
668 "queue size must be <= 4096, >= 64, "
669 "and multiples of 64");
670 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
671 format_vlib_pci_addr, &args->addr,
672 "queue size must be <= 4096, >= 64, and multiples of 64");
676 pool_foreach (vd, vmxm->devices) {
677 if (vd->pci_addr.as_u32 == args->addr.as_u32)
679 args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
681 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
682 &args->addr, "pci address in use");
683 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
684 format_vlib_pci_addr, &args->addr, "pci address in use");
691 error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto",
692 VMXNET3_BIND_FORCE == args->bind);
695 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
697 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
699 "error encountered on binding pci device");
700 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
701 format_vlib_pci_addr, &args->addr,
702 "error encountered on binding pci devicee");
708 vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
710 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
712 clib_error_return (error, "%U: %s", format_vlib_pci_addr,
714 "error encountered on pci device open");
715 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
716 format_vlib_pci_addr, &args->addr,
717 "error encountered on pci device open");
722 * Do not use vmxnet3_log_error prior to this line since the macro
723 * references vd->pci_dev_handle
725 pool_get (vmxm->devices, vd);
726 vd->num_tx_queues = args->txq_num;
727 vd->num_rx_queues = args->rxq_num;
728 vd->dev_instance = vd - vmxm->devices;
729 vd->per_interface_next_index = ~0;
730 vd->pci_addr = args->addr;
732 if (args->enable_elog)
733 vd->flags |= VMXNET3_DEVICE_F_ELOG;
735 vd->pci_dev_handle = h;
736 vd->numa_node = vlib_pci_get_numa_node (vm, h);
737 vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
739 vlib_pci_set_private_data (vm, h, vd->dev_instance);
741 if ((error = vlib_pci_bus_master_enable (vm, h)))
743 vmxnet3_log_error (vd, "error encountered on pci bus master enable");
747 if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
749 vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
753 if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
755 vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
759 num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
760 if (num_intr < vd->num_rx_queues + 1)
762 vmxnet3_log_error (vd,
763 "No sufficient interrupt lines (%u) for rx queues",
766 clib_error_return (0,
767 "No sufficient interrupt lines (%u) for rx queues",
771 if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
772 &vmxnet3_rxq_irq_handler)))
774 vmxnet3_log_error (vd,
775 "error encountered on pci register msix handler 0");
779 if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
780 &vmxnet3_event_irq_handler)))
782 vmxnet3_log_error (vd,
783 "error encountered on pci register msix handler 1");
787 if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
789 vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
793 if ((error = vlib_pci_intr_enable (vm, h)))
795 vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
799 if ((error = vmxnet3_device_init (vm, vd, args)))
801 vmxnet3_log_error (vd, "error encountered on device init");
805 /* create interface */
806 eir.dev_class_index = vmxnet3_device_class.index;
807 eir.dev_instance = vd->dev_instance;
808 eir.address = vd->mac_addr;
809 eir.cb.flag_change = vmxnet3_flag_change;
810 vd->hw_if_index = vnet_eth_register_interface (vnm, &eir);
812 vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
813 vd->sw_if_index = sw->sw_if_index;
814 args->sw_if_index = sw->sw_if_index;
816 cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO |
817 VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
821 cc.val = VNET_HW_IF_CAP_INT_MODE;
823 vnet_hw_if_change_caps (vnm, vd->hw_if_index, &cc);
825 vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
826 /* Disable interrupts */
827 vmxnet3_disable_interrupt (vd);
828 vec_foreach_index (qid, vd->rxqs)
830 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
832 vmxnet3_per_thread_data_t *ptd;
834 qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
835 VNET_HW_IF_RXQ_THREAD_ANY);
836 fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
837 vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
838 rxq->queue_index = qi;
840 vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
841 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
843 ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
844 ptd->polling_q_count++;
846 rxq->buffer_pool_index =
847 vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
848 vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
849 vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
852 vec_foreach_index (qid, vd->txqs)
854 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
856 vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
858 for (u32 i = 0; i < vlib_get_n_threads (); i++)
860 u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
861 vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
863 vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
865 vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
866 vmxnet3_enable_interrupt (vd);
868 vnet_hw_interface_set_link_speed (
869 vnm, vd->hw_if_index,
870 (vd->link_speed == UINT32_MAX) ? UINT32_MAX : vd->link_speed * 1000);
871 if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
872 vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
873 VNET_HW_INTERFACE_FLAG_LINK_UP);
875 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
879 vmxnet3_delete_if (vm, vd);
880 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
885 vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * vd)
887 vnet_main_t *vnm = vnet_get_main ();
888 vmxnet3_main_t *vmxm = &vmxnet3_main;
892 /* Quiesce the device */
893 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
895 /* Reset the device */
896 vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
900 vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
901 ethernet_delete_interface (vnm, vd->hw_if_index);
904 vlib_pci_device_close (vm, vd->pci_dev_handle);
906 vec_foreach_index (i, vd->rxqs)
908 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
909 u16 mask = rxq->size - 1;
911 vmxnet3_per_thread_data_t *ptd =
912 vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
914 if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
916 ASSERT (ptd->polling_q_count != 0);
917 ptd->polling_q_count--;
919 for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
921 vmxnet3_rx_ring *ring;
923 ring = &rxq->rx_ring[rid];
924 desc_idx = (ring->consume + 1) & mask;
925 vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
927 vec_free (ring->bufs);
928 vlib_physmem_free (vm, rxq->rx_desc[rid]);
930 vlib_physmem_free (vm, rxq->rx_comp);
933 vec_free (vd->rx_stats);
935 vec_foreach_index (i, vd->txqs)
937 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
938 u16 mask = txq->size - 1;
941 desc_idx = txq->tx_ring.consume;
942 end_idx = txq->tx_ring.produce;
943 while (desc_idx != end_idx)
945 bi = txq->tx_ring.bufs[desc_idx];
946 vlib_buffer_free_no_next (vm, &bi, 1);
950 clib_spinlock_free (&txq->lock);
951 vec_free (txq->tx_ring.bufs);
952 vlib_physmem_free (vm, txq->tx_desc);
953 vlib_physmem_free (vm, txq->tx_comp);
956 vec_free (vd->tx_stats);
958 vlib_physmem_free (vm, vd->driver_shared);
959 vlib_physmem_free (vm, vd->queues);
960 vlib_physmem_free (vm, vd->rss);
962 clib_error_free (vd->error);
963 clib_memset (vd, 0, sizeof (*vd));
964 pool_put (vmxm->devices, vd);
969 * fd.io coding-style-patch-verification: ON
972 * eval: (c-set-style "gnu")