FD.io VPP  v21.01.1
Vector Packet Processing
vmxnet3.c
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 
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 
23 #include <vmxnet3/vmxnet3.h>
24 
25 #define PCI_VENDOR_ID_VMWARE 0x15ad
26 #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07b0
27 
29 
30 static pci_device_id_t vmxnet3_pci_device_ids[] = {
31  {
33  .device_id = PCI_DEVICE_ID_VMWARE_VMXNET3},
34  {0},
35 };
36 
37 static clib_error_t *
39  u32 flags)
40 {
41  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
44  uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
45 
46  if (vd->flags & VMXNET3_DEVICE_F_ERROR)
47  return clib_error_return (0, "device is in error state");
48 
49  if (is_up)
50  {
53  vd->flags |= VMXNET3_DEVICE_F_ADMIN_UP;
54  }
55  else
56  {
58  vd->flags &= ~VMXNET3_DEVICE_F_ADMIN_UP;
59  }
60  return 0;
61 }
62 
63 static clib_error_t *
66 {
68  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
70  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
71 
72  if (mode == VNET_HW_IF_RX_MODE_POLLING)
73  rxq->int_mode = 0;
74  else
75  rxq->int_mode = 1;
76 
77  return 0;
78 }
79 
80 static void
82  u32 node_index)
83 {
85  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
87 
88  /* Shut off redirection */
89  if (node_index == ~0)
90  {
91  vd->per_interface_next_index = node_index;
92  return;
93  }
94 
97  node_index);
98 }
99 
100 static void
102 {
103  vmxnet3_main_t *vmxm = &vmxnet3_main;
104  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, instance);
105  vmxnet3_tx_queue *tx = VMXNET3_TX_START (vd);
106  vmxnet3_rx_queue *rx = VMXNET3_RX_START (vd);
107  u16 qid;
108 
109  /*
110  * Set the "last_cleared_stats" to the current stats, so that
111  * things appear to clear from a display perspective.
112  */
113  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
114 
115  vec_foreach_index (qid, vd->txqs)
116  {
117  vmxnet3_tx_stats *txs = vec_elt_at_index (vd->tx_stats, qid);
118  clib_memcpy (txs, &tx->stats, sizeof (*txs));
119  tx++;
120  }
121  vec_foreach_index (qid, vd->rxqs)
122  {
123  vmxnet3_rx_stats *rxs = vec_elt_at_index (vd->rx_stats, qid);
124  clib_memcpy (rxs, &rx->stats, sizeof (*rxs));
125  rx++;
126  }
127 }
128 
130 #define _(n,s) s,
132 #undef _
133 };
134 
135 /* *INDENT-OFF* */
137 {
138  .name = "VMXNET3 interface",
139  .format_device = format_vmxnet3_device,
140  .format_device_name = format_vmxnet3_device_name,
141  .admin_up_down_function = vmxnet3_interface_admin_up_down,
142  .clear_counters = vmxnet3_clear_hw_interface_counters,
143  .rx_mode_change_function = vmxnet3_interface_rx_mode_change,
144  .rx_redirect_to_node = vmxnet3_set_interface_next_node,
145  .tx_function_n_errors = VMXNET3_TX_N_ERROR,
146  .tx_function_error_strings = vmxnet3_tx_func_error_strings,
147 };
148 /* *INDENT-ON* */
149 
150 static u32
152 {
153  return 0;
154 }
155 
156 static void
158 {
159  u32 val;
160 
161  memcpy (&val, vd->mac_addr, 4);
162  vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACL, val);
163 
164  val = 0;
165  memcpy (&val, vd->mac_addr + 4, 2);
166  vmxnet3_reg_write (vd, 1, VMXNET3_REG_MACH, val);
167 }
168 
169 static clib_error_t *
171 {
172  vmxnet3_shared *shared;
173  u64 shared_dma;
174  u16 qid, rid;
175  vmxnet3_tx_queue *tx = VMXNET3_TX_START (vd);
176  vmxnet3_rx_queue *rx = VMXNET3_RX_START (vd);
177 
178  vd->driver_shared =
179  vlib_physmem_alloc_aligned_on_numa (vm, sizeof (*vd->driver_shared), 512,
180  vd->numa_node);
181  if (vd->driver_shared == 0)
182  return vlib_physmem_last_error (vm);
183 
184  clib_memset (vd->driver_shared, 0, sizeof (*vd->driver_shared));
185 
186  vec_foreach_index (qid, vd->txqs)
187  {
188  vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
189 
190  tx->cfg.desc_address = vmxnet3_dma_addr (vm, vd, txq->tx_desc);
191  tx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, txq->tx_comp);
192  tx->cfg.num_desc = txq->size;
193  tx->cfg.num_comp = txq->size;
194  tx++;
195  }
196 
197  vec_foreach_index (qid, vd->rxqs)
198  {
199  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
200 
201  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
202  {
203  rx->cfg.desc_address[rid] = vmxnet3_dma_addr (vm, vd,
204  rxq->rx_desc[rid]);
205  rx->cfg.num_desc[rid] = rxq->size;
206  }
207  rx->cfg.comp_address = vmxnet3_dma_addr (vm, vd, rxq->rx_comp);
208  rx->cfg.num_comp = rxq->size;
209  rx->cfg.intr_index = qid;
210  rx++;
211  }
212 
213  shared = vd->driver_shared;
214  shared->magic = VMXNET3_SHARED_MAGIC;
215  shared->misc.version = VMXNET3_VERSION_MAGIC;
216  if (sizeof (void *) == 4)
217  shared->misc.guest_info = VMXNET3_GOS_BITS_32;
218  else
219  shared->misc.guest_info = VMXNET3_GOS_BITS_64;
220  shared->misc.guest_info |= VMXNET3_GOS_TYPE_LINUX;
221  shared->misc.version_support = VMXNET3_VERSION_SELECT;
222  shared->misc.upt_features = VMXNET3_F_RXCSUM;
223  if (vd->gso_enable)
224  shared->misc.upt_features |= VMXNET3_F_LRO;
225  if (vd->num_rx_queues > 1)
226  {
227  shared->misc.upt_features |= VMXNET3_F_RSS;
228  shared->rss.version = 1;
229  shared->rss.address = vmxnet3_dma_addr (vm, vd, vd->rss);
230  shared->rss.length = sizeof (*vd->rss);
231  }
232  shared->misc.max_num_rx_sg = 0;
233  shared->misc.upt_version_support = VMXNET3_UPT_VERSION_SELECT;
234  shared->misc.queue_desc_address = vmxnet3_dma_addr (vm, vd, vd->queues);
235  shared->misc.queue_desc_len = sizeof (*tx) * vd->num_tx_queues +
236  sizeof (*rx) * vd->num_rx_queues;
237  shared->misc.mtu = VMXNET3_MTU;
238  shared->misc.num_tx_queues = vd->num_tx_queues;
239  shared->misc.num_rx_queues = vd->num_rx_queues;
240  shared->interrupt.num_intrs = vd->num_intrs;
241  shared->interrupt.event_intr_index = vd->num_rx_queues;
242  shared->interrupt.control = VMXNET3_IC_DISABLE_ALL;
243  shared->rx_filter.mode = VMXNET3_RXMODE_UCAST | VMXNET3_RXMODE_BCAST |
244  VMXNET3_RXMODE_ALL_MULTI | VMXNET3_RXMODE_PROMISC;
245  shared_dma = vmxnet3_dma_addr (vm, vd, shared);
246 
247  vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAL, shared_dma);
248  vmxnet3_reg_write (vd, 1, VMXNET3_REG_DSAH, shared_dma >> 32);
249 
250  return 0;
251 }
252 
253 static inline void
255 {
256  int i;
257  vmxnet3_shared *shared = vd->driver_shared;
258 
259  shared->interrupt.control &= ~VMXNET3_IC_DISABLE_ALL;
260  for (i = 0; i < vd->num_intrs; i++)
261  vmxnet3_reg_write (vd, 0, VMXNET3_REG_IMR + i * 8, 0);
262 }
263 
264 static inline void
266 {
267  int i;
268  vmxnet3_shared *shared = vd->driver_shared;
269 
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, 1);
273 }
274 
275 static clib_error_t *
277 {
278  vmxnet3_rxq_t *rxq;
279  vmxnet3_rx_stats *rxs;
280  u16 rid;
281 
282  vec_validate (vd->rx_stats, qid);
283  rxs = vec_elt_at_index (vd->rx_stats, qid);
284  clib_memset (rxs, 0, sizeof (*rxs));
285 
287  rxq = vec_elt_at_index (vd->rxqs, qid);
288  clib_memset (rxq, 0, sizeof (*rxq));
289  rxq->size = qsz;
290  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
291  {
293  (vm, qsz * sizeof (*rxq->rx_desc[rid]), 512, vd->numa_node);
294 
295  if (rxq->rx_desc[rid] == 0)
296  return vlib_physmem_last_error (vm);
297 
298  clib_memset (rxq->rx_desc[rid], 0, qsz * sizeof (*rxq->rx_desc[rid]));
299  }
300  rxq->rx_comp =
301  vlib_physmem_alloc_aligned_on_numa (vm, qsz * sizeof (*rxq->rx_comp), 512,
302  vd->numa_node);
303  if (rxq->rx_comp == 0)
304  return vlib_physmem_last_error (vm);
305 
306  clib_memset (rxq->rx_comp, 0, qsz * sizeof (*rxq->rx_comp));
307  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
308  {
309  vmxnet3_rx_ring *ring;
310 
311  ring = &rxq->rx_ring[rid];
312  ring->gen = VMXNET3_RXF_GEN;
313  ring->rid = rid;
315  }
317 
318  return 0;
319 }
320 
321 static clib_error_t *
323 {
324  vmxnet3_txq_t *txq;
325  vmxnet3_tx_stats *txs;
326  u32 size;
327 
328  if (qid >= vd->num_tx_queues)
329  {
330  qid = qid % vd->num_tx_queues;
331  txq = vec_elt_at_index (vd->txqs, qid);
332  if (txq->lock == 0)
333  clib_spinlock_init (&txq->lock);
334  vd->flags |= VMXNET3_DEVICE_F_SHARED_TXQ_LOCK;
335  return 0;
336  }
337 
338  vec_validate (vd->tx_stats, qid);
339  txs = vec_elt_at_index (vd->tx_stats, qid);
340  clib_memset (txs, 0, sizeof (*txs));
341 
343  txq = vec_elt_at_index (vd->txqs, qid);
344  clib_memset (txq, 0, sizeof (*txq));
345  txq->size = qsz;
346  txq->reg_txprod = qid * 8 + VMXNET3_REG_TXPROD;
347 
348  size = qsz * sizeof (*txq->tx_desc);
349  txq->tx_desc =
350  vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
351  if (txq->tx_desc == 0)
352  return vlib_physmem_last_error (vm);
353 
354  memset (txq->tx_desc, 0, size);
355 
356  size = qsz * sizeof (*txq->tx_comp);
357  txq->tx_comp =
358  vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
359  if (txq->tx_comp == 0)
360  return vlib_physmem_last_error (vm);
361 
362  clib_memset (txq->tx_comp, 0, size);
364  txq->tx_ring.gen = VMXNET3_TXF_GEN;
366 
367  return 0;
368 }
369 
371  0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac,
372  0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28,
373  0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70,
374  0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3,
375  0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9,
376 };
377 
378 static clib_error_t *
380 {
381  vmxnet3_rss_shared *rss;
382  size_t size = sizeof (*rss);
383  u8 i;
384 
385  vd->rss = vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
386  if (vd->rss == 0)
387  return vlib_physmem_last_error (vm);
388 
389  clib_memset (vd->rss, 0, size);
390  rss = vd->rss;
391  rss->hash_type =
392  VMXNET3_RSS_HASH_TYPE_IPV4 | VMXNET3_RSS_HASH_TYPE_TCP_IPV4 |
393  VMXNET3_RSS_HASH_TYPE_IPV6 | VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
394  rss->hash_func = VMXNET3_RSS_HASH_FUNC_TOEPLITZ;
395  rss->hash_key_sz = VMXNET3_RSS_MAX_KEY_SZ;
396  rss->ind_table_sz = VMXNET3_RSS_MAX_IND_TABLE_SZ;
398  for (i = 0; i < rss->ind_table_sz; i++)
399  rss->ind_table[i] = i % vd->num_rx_queues;
400 
401  return 0;
402 }
403 
404 static clib_error_t *
407 {
408  clib_error_t *error = 0;
409  u32 ret, i, size;
411 
412  /* Quiesce the device */
413  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
414  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
415  if (ret != 0)
416  {
417  error = clib_error_return (0, "error on quiescing device rc (%u)", ret);
418  return error;
419  }
420 
421  /* Reset the device */
422  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
423  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
424  if (ret != 0)
425  {
426  error = clib_error_return (0, "error on resetting device rc (%u)", ret);
427  return error;
428  }
429 
430  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_VRRS);
431  vd->version = count_leading_zeros (ret);
432  vd->version = uword_bits - vd->version;
433 
434  if (vd->version == 0)
435  {
436  error = clib_error_return (0, "unsupported hardware version %u",
437  vd->version);
438  return error;
439  }
440 
441  /* cap support version to 3 */
443  1 << (clib_min (3, vd->version) - 1));
444 
445  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_UVRS);
446  if (ret & 1)
448  else
449  {
450  error = clib_error_return (0, "unsupported upt version %u", ret);
451  return error;
452  }
453 
454  /* GSO is only supported for version >= 3 */
455  if (args->enable_gso)
456  {
457  if (vd->version >= 3)
458  vd->gso_enable = 1;
459  else
460  {
461  error =
463  "GSO is not supported because hardware version"
464  " is %u. It must be >= 3", vd->version);
465  return error;
466  }
467  }
468 
469  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
470  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
471  if (ret & 1)
472  {
473  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
474  vd->link_speed = ret >> 16;
475  }
476  else
477  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
478 
479  /* Get the mac address */
480  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
481  clib_memcpy (vd->mac_addr, &ret, 4);
482  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACH);
483  clib_memcpy (vd->mac_addr + 4, &ret, 2);
484 
485  size = sizeof (vmxnet3_rx_queue) * vd->num_rx_queues +
486  sizeof (vmxnet3_tx_queue) * vd->num_tx_queues;
487 
488  vd->queues =
489  vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
490  if (vd->queues == 0)
491  return vlib_physmem_last_error (vm);
492 
493  clib_memset (vd->queues, 0, size);
494 
495  if (vd->num_rx_queues > 1)
496  {
497  error = vmxnet3_rss_init (vm, vd);
498  if (error)
499  return error;
500  }
501 
502  for (i = 0; i < vd->num_rx_queues; i++)
503  {
504  error = vmxnet3_rxq_init (vm, vd, i, args->rxq_size);
505  if (error)
506  return error;
507  }
508 
509  for (i = 0; i < tm->n_vlib_mains; i++)
510  {
511  error = vmxnet3_txq_init (vm, vd, i, args->txq_size);
512  if (error)
513  return error;
514  }
515 
516  error = vmxnet3_provision_driver_shared (vm, vd);
517  if (error)
518  return error;
519 
520  vmxnet3_write_mac (vd);
521 
522  /* Activate device */
523  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
524  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
525  if (ret != 0)
526  {
527  error =
528  clib_error_return (0, "error on activating device rc (%u)", ret);
529  return error;
530  }
531 
532  return error;
533 }
534 
535 static void
537 {
538  vnet_main_t *vnm = vnet_get_main ();
539  vmxnet3_main_t *vmxm = &vmxnet3_main;
540  uword pd = vlib_pci_get_private_data (vm, h);
541  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
542  u16 qid = line;
543 
544  if (vec_len (vd->rxqs) > qid && vd->rxqs[qid].int_mode != 0)
546 }
547 
548 static void
550  u16 line)
551 {
552  vnet_main_t *vnm = vnet_get_main ();
553  vmxnet3_main_t *vmxm = &vmxnet3_main;
554  uword pd = vlib_pci_get_private_data (vm, h);
555  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
556  u32 ret;
557 
558  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
559  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
560  if (ret & 1)
561  {
562  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
563  vd->link_speed = ret >> 16;
565  vd->link_speed * 1000);
568  }
569  else
570  {
571  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
573  }
574 }
575 
576 static u8
578 {
579  if (qsz < 64 || qsz > 4096)
580  return 0;
581  if ((qsz % 64) != 0)
582  return 0;
583  return 1;
584 }
585 
586 static u8
588 {
590 
591  if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
592  return 0;
593  return 1;
594 }
595 
596 static u8
598 {
599  if (num > VMXNET3_RXQ_MAX)
600  return 0;
601  return 1;
602 }
603 
604 void
606 {
607  vnet_main_t *vnm = vnet_get_main ();
608  vmxnet3_main_t *vmxm = &vmxnet3_main;
609  vmxnet3_device_t *vd;
611  clib_error_t *error = 0;
612  u16 qid;
613  u32 num_intr;
614 
615  if (args->txq_num == 0)
616  args->txq_num = 1;
617  if (args->rxq_num == 0)
618  args->rxq_num = 1;
619  if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
620  {
621  args->rv = VNET_API_ERROR_INVALID_VALUE;
622  args->error =
623  clib_error_return (error, "number of rx queues must be <= %u",
625  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
626  format_vlib_pci_addr, &args->addr,
627  "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
628  return;
629  }
630 
631  if (!vmxnet3_tx_queue_num_valid (args->txq_num))
632  {
633  args->rv = VNET_API_ERROR_INVALID_VALUE;
634  args->error =
635  clib_error_return (error,
636  "number of tx queues must be <= %u and <= number of "
637  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
638  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
639  format_vlib_pci_addr, &args->addr,
640  "number of tx queues must be <= %u and <= number of "
641  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
642  return;
643  }
644  if (args->rxq_size == 0)
646  if (args->txq_size == 0)
648 
649  if (!vmxnet3_queue_size_valid (args->rxq_size) ||
651  {
652  args->rv = VNET_API_ERROR_INVALID_VALUE;
653  args->error =
654  clib_error_return (error,
655  "queue size must be <= 4096, >= 64, "
656  "and multiples of 64");
657  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
658  format_vlib_pci_addr, &args->addr,
659  "queue size must be <= 4096, >= 64, and multiples of 64");
660  return;
661  }
662 
663  /* *INDENT-OFF* */
664  pool_foreach (vd, vmxm->devices) {
665  if (vd->pci_addr.as_u32 == args->addr.as_u32)
666  {
667  args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
668  args->error =
669  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
670  &args->addr, "pci address in use");
671  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
672  format_vlib_pci_addr, &args->addr, "pci address in use");
673  return;
674  }
675  }
676  /* *INDENT-ON* */
677 
678  if (args->bind)
679  {
680  error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
681  if (error)
682  {
683  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
684  args->error =
685  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
686  &args->addr,
687  "error encountered on binding pci device");
688  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
689  format_vlib_pci_addr, &args->addr,
690  "error encountered on binding pci devicee");
691  return;
692  }
693  }
694 
695  if ((error =
696  vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
697  {
698  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
699  args->error =
700  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
701  &args->addr,
702  "error encountered on pci device open");
703  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
704  format_vlib_pci_addr, &args->addr,
705  "error encountered on pci device open");
706  return;
707  }
708 
709  /*
710  * Do not use vmxnet3_log_error prior to this line since the macro
711  * references vd->pci_dev_handle
712  */
713  pool_get (vmxm->devices, vd);
714  vd->num_tx_queues = args->txq_num;
715  vd->num_rx_queues = args->rxq_num;
716  vd->dev_instance = vd - vmxm->devices;
717  vd->per_interface_next_index = ~0;
718  vd->pci_addr = args->addr;
719 
720  if (args->enable_elog)
721  vd->flags |= VMXNET3_DEVICE_F_ELOG;
722 
723  vd->pci_dev_handle = h;
724  vd->numa_node = vlib_pci_get_numa_node (vm, h);
725  vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
726 
728 
729  if ((error = vlib_pci_bus_master_enable (vm, h)))
730  {
731  vmxnet3_log_error (vd, "error encountered on pci bus master enable");
732  goto error;
733  }
734 
735  if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
736  {
737  vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
738  goto error;
739  }
740 
741  if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
742  {
743  vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
744  goto error;
745  }
746 
747  num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
748  if (num_intr < vd->num_rx_queues + 1)
749  {
750  vmxnet3_log_error (vd,
751  "No sufficient interrupt lines (%u) for rx queues",
752  num_intr);
753  error =
755  "No sufficient interrupt lines (%u) for rx queues",
756  num_intr);
757  goto error;
758  }
759  if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
761  {
762  vmxnet3_log_error (vd,
763  "error encountered on pci register msix handler 0");
764  goto error;
765  }
766 
767  if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
769  {
770  vmxnet3_log_error (vd,
771  "error encountered on pci register msix handler 1");
772  goto error;
773  }
774 
775  if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
776  {
777  vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
778  goto error;
779  }
780 
781  if ((error = vlib_pci_intr_enable (vm, h)))
782  {
783  vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
784  goto error;
785  }
786 
787  if ((error = vmxnet3_device_init (vm, vd, args)))
788  {
789  vmxnet3_log_error (vd, "error encountered on device init");
790  goto error;
791  }
792 
793  /* create interface */
795  vd->dev_instance, vd->mac_addr,
797 
798  if (error)
799  {
800  vmxnet3_log_error (vd,
801  "error encountered on ethernet register interface");
802  goto error;
803  }
804 
806  vd->sw_if_index = sw->sw_if_index;
807  args->sw_if_index = sw->sw_if_index;
808 
811  if (vd->gso_enable)
814 
816  vmxnet3_input_node.index);
817  /* Disable interrupts */
819  vec_foreach_index (qid, vd->rxqs)
820  {
821  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
822  u32 thread_index;
823  u32 numa_node;
824 
826  thread_index = vnet_get_device_input_thread_index (vnm, vd->hw_if_index,
827  qid);
828  numa_node = vlib_mains[thread_index]->numa_node;
829  rxq->buffer_pool_index =
831  vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
832  vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
833  }
834  vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
836 
838  vd->link_speed * 1000);
839  if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
842  else
844  return;
845 
846 error:
847  vmxnet3_delete_if (vm, vd);
848  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
849  args->error = error;
850 }
851 
852 void
854 {
855  vnet_main_t *vnm = vnet_get_main ();
856  vmxnet3_main_t *vmxm = &vmxnet3_main;
857  u32 i, bi;
858  u16 desc_idx, qid;
859 
860  /* Quiesce the device */
861  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
862 
863  /* Reset the device */
864  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
865 
866  if (vd->hw_if_index)
867  {
869  vec_foreach_index (qid, vd->rxqs)
872  }
873 
875 
876  /* *INDENT-OFF* */
877  vec_foreach_index (i, vd->rxqs)
878  {
879  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
880  u16 mask = rxq->size - 1;
881  u16 rid;
882 
883  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
884  {
885  vmxnet3_rx_ring *ring;
886 
887  ring = &rxq->rx_ring[rid];
888  desc_idx = (ring->consume + 1) & mask;
889  vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
890  ring->fill);
891  vec_free (ring->bufs);
892  vlib_physmem_free (vm, rxq->rx_desc[rid]);
893  }
894  vlib_physmem_free (vm, rxq->rx_comp);
895  }
896  /* *INDENT-ON* */
897  vec_free (vd->rxqs);
898  vec_free (vd->rx_stats);
899 
900  /* *INDENT-OFF* */
901  vec_foreach_index (i, vd->txqs)
902  {
903  vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
904  u16 mask = txq->size - 1;
905  u16 end_idx;
906 
907  desc_idx = txq->tx_ring.consume;
908  end_idx = txq->tx_ring.produce;
909  while (desc_idx != end_idx)
910  {
911  bi = txq->tx_ring.bufs[desc_idx];
912  vlib_buffer_free_no_next (vm, &bi, 1);
913  desc_idx++;
914  desc_idx &= mask;
915  }
916  clib_spinlock_free (&txq->lock);
917  vec_free (txq->tx_ring.bufs);
918  vlib_physmem_free (vm, txq->tx_desc);
919  vlib_physmem_free (vm, txq->tx_comp);
920  }
921  /* *INDENT-ON* */
922  vec_free (vd->txqs);
923  vec_free (vd->tx_stats);
924 
926  vlib_physmem_free (vm, vd->queues);
927  vlib_physmem_free (vm, vd->rss);
928 
929  clib_error_free (vd->error);
930  clib_memset (vd, 0, sizeof (*vd));
931  pool_put (vmxm->devices, vd);
932 
933 }
934 
935 /*
936  * fd.io coding-style-patch-verification: ON
937  *
938  * Local Variables:
939  * eval: (c-set-style "gnu")
940  * End:
941  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
static char * vmxnet3_tx_func_error_strings[]
Definition: vmxnet3.c:129
static_always_inline clib_error_t * vmxnet3_rxq_refill_ring0(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_rxq_t *rxq)
Definition: vmxnet3.h:688
void vmxnet3_delete_if(vlib_main_t *vm, vmxnet3_device_t *vd)
Definition: vmxnet3.c:853
#define vec_foreach_index(var, v)
Iterate over vector indices.
static clib_error_t * vlib_pci_intr_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.h:239
#define clib_min(x, y)
Definition: clib.h:328
static clib_error_t * vlib_pci_bus_master_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.h:271
static void * vlib_physmem_alloc_aligned_on_numa(vlib_main_t *vm, uword n_bytes, uword alignment, u32 numa_node)
Definition: physmem_funcs.h:63
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
format_function_t format_vmxnet3_device_name
Definition: vmxnet3.h:631
#define VMXNET3_GOS_BITS_32
Definition: vmxnet3.h:172
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:393
#define VMXNET3_REG_VRRS
Definition: vmxnet3.h:104
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define VMXNET3_REG_TXPROD
Definition: vmxnet3.h:98
#define count_leading_zeros(x)
Definition: clib.h:156
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
vmxnet3_rx_desc * rx_desc[VMXNET3_RX_RING_SIZE]
Definition: vmxnet3.h:520
static_always_inline uword vmxnet3_dma_addr(vlib_main_t *vm, vmxnet3_device_t *vd, void *p)
Definition: vmxnet3.h:670
unsigned long u64
Definition: types.h:89
vlib_pci_dev_handle_t pci_dev_handle
Definition: vmxnet3.h:564
void vlib_pci_device_close(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:1311
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define VMXNET3_REG_DSAL
Definition: vmxnet3.h:106
clib_spinlock_t lock
Definition: vmxnet3.h:546
#define VMXNET3_RXQ_MAX
Definition: vmxnet3.h:91
vlib_pci_addr_t pci_addr
Definition: vmxnet3.h:565
u32 vlib_pci_get_num_msix_interrupts(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:177
#define VMXNET3_REG_MACL
Definition: vmxnet3.h:109
static clib_error_t * vlib_physmem_last_error(struct vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define foreach_vmxnet3_tx_func_error
Definition: vmxnet3.h:19
#define VMXNET3_MTU
Definition: vmxnet3.h:116
#define VMXNET3_RX_START(vd)
Definition: vmxnet3.h:93
vmxnet3_main_t vmxnet3_main
Definition: vmxnet3.c:28
#define VMXNET3_NUM_TX_DESC
Definition: vmxnet3.h:160
void vmxnet3_create_if(vlib_main_t *vm, vmxnet3_create_if_args_t *args)
Definition: vmxnet3.c:605
clib_error_t * vlib_pci_enable_msix_irq(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start, u16 count)
Definition: pci.c:895
vlib_main_t * vm
Definition: in2out_ed.c:1580
static void vmxnet3_event_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:549
vmxnet3_tx_stats * tx_stats
Definition: vmxnet3.h:586
u32 numa_node
Definition: main.h:252
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:520
u16 mask
Definition: flow_types.api:52
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:509
static clib_error_t * vmxnet3_rss_init(vlib_main_t *vm, vmxnet3_device_t *vd)
Definition: vmxnet3.c:379
static clib_error_t * vmxnet3_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: vmxnet3.c:38
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
vlib_main_t ** vlib_mains
Definition: buffer.c:332
static void vmxnet3_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: vmxnet3.c:81
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1173
unsigned char u8
Definition: types.h:56
static_always_inline void vmxnet3_reg_write(vmxnet3_device_t *vd, u8 bar, u32 addr, u32 val)
Definition: vmxnet3.h:652
static clib_error_t * vmxnet3_interface_rx_mode_change(vnet_main_t *vnm, u32 hw_if_index, u32 qid, vnet_hw_if_rx_mode mode)
Definition: vmxnet3.c:64
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:72
#define VMXNET3_RXCF_GEN
Definition: vmxnet3.h:129
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
Definition: string.h:180
static_always_inline u32 vmxnet3_reg_read(vmxnet3_device_t *vd, u8 bar, u32 addr)
Definition: vmxnet3.h:659
#define VMXNET3_VERSION_SELECT
Definition: vmxnet3.h:167
vmxnet3_rxq_t * rxqs
Definition: vmxnet3.h:569
vlib_log_class_t log_default
Definition: vmxnet3.h:594
static void vmxnet3_clear_hw_interface_counters(u32 instance)
Definition: vmxnet3.c:101
#define VMXNET3_TXQ_MAX
Definition: vmxnet3.h:90
static void vmxnet3_rxq_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:536
void * bar[2]
Definition: vmxnet3.h:566
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:127
vnet_hw_interface_flags_t flags
Definition: interface.h:538
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
#define VMXNET3_RSS_MAX_KEY_SZ
Definition: vmxnet3.h:87
vmxnet3_shared * driver_shared
Definition: vmxnet3.h:581
unsigned int u32
Definition: types.h:88
vlib_pci_addr_t addr
Definition: vmxnet3.h:601
#define VMXNET3_REG_UVRS
Definition: vmxnet3.h:105
#define VMXNET3_REG_MACH
Definition: vmxnet3.h:110
static clib_error_t * vmxnet3_rxq_init(vlib_main_t *vm, vmxnet3_device_t *vd, u16 qid, u16 qsz)
Definition: vmxnet3.c:276
#define VMXNET3_REG_IMR
Definition: vmxnet3.h:97
#define VMXNET3_RSS_HASH_FUNC_TOEPLITZ
Definition: vmxnet3.h:86
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
Definition: buffer_funcs.h:984
Definition: cJSON.c:84
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
static_always_inline uword vnet_get_device_input_thread_index(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:118
#define VMXNET3_REG_CMD
Definition: vmxnet3.h:108
static void vmxnet3_write_mac(vmxnet3_device_t *vd)
Definition: vmxnet3.c:157
void vlib_pci_set_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h, uword private_data)
Definition: pci.c:155
static u8 vmxnet3_queue_size_valid(u16 qsz)
Definition: vmxnet3.c:577
clib_error_t * vlib_pci_bind_to_uio(vlib_main_t *vm, vlib_pci_addr_t *addr, char *uio_drv_name)
Definition: pci.c:397
unsigned short u16
Definition: types.h:57
#define VMXNET3_GOS_TYPE_LINUX
Definition: vmxnet3.h:174
#define VMXNET3_GOS_BITS_64
Definition: vmxnet3.h:173
vmxnet3_rx_comp_ring rx_comp_ring
Definition: vmxnet3.h:522
u32 size
Definition: vhost_user.h:106
vec_header_t h
Definition: buffer.c:322
vmxnet3_tx_comp_ring tx_comp_ring
Definition: vmxnet3.h:551
#define VMXNET3_UPT_VERSION_SELECT
Definition: vmxnet3.h:168
#define VMXNET3_RX_RING_SIZE
Definition: vmxnet3.h:158
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
clib_error_t * vlib_pci_register_msix_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 start, u32 count, pci_msix_handler_function_t *msix_handler)
Definition: pci.c:838
vmxnet3_tx_comp * tx_comp
Definition: vmxnet3.h:549
uword vlib_pci_get_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:148
u8 buffer_pool_index
Definition: vmxnet3.h:518
u32 vlib_pci_dev_handle_t
Definition: pci.h:97
vl_api_tunnel_mode_t mode
Definition: gre.api:48
#define VMXNET3_VERSION_MAGIC
Definition: vmxnet3.h:165
vmxnet3_rss_shared * rss
Definition: vmxnet3.h:583
static void vmxnet3_enable_interrupt(vmxnet3_device_t *vd)
Definition: vmxnet3.c:254
#define VMXNET3_TXF_GEN
Definition: vmxnet3.h:146
u32 vlib_pci_get_numa_node(vlib_main_t *vm, vlib_pci_dev_handle_t h)
Definition: pci.c:170
#define VMXNET3_IC_DISABLE_ALL
Definition: vmxnet3.h:170
static void vlib_buffer_free_no_next(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers, does not free the buffer chain for each buffer.
Definition: buffer_funcs.h:954
static void vmxnet3_disable_interrupt(vmxnet3_device_t *vd)
Definition: vmxnet3.c:265
#define uword_bits
Definition: types.h:102
static void vlib_physmem_free(vlib_main_t *vm, void *p)
Definition: physmem_funcs.h:89
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static const u8 vmxnet3_rss_key[VMXNET3_RSS_MAX_KEY_SZ]
Definition: vmxnet3.c:370
void vlib_log(vlib_log_level_t level, vlib_log_class_t class, char *fmt,...)
Definition: log.c:131
u8 mac_addr[6]
Definition: vmxnet3.h:577
#define PCI_VENDOR_ID_VMWARE
Definition: vmxnet3.c:25
u32 per_interface_next_index
Definition: vmxnet3.h:558
VNET_DEVICE_CLASS(vmxnet3_device_class,)
vmxnet3_txq_t * txqs
Definition: vmxnet3.h:570
clib_error_t * error
Definition: vmxnet3.h:579
static clib_error_t * vmxnet3_device_init(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_create_if_args_t *args)
Definition: vmxnet3.c:405
void * queues
Definition: vmxnet3.h:582
#define VMXNET3_RXF_GEN
Definition: vmxnet3.h:119
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:139
format_function_t format_vmxnet3_device
Definition: vmxnet3.h:630
#define VMXNET3_REG_DSAH
Definition: vmxnet3.h:107
vmxnet3_rx_stats * rx_stats
Definition: vmxnet3.h:587
#define VMXNET3_TXCF_GEN
Definition: vmxnet3.h:155
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
vl_api_ip4_address_t hi
Definition: arp.api:37
static u8 vmxnet3_rx_queue_num_valid(u16 num)
Definition: vmxnet3.c:597
static clib_error_t * vmxnet3_provision_driver_shared(vlib_main_t *vm, vmxnet3_device_t *vd)
Definition: vmxnet3.c:170
vlib_node_registration_t vmxnet3_input_node
(constructor) VLIB_REGISTER_NODE (vmxnet3_input_node)
Definition: input.c:488
u32 reg_txprod
Definition: vmxnet3.h:545
#define VMXNET3_SHARED_MAGIC
Definition: vmxnet3.h:166
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define PCI_DEVICE_ID_VMWARE_VMXNET3
Definition: vmxnet3.c:26
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:348
u32 instance
Definition: gre.api:51
vmxnet3_tx_desc * tx_desc
Definition: vmxnet3.h:548
u64 uword
Definition: types.h:112
#define VMXNET3_RSS_MAX_IND_TABLE_SZ
Definition: vmxnet3.h:88
vnet_device_class_t vmxnet3_device_class
static u32 vmxnet3_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
Definition: vmxnet3.c:151
#define VMXNET3_TX_START(vd)
Definition: vmxnet3.h:92
vmxnet3_rx_comp * rx_comp
Definition: vmxnet3.h:521
#define clib_error_free(e)
Definition: error.h:86
vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE]
Definition: vmxnet3.h:519
clib_error_t * vlib_pci_map_region(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource, void **result)
Definition: pci.c:1182
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:188
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
vmxnet3_device_t * devices
Definition: vmxnet3.h:592
vnet_hw_if_rx_mode
Definition: interface.h:53
static_always_inline clib_error_t * vmxnet3_rxq_refill_ring1(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_rxq_t *rxq)
Definition: vmxnet3.h:734
#define vmxnet3_log_error(dev, f,...)
Definition: vmxnet3.h:639
static u8 vmxnet3_tx_queue_num_valid(u16 num)
Definition: vmxnet3.c:587
#define VMXNET3_NUM_RX_DESC
Definition: vmxnet3.h:162
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vmxnet3_tx_ring tx_ring
Definition: vmxnet3.h:550
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
Definition: buffer_funcs.h:199
clib_error_t * error
Definition: vmxnet3.h:612
clib_error_t * vlib_pci_device_open(vlib_main_t *vm, vlib_pci_addr_t *addr, pci_device_id_t ids[], vlib_pci_dev_handle_t *handle)
Definition: pci.c:1251
static void vnet_hw_interface_set_link_speed(vnet_main_t *vnm, u32 hw_if_index, u32 link_speed)
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
static clib_error_t * vmxnet3_txq_init(vlib_main_t *vm, vmxnet3_device_t *vd, u16 qid, u16 qsz)
Definition: vmxnet3.c:322
u16 vendor_id
Definition: pci.h:127
format_function_t format_vlib_pci_addr
Definition: pci.h:326