FD.io VPP  v21.06
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>
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
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  {
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  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
544 
545  if (vec_len (vd->rxqs) > qid && vd->rxqs[qid].int_mode != 0)
547 }
548 
549 static void
551  u16 line)
552 {
553  vnet_main_t *vnm = vnet_get_main ();
554  vmxnet3_main_t *vmxm = &vmxnet3_main;
555  uword pd = vlib_pci_get_private_data (vm, h);
556  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
557  u32 ret;
558 
559  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
560  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
561  if (ret & 1)
562  {
563  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
564  vd->link_speed = ret >> 16;
566  vd->link_speed * 1000);
569  }
570  else
571  {
572  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
574  }
575 }
576 
577 static u8
579 {
580  if (qsz < 64 || qsz > 4096)
581  return 0;
582  if ((qsz % 64) != 0)
583  return 0;
584  return 1;
585 }
586 
587 static u8
589 {
591 
592  if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
593  return 0;
594  return 1;
595 }
596 
597 static u8
599 {
600  if (num > VMXNET3_RXQ_MAX)
601  return 0;
602  return 1;
603 }
604 
605 void
607 {
608  vnet_main_t *vnm = vnet_get_main ();
609  vmxnet3_main_t *vmxm = &vmxnet3_main;
610  vmxnet3_device_t *vd;
612  clib_error_t *error = 0;
613  u16 qid;
614  u32 num_intr;
615 
616  if (args->txq_num == 0)
617  args->txq_num = 1;
618  if (args->rxq_num == 0)
619  args->rxq_num = 1;
620  if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
621  {
622  args->rv = VNET_API_ERROR_INVALID_VALUE;
623  args->error =
624  clib_error_return (error, "number of rx queues must be <= %u",
626  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
627  format_vlib_pci_addr, &args->addr,
628  "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
629  return;
630  }
631 
632  if (!vmxnet3_tx_queue_num_valid (args->txq_num))
633  {
634  args->rv = VNET_API_ERROR_INVALID_VALUE;
635  args->error =
636  clib_error_return (error,
637  "number of tx queues must be <= %u and <= number of "
638  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
639  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
640  format_vlib_pci_addr, &args->addr,
641  "number of tx queues must be <= %u and <= number of "
642  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
643  return;
644  }
645  if (args->rxq_size == 0)
647  if (args->txq_size == 0)
649 
650  if (!vmxnet3_queue_size_valid (args->rxq_size) ||
652  {
653  args->rv = VNET_API_ERROR_INVALID_VALUE;
654  args->error =
655  clib_error_return (error,
656  "queue size must be <= 4096, >= 64, "
657  "and multiples of 64");
658  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
659  format_vlib_pci_addr, &args->addr,
660  "queue size must be <= 4096, >= 64, and multiples of 64");
661  return;
662  }
663 
664  /* *INDENT-OFF* */
665  pool_foreach (vd, vmxm->devices) {
666  if (vd->pci_addr.as_u32 == args->addr.as_u32)
667  {
668  args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
669  args->error =
670  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
671  &args->addr, "pci address in use");
672  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
673  format_vlib_pci_addr, &args->addr, "pci address in use");
674  return;
675  }
676  }
677  /* *INDENT-ON* */
678 
679  if (args->bind)
680  {
681  error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
682  if (error)
683  {
684  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
685  args->error =
686  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
687  &args->addr,
688  "error encountered on binding pci device");
689  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
690  format_vlib_pci_addr, &args->addr,
691  "error encountered on binding pci devicee");
692  return;
693  }
694  }
695 
696  if ((error =
697  vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
698  {
699  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
700  args->error =
701  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
702  &args->addr,
703  "error encountered on pci device open");
704  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
705  format_vlib_pci_addr, &args->addr,
706  "error encountered on pci device open");
707  return;
708  }
709 
710  /*
711  * Do not use vmxnet3_log_error prior to this line since the macro
712  * references vd->pci_dev_handle
713  */
714  pool_get (vmxm->devices, vd);
715  vd->num_tx_queues = args->txq_num;
716  vd->num_rx_queues = args->rxq_num;
717  vd->dev_instance = vd - vmxm->devices;
718  vd->per_interface_next_index = ~0;
719  vd->pci_addr = args->addr;
720 
721  if (args->enable_elog)
722  vd->flags |= VMXNET3_DEVICE_F_ELOG;
723 
724  vd->pci_dev_handle = h;
725  vd->numa_node = vlib_pci_get_numa_node (vm, h);
726  vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
727 
729 
730  if ((error = vlib_pci_bus_master_enable (vm, h)))
731  {
732  vmxnet3_log_error (vd, "error encountered on pci bus master enable");
733  goto error;
734  }
735 
736  if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
737  {
738  vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
739  goto error;
740  }
741 
742  if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
743  {
744  vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
745  goto error;
746  }
747 
748  num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
749  if (num_intr < vd->num_rx_queues + 1)
750  {
751  vmxnet3_log_error (vd,
752  "No sufficient interrupt lines (%u) for rx queues",
753  num_intr);
754  error =
756  "No sufficient interrupt lines (%u) for rx queues",
757  num_intr);
758  goto error;
759  }
760  if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
762  {
763  vmxnet3_log_error (vd,
764  "error encountered on pci register msix handler 0");
765  goto error;
766  }
767 
768  if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
770  {
771  vmxnet3_log_error (vd,
772  "error encountered on pci register msix handler 1");
773  goto error;
774  }
775 
776  if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
777  {
778  vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
779  goto error;
780  }
781 
782  if ((error = vlib_pci_intr_enable (vm, h)))
783  {
784  vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
785  goto error;
786  }
787 
788  if ((error = vmxnet3_device_init (vm, vd, args)))
789  {
790  vmxnet3_log_error (vd, "error encountered on device init");
791  goto error;
792  }
793 
794  /* create interface */
796  vd->dev_instance, vd->mac_addr,
798 
799  if (error)
800  {
801  vmxnet3_log_error (vd,
802  "error encountered on ethernet register interface");
803  goto error;
804  }
805 
807  vd->sw_if_index = sw->sw_if_index;
808  args->sw_if_index = sw->sw_if_index;
809 
812  if (vd->gso_enable)
813  {
817  }
818 
820  /* Disable interrupts */
822  vec_foreach_index (qid, vd->rxqs)
823  {
824  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
825  u32 qi, fi;
826 
827  qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
829  fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
831  rxq->queue_index = qi;
832  rxq->buffer_pool_index =
834  vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
835  vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
836  }
838 
839  vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
841 
843  vd->link_speed * 1000);
844  if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
847  else
849  return;
850 
851 error:
852  vmxnet3_delete_if (vm, vd);
853  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
854  args->error = error;
855 }
856 
857 void
859 {
860  vnet_main_t *vnm = vnet_get_main ();
861  vmxnet3_main_t *vmxm = &vmxnet3_main;
862  u32 i, bi;
863  u16 desc_idx;
864 
865  /* Quiesce the device */
866  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
867 
868  /* Reset the device */
869  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
870 
871  if (vd->hw_if_index)
872  {
875  }
876 
878 
879  /* *INDENT-OFF* */
880  vec_foreach_index (i, vd->rxqs)
881  {
882  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
883  u16 mask = rxq->size - 1;
884  u16 rid;
885 
886  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
887  {
888  vmxnet3_rx_ring *ring;
889 
890  ring = &rxq->rx_ring[rid];
891  desc_idx = (ring->consume + 1) & mask;
892  vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
893  ring->fill);
894  vec_free (ring->bufs);
895  vlib_physmem_free (vm, rxq->rx_desc[rid]);
896  }
897  vlib_physmem_free (vm, rxq->rx_comp);
898  }
899  /* *INDENT-ON* */
900  vec_free (vd->rxqs);
901  vec_free (vd->rx_stats);
902 
903  /* *INDENT-OFF* */
904  vec_foreach_index (i, vd->txqs)
905  {
906  vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
907  u16 mask = txq->size - 1;
908  u16 end_idx;
909 
910  desc_idx = txq->tx_ring.consume;
911  end_idx = txq->tx_ring.produce;
912  while (desc_idx != end_idx)
913  {
914  bi = txq->tx_ring.bufs[desc_idx];
915  vlib_buffer_free_no_next (vm, &bi, 1);
916  desc_idx++;
917  desc_idx &= mask;
918  }
919  clib_spinlock_free (&txq->lock);
920  vec_free (txq->tx_ring.bufs);
921  vlib_physmem_free (vm, txq->tx_desc);
922  vlib_physmem_free (vm, txq->tx_comp);
923  }
924  /* *INDENT-ON* */
925  vec_free (vd->txqs);
926  vec_free (vd->tx_stats);
927 
929  vlib_physmem_free (vm, vd->queues);
930  vlib_physmem_free (vm, vd->rss);
931 
932  clib_error_free (vd->error);
933  clib_memset (vd, 0, sizeof (*vd));
934  pool_put (vmxm->devices, vd);
935 
936 }
937 
938 /*
939  * fd.io coding-style-patch-verification: ON
940  *
941  * Local Variables:
942  * eval: (c-set-style "gnu")
943  * End:
944  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
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:689
void vmxnet3_delete_if(vlib_main_t *vm, vmxnet3_device_t *vd)
Definition: vmxnet3.c:858
#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:342
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:632
#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
#define VMXNET3_REG_TXPROD
Definition: vmxnet3.h:98
#define count_leading_zeros(x)
Definition: clib.h:160
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
vmxnet3_rx_desc * rx_desc[VMXNET3_RX_RING_SIZE]
Definition: vmxnet3.h:521
static_always_inline uword vmxnet3_dma_addr(vlib_main_t *vm, vmxnet3_device_t *vd, void *p)
Definition: vmxnet3.h:671
unsigned long u64
Definition: types.h:89
vlib_pci_dev_handle_t pci_dev_handle
Definition: vmxnet3.h:565
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:547
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
#define VMXNET3_RXQ_MAX
Definition: vmxnet3.h:91
vlib_pci_addr_t pci_addr
Definition: vmxnet3.h:566
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:606
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
static void vmxnet3_event_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:550
static_always_inline void vnet_hw_if_rx_queue_set_int_pending(vnet_main_t *vnm, u32 queue_index)
vmxnet3_tx_stats * tx_stats
Definition: vmxnet3.h:587
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
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:513
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:255
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:1177
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:653
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
uword vlib_pci_get_msix_file_index(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 index)
Definition: pci.c:917
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
unsigned int u32
Definition: types.h:88
#define clib_memcpy(d, s, n)
Definition: string.h:197
static_always_inline u32 vmxnet3_reg_read(vmxnet3_device_t *vd, u8 bar, u32 addr)
Definition: vmxnet3.h:660
#define VMXNET3_VERSION_SELECT
Definition: vmxnet3.h:167
vmxnet3_rxq_t * rxqs
Definition: vmxnet3.h:570
vlib_log_class_t log_default
Definition: vmxnet3.h:595
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:567
#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:582
vnet_main_t * vnet_get_main(void)
u32 queue_index
Definition: vmxnet3.h:519
vlib_pci_addr_t addr
Definition: vmxnet3.h:602
static_always_inline u8 vnet_hw_if_get_rx_queue_numa_node(vnet_main_t *vnm, u32 queue_index)
#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: cJSON.c:88
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
u32 vnet_hw_if_register_rx_queue(vnet_main_t *vnm, u32 hw_if_index, u32 queue_id, u32 thread_index)
Definition: rx_queue.c:64
#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:578
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:523
u32 size
Definition: vhost_user.h:125
vmxnet3_tx_comp_ring tx_comp_ring
Definition: vmxnet3.h:552
#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:305
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:550
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
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
void vnet_hw_if_update_runtime_data(vnet_main_t *vnm, u32 hw_if_index)
Definition: runtime.c:58
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:584
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:999
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:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
vl_api_pnat_mask_t mask
Definition: pnat.api:45
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:578
#define PCI_VENDOR_ID_VMWARE
Definition: vmxnet3.c:25
u32 per_interface_next_index
Definition: vmxnet3.h:559
VNET_DEVICE_CLASS(vmxnet3_device_class,)
vmxnet3_txq_t * txqs
Definition: vmxnet3.h:571
clib_error_t * error
Definition: vmxnet3.h:580
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:583
#define VMXNET3_RXF_GEN
Definition: vmxnet3.h:119
format_function_t format_vmxnet3_device
Definition: vmxnet3.h:631
#define VMXNET3_REG_DSAH
Definition: vmxnet3.h:107
vmxnet3_rx_stats * rx_stats
Definition: vmxnet3.h:588
#define VMXNET3_TXCF_GEN
Definition: vmxnet3.h:155
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
vl_api_ip4_address_t hi
Definition: arp.api:37
static u8 vmxnet3_rx_queue_num_valid(u16 num)
Definition: vmxnet3.c:598
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:491
u32 reg_txprod
Definition: vmxnet3.h:546
void vnet_hw_if_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: rx_queue.c:157
#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:549
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
node node_index
vmxnet3_rx_comp * rx_comp
Definition: vmxnet3.h:522
#define clib_error_free(e)
Definition: error.h:86
vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE]
Definition: vmxnet3.h:520
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
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
vmxnet3_device_t * devices
Definition: vmxnet3.h:593
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:735
#define vmxnet3_log_error(dev, f,...)
Definition: vmxnet3.h:640
static u8 vmxnet3_tx_queue_num_valid(u16 num)
Definition: vmxnet3.c:588
#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:551
#define VNET_HW_IF_RXQ_THREAD_ANY
Definition: interface.h:598
clib_error_t * error
Definition: vmxnet3.h:613
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 clib_error_t * vmxnet3_txq_init(vlib_main_t *vm, vmxnet3_device_t *vd, u16 qid, u16 qsz)
Definition: vmxnet3.c:322
void vnet_hw_if_set_rx_queue_file_index(vnet_main_t *vnm, u32 queue_index, u32 file_index)
Definition: rx_queue.c:144
u16 vendor_id
Definition: pci.h:127
format_function_t format_vlib_pci_addr
Definition: pci.h:326