FD.io VPP  v20.01-48-g3e0dafb74
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 
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 && (vd->version >= 3))
456  {
457  vd->gso_enable = 1;
458  }
459 
460  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
461  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
462  if (ret & 1)
463  {
464  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
465  vd->link_speed = ret >> 16;
466  }
467  else
468  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
469 
470  /* Get the mac address */
471  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
472  clib_memcpy (vd->mac_addr, &ret, 4);
473  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACH);
474  clib_memcpy (vd->mac_addr + 4, &ret, 2);
475 
476  size = sizeof (vmxnet3_rx_queue) * vd->num_rx_queues +
477  sizeof (vmxnet3_tx_queue) * vd->num_tx_queues;
478 
479  vd->queues =
480  vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
481  if (vd->queues == 0)
482  return vlib_physmem_last_error (vm);
483 
484  clib_memset (vd->queues, 0, size);
485 
486  if (vd->num_rx_queues > 1)
487  {
488  error = vmxnet3_rss_init (vm, vd);
489  if (error)
490  return error;
491  }
492 
493  for (i = 0; i < vd->num_rx_queues; i++)
494  {
495  error = vmxnet3_rxq_init (vm, vd, i, args->rxq_size);
496  if (error)
497  return error;
498  }
499 
500  for (i = 0; i < tm->n_vlib_mains; i++)
501  {
502  error = vmxnet3_txq_init (vm, vd, i, args->txq_size);
503  if (error)
504  return error;
505  }
506 
507  error = vmxnet3_provision_driver_shared (vm, vd);
508  if (error)
509  return error;
510 
511  vmxnet3_write_mac (vd);
512 
513  /* Activate device */
514  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
515  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
516  if (ret != 0)
517  {
518  error =
519  clib_error_return (0, "error on activating device rc (%u)", ret);
520  return error;
521  }
522 
523  return error;
524 }
525 
526 static void
528 {
529  vnet_main_t *vnm = vnet_get_main ();
530  vmxnet3_main_t *vmxm = &vmxnet3_main;
531  uword pd = vlib_pci_get_private_data (vm, h);
532  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
533  u16 qid = line;
534 
535  if (vec_len (vd->rxqs) > qid && vd->rxqs[qid].int_mode != 0)
537 }
538 
539 static void
541  u16 line)
542 {
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);
547  u32 ret;
548 
549  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
550  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
551  if (ret & 1)
552  {
553  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
554  vd->link_speed = ret >> 16;
556  vd->link_speed * 1000);
559  }
560  else
561  {
562  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
564  }
565 }
566 
567 static u8
569 {
570  if (qsz < 64 || qsz > 4096)
571  return 0;
572  if ((qsz % 64) != 0)
573  return 0;
574  return 1;
575 }
576 
577 static u8
579 {
581 
582  if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
583  return 0;
584  return 1;
585 }
586 
587 static u8
589 {
590  if (num > VMXNET3_RXQ_MAX)
591  return 0;
592  return 1;
593 }
594 
595 void
597 {
598  vnet_main_t *vnm = vnet_get_main ();
599  vmxnet3_main_t *vmxm = &vmxnet3_main;
600  vmxnet3_device_t *vd;
602  clib_error_t *error = 0;
603  u16 qid;
604  u32 num_intr;
605 
606  if (args->txq_num == 0)
607  args->txq_num = 1;
608  if (args->rxq_num == 0)
609  args->rxq_num = 1;
610  if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
611  {
612  args->rv = VNET_API_ERROR_INVALID_VALUE;
613  args->error =
614  clib_error_return (error, "number of rx queues must be <= %u",
616  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
617  format_vlib_pci_addr, &args->addr,
618  "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
619  return;
620  }
621 
622  if (!vmxnet3_tx_queue_num_valid (args->txq_num))
623  {
624  args->rv = VNET_API_ERROR_INVALID_VALUE;
625  args->error =
626  clib_error_return (error,
627  "number of tx queues must be <= %u and <= number of "
628  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
629  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
630  format_vlib_pci_addr, &args->addr,
631  "number of tx queues must be <= %u and <= number of "
632  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
633  return;
634  }
635  if (args->rxq_size == 0)
637  if (args->txq_size == 0)
639 
640  if (!vmxnet3_queue_size_valid (args->rxq_size) ||
642  {
643  args->rv = VNET_API_ERROR_INVALID_VALUE;
644  args->error =
645  clib_error_return (error,
646  "queue size must be <= 4096, >= 64, "
647  "and multiples of 64");
648  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
649  format_vlib_pci_addr, &args->addr,
650  "queue size must be <= 4096, >= 64, and multiples of 64");
651  return;
652  }
653 
654  /* *INDENT-OFF* */
655  pool_foreach (vd, vmxm->devices, ({
656  if (vd->pci_addr.as_u32 == args->addr.as_u32)
657  {
658  args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
659  args->error =
660  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
661  &args->addr, "pci address in use");
662  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
663  format_vlib_pci_addr, &args->addr, "pci address in use");
664  return;
665  }
666  }));
667  /* *INDENT-ON* */
668 
669  if (args->bind)
670  {
671  error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
672  if (error)
673  {
674  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
675  args->error =
676  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
677  &args->addr,
678  "error encountered on binding pci device");
679  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
680  format_vlib_pci_addr, &args->addr,
681  "error encountered on binding pci devicee");
682  return;
683  }
684  }
685 
686  if ((error =
687  vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
688  {
689  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
690  args->error =
691  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
692  &args->addr,
693  "error encountered on pci device open");
694  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
695  format_vlib_pci_addr, &args->addr,
696  "error encountered on pci device open");
697  return;
698  }
699 
700  /*
701  * Do not use vmxnet3_log_error prior to this line since the macro
702  * references vd->pci_dev_handle
703  */
704  pool_get (vmxm->devices, vd);
705  vd->num_tx_queues = args->txq_num;
706  vd->num_rx_queues = args->rxq_num;
707  vd->dev_instance = vd - vmxm->devices;
708  vd->per_interface_next_index = ~0;
709  vd->pci_addr = args->addr;
710 
711  if (args->enable_elog)
712  vd->flags |= VMXNET3_DEVICE_F_ELOG;
713 
714  vd->pci_dev_handle = h;
715  vd->numa_node = vlib_pci_get_numa_node (vm, h);
716  vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
717 
718  vlib_pci_set_private_data (vm, h, vd->dev_instance);
719 
720  if ((error = vlib_pci_bus_master_enable (vm, h)))
721  {
722  vmxnet3_log_error (vd, "error encountered on pci bus master enable");
723  goto error;
724  }
725 
726  if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
727  {
728  vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
729  goto error;
730  }
731 
732  if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
733  {
734  vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
735  goto error;
736  }
737 
738  num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
739  if (num_intr < vd->num_rx_queues + 1)
740  {
741  vmxnet3_log_error (vd,
742  "No sufficient interrupt lines (%u) for rx queues",
743  num_intr);
744  goto error;
745  }
746  if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
748  {
749  vmxnet3_log_error (vd,
750  "error encountered on pci register msix handler 0");
751  goto error;
752  }
753 
754  if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
756  {
757  vmxnet3_log_error (vd,
758  "error encountered on pci register msix handler 1");
759  goto error;
760  }
761 
762  if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
763  {
764  vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
765  goto error;
766  }
767 
768  if ((error = vlib_pci_intr_enable (vm, h)))
769  {
770  vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
771  goto error;
772  }
773 
774  if ((error = vmxnet3_device_init (vm, vd, args)))
775  {
776  vmxnet3_log_error (vd, "error encountered on device init");
777  goto error;
778  }
779 
780  /* create interface */
782  vd->dev_instance, vd->mac_addr,
783  &vd->hw_if_index, vmxnet3_flag_change);
784 
785  if (error)
786  {
787  vmxnet3_log_error (vd,
788  "error encountered on ethernet register interface");
789  goto error;
790  }
791 
792  vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
793  vd->sw_if_index = sw->sw_if_index;
794  args->sw_if_index = sw->sw_if_index;
795 
796  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vd->hw_if_index);
798  if (vd->gso_enable)
800 
801  vnet_hw_interface_set_input_node (vnm, vd->hw_if_index,
802  vmxnet3_input_node.index);
803  /* Disable interrupts */
805  vec_foreach_index (qid, vd->rxqs)
806  {
807  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
808  u32 thread_index;
809  u32 numa_node;
810 
811  vnet_hw_interface_assign_rx_thread (vnm, vd->hw_if_index, qid, ~0);
812  thread_index = vnet_get_device_input_thread_index (vnm, vd->hw_if_index,
813  qid);
814  numa_node = vlib_mains[thread_index]->numa_node;
815  rxq->buffer_pool_index =
817  vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
818  vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
819  }
820  vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
822 
823  vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
824  vd->link_speed * 1000);
825  if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
826  vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
828  else
829  vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
830  return;
831 
832 error:
833  vmxnet3_delete_if (vm, vd);
834  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
835  args->error = error;
836 }
837 
838 void
840 {
841  vnet_main_t *vnm = vnet_get_main ();
842  vmxnet3_main_t *vmxm = &vmxnet3_main;
843  u32 i, bi;
844  u16 desc_idx, qid;
845 
846  /* Quiesce the device */
847  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
848 
849  /* Reset the device */
850  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
851 
852  if (vd->hw_if_index)
853  {
855  vec_foreach_index (qid, vd->rxqs)
858  }
859 
861 
862  /* *INDENT-OFF* */
863  vec_foreach_index (i, vd->rxqs)
864  {
865  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
866  u16 mask = rxq->size - 1;
867  u16 rid;
868 
869  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
870  {
871  vmxnet3_rx_ring *ring;
872 
873  ring = &rxq->rx_ring[rid];
874  desc_idx = (ring->consume + 1) & mask;
875  vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
876  ring->fill);
877  vec_free (ring->bufs);
878  vlib_physmem_free (vm, rxq->rx_desc[rid]);
879  }
880  vlib_physmem_free (vm, rxq->rx_comp);
881  }
882  /* *INDENT-ON* */
883  vec_free (vd->rxqs);
884  vec_free (vd->rx_stats);
885 
886  /* *INDENT-OFF* */
887  vec_foreach_index (i, vd->txqs)
888  {
889  vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
890  u16 mask = txq->size - 1;
891  u16 end_idx;
892 
893  desc_idx = txq->tx_ring.consume;
894  end_idx = txq->tx_ring.produce;
895  while (desc_idx != end_idx)
896  {
897  bi = txq->tx_ring.bufs[desc_idx];
898  vlib_buffer_free_no_next (vm, &bi, 1);
899  desc_idx++;
900  desc_idx &= mask;
901  }
902  clib_spinlock_free (&txq->lock);
903  vec_free (txq->tx_ring.bufs);
904  vlib_physmem_free (vm, txq->tx_desc);
905  vlib_physmem_free (vm, txq->tx_comp);
906  }
907  /* *INDENT-ON* */
908  vec_free (vd->txqs);
909  vec_free (vd->tx_stats);
910 
912  vlib_physmem_free (vm, vd->queues);
913  vlib_physmem_free (vm, vd->rss);
914 
915  clib_error_free (vd->error);
916  clib_memset (vd, 0, sizeof (*vd));
917  pool_put (vmxm->devices, vd);
918 
919 }
920 
921 /*
922  * fd.io coding-style-patch-verification: ON
923  *
924  * Local Variables:
925  * eval: (c-set-style "gnu")
926  * End:
927  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
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:839
#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:295
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
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:378
#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:138
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:1274
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
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
int i
#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:596
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:882
static void vmxnet3_event_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:540
vmxnet3_tx_stats * tx_stats
Definition: vmxnet3.h:586
u32 numa_node
Definition: main.h:220
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:451
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:237
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:1092
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 void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:70
#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
vnet_hw_interface_rx_mode
Definition: interface.h:53
#define VMXNET3_TXQ_MAX
Definition: vmxnet3.h:90
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
static void vmxnet3_rxq_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:527
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:136
vnet_hw_interface_flags_t flags
Definition: interface.h:523
#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
vl_api_gre_tunnel_mode_t mode
Definition: gre.api:55
#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:63
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:937
static clib_error_t * vmxnet3_interface_rx_mode_change(vnet_main_t *vnm, u32 hw_if_index, u32 qid, vnet_hw_interface_rx_mode mode)
Definition: vmxnet3.c:64
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
static_always_inline uword vnet_get_device_input_thread_index(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:127
#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:568
clib_error_t * vlib_pci_bind_to_uio(vlib_main_t *vm, vlib_pci_addr_t *addr, char *uio_drv_name)
Definition: pci.c:385
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
u64 size
Definition: vhost_user.h:140
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:287
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:825
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
vlib_main_t * vm
Definition: in2out_ed.c:1810
#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:907
static void vmxnet3_disable_interrupt(vmxnet3_device_t *vd)
Definition: vmxnet3.c:265
u32 flags
Definition: vhost_user.h:141
#define uword_bits
Definition: types.h:102
static void vlib_physmem_free(vlib_main_t *vm, void *p)
Definition: physmem_funcs.h:89
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
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:87
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:588
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:481
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:331
u32 instance
Definition: gre.api:57
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:492
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:1145
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
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:578
#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:163
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:1214
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:324