FD.io VPP  v19.08-27-gf4dcae4
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->lro_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  vnet_main_t *vnm = vnet_get_main ();
409  vmxnet3_main_t *vmxm = &vmxnet3_main;
410  clib_error_t *error = 0;
411  u32 ret, i, size;
413 
414  /* Quiesce the device */
415  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
416  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
417  if (ret != 0)
418  {
419  error = clib_error_return (0, "error on quiescing device rc (%u)", ret);
420  return error;
421  }
422 
423  /* Reset the device */
424  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
425  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
426  if (ret != 0)
427  {
428  error = clib_error_return (0, "error on resetting device rc (%u)", ret);
429  return error;
430  }
431 
432  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_VRRS);
433  vd->version = count_leading_zeros (ret);
434  vd->version = uword_bits - vd->version;
435 
436  if (vd->version == 0)
437  {
438  error = clib_error_return (0, "unsupported hardware version %u",
439  vd->version);
440  return error;
441  }
442 
443  /* cap support version to 3 */
445  1 << (clib_min (3, vd->version) - 1));
446 
447  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_UVRS);
448  if (ret & 1)
450  else
451  {
452  error = clib_error_return (0, "unsupported upt version %u", ret);
453  return error;
454  }
455 
456  /* LRO is only supported for version >= 3 */
457  if ((vmxm->lro_configured) && (vd->version >= 3))
458  {
459  vd->lro_enable = 1;
461  }
462 
463  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
464  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
465  if (ret & 1)
466  {
467  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
468  vd->link_speed = ret >> 16;
469  }
470  else
471  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
472 
473  /* Get the mac address */
474  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
475  clib_memcpy (vd->mac_addr, &ret, 4);
476  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACH);
477  clib_memcpy (vd->mac_addr + 4, &ret, 2);
478 
479  size = sizeof (vmxnet3_rx_queue) * vd->num_rx_queues +
480  sizeof (vmxnet3_tx_queue) * vd->num_tx_queues;
481 
482  vd->queues =
483  vlib_physmem_alloc_aligned_on_numa (vm, size, 512, vd->numa_node);
484  if (vd->queues == 0)
485  return vlib_physmem_last_error (vm);
486 
487  clib_memset (vd->queues, 0, size);
488 
489  if (vd->num_rx_queues > 1)
490  {
491  error = vmxnet3_rss_init (vm, vd);
492  if (error)
493  return error;
494  }
495 
496  for (i = 0; i < vd->num_rx_queues; i++)
497  {
498  error = vmxnet3_rxq_init (vm, vd, i, args->rxq_size);
499  if (error)
500  return error;
501  }
502 
503  for (i = 0; i < tm->n_vlib_mains; i++)
504  {
505  error = vmxnet3_txq_init (vm, vd, i, args->txq_size);
506  if (error)
507  return error;
508  }
509 
510  error = vmxnet3_provision_driver_shared (vm, vd);
511  if (error)
512  return error;
513 
514  vmxnet3_write_mac (vd);
515 
516  /* Activate device */
517  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
518  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
519  if (ret != 0)
520  {
521  error =
522  clib_error_return (0, "error on activating device rc (%u)", ret);
523  return error;
524  }
525 
526  return error;
527 }
528 
529 static void
531 {
532  vnet_main_t *vnm = vnet_get_main ();
533  vmxnet3_main_t *vmxm = &vmxnet3_main;
534  uword pd = vlib_pci_get_private_data (vm, h);
535  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
536  u16 qid = line;
537 
538  if (vec_len (vd->rxqs) > qid && vd->rxqs[qid].int_mode != 0)
540 }
541 
542 static void
544  u16 line)
545 {
546  vnet_main_t *vnm = vnet_get_main ();
547  vmxnet3_main_t *vmxm = &vmxnet3_main;
548  uword pd = vlib_pci_get_private_data (vm, h);
549  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
550  u32 ret;
551 
552  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
553  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
554  if (ret & 1)
555  {
556  vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
557  vd->link_speed = ret >> 16;
559  vd->link_speed * 1000);
562  }
563  else
564  {
565  vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
567  }
568 }
569 
570 static u8
572 {
573  if (qsz < 64 || qsz > 4096)
574  return 0;
575  if ((qsz % 64) != 0)
576  return 0;
577  return 1;
578 }
579 
580 static u8
582 {
584 
585  if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
586  return 0;
587  return 1;
588 }
589 
590 static u8
592 {
593  if (num > VMXNET3_RXQ_MAX)
594  return 0;
595  return 1;
596 }
597 
598 void
600 {
601  vnet_main_t *vnm = vnet_get_main ();
602  vmxnet3_main_t *vmxm = &vmxnet3_main;
603  vmxnet3_device_t *vd;
605  clib_error_t *error = 0;
606  u16 qid;
607  u32 num_intr;
608 
609  if (args->txq_num == 0)
610  args->txq_num = 1;
611  if (args->rxq_num == 0)
612  args->rxq_num = 1;
613  if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
614  {
615  args->rv = VNET_API_ERROR_INVALID_VALUE;
616  args->error =
617  clib_error_return (error, "number of rx queues must be <= %u",
619  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
620  format_vlib_pci_addr, &args->addr,
621  "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
622  return;
623  }
624 
625  if (!vmxnet3_tx_queue_num_valid (args->txq_num))
626  {
627  args->rv = VNET_API_ERROR_INVALID_VALUE;
628  args->error =
629  clib_error_return (error,
630  "number of tx queues must be <= %u and <= number of "
631  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
632  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
633  format_vlib_pci_addr, &args->addr,
634  "number of tx queues must be <= %u and <= number of "
635  "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
636  return;
637  }
638  if (args->rxq_size == 0)
640  if (args->txq_size == 0)
642 
643  if (!vmxnet3_queue_size_valid (args->rxq_size) ||
645  {
646  args->rv = VNET_API_ERROR_INVALID_VALUE;
647  args->error =
648  clib_error_return (error,
649  "queue size must be <= 4096, >= 64, "
650  "and multiples of 64");
651  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
652  format_vlib_pci_addr, &args->addr,
653  "queue size must be <= 4096, >= 64, and multiples of 64");
654  return;
655  }
656 
657  /* *INDENT-OFF* */
658  pool_foreach (vd, vmxm->devices, ({
659  if (vd->pci_addr.as_u32 == args->addr.as_u32)
660  {
661  args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
662  args->error =
663  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
664  &args->addr, "pci address in use");
665  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
666  format_vlib_pci_addr, &args->addr, "pci address in use");
667  return;
668  }
669  }));
670  /* *INDENT-ON* */
671 
672  if (args->bind)
673  {
674  error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
675  if (error)
676  {
677  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
678  args->error =
679  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
680  &args->addr,
681  "error encountered on binding pci device");
682  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
683  format_vlib_pci_addr, &args->addr,
684  "error encountered on binding pci devicee");
685  return;
686  }
687  }
688 
689  if ((error =
690  vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
691  {
692  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
693  args->error =
694  clib_error_return (error, "%U: %s", format_vlib_pci_addr,
695  &args->addr,
696  "error encountered on pci device open");
697  vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
698  format_vlib_pci_addr, &args->addr,
699  "error encountered on pci device open");
700  return;
701  }
702 
703  /*
704  * Do not use vmxnet3_log_error prior to this line since the macro
705  * references vd->pci_dev_handle
706  */
707  pool_get (vmxm->devices, vd);
708  vd->num_tx_queues = args->txq_num;
709  vd->num_rx_queues = args->rxq_num;
710  vd->dev_instance = vd - vmxm->devices;
711  vd->per_interface_next_index = ~0;
712  vd->pci_addr = args->addr;
713 
714  if (args->enable_elog)
715  vd->flags |= VMXNET3_DEVICE_F_ELOG;
716 
717  vd->pci_dev_handle = h;
718  vd->numa_node = vlib_pci_get_numa_node (vm, h);
719  vd->num_intrs = vd->num_rx_queues + 1; // +1 for the event interrupt
720 
721  vlib_pci_set_private_data (vm, h, vd->dev_instance);
722 
723  if ((error = vlib_pci_bus_master_enable (vm, h)))
724  {
725  vmxnet3_log_error (vd, "error encountered on pci bus master enable");
726  goto error;
727  }
728 
729  if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
730  {
731  vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
732  goto error;
733  }
734 
735  if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
736  {
737  vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
738  goto error;
739  }
740 
741  num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
742  if (num_intr < vd->num_rx_queues + 1)
743  {
744  vmxnet3_log_error (vd,
745  "No sufficient interrupt lines (%u) for rx queues",
746  num_intr);
747  goto error;
748  }
749  if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
751  {
752  vmxnet3_log_error (vd,
753  "error encountered on pci register msix handler 0");
754  goto error;
755  }
756 
757  if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
759  {
760  vmxnet3_log_error (vd,
761  "error encountered on pci register msix handler 1");
762  goto error;
763  }
764 
765  if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
766  {
767  vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
768  goto error;
769  }
770 
771  if ((error = vlib_pci_intr_enable (vm, h)))
772  {
773  vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
774  goto error;
775  }
776 
777  if ((error = vmxnet3_device_init (vm, vd, args)))
778  {
779  vmxnet3_log_error (vd, "error encountered on device init");
780  goto error;
781  }
782 
783  /* create interface */
785  vd->dev_instance, vd->mac_addr,
786  &vd->hw_if_index, vmxnet3_flag_change);
787 
788  if (error)
789  {
790  vmxnet3_log_error (vd,
791  "error encountered on ethernet register interface");
792  goto error;
793  }
794 
795  vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
796  vd->sw_if_index = sw->sw_if_index;
797  args->sw_if_index = sw->sw_if_index;
798 
799  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vd->hw_if_index);
801  if (vd->lro_enable)
803 
804  vnet_hw_interface_set_input_node (vnm, vd->hw_if_index,
805  vmxnet3_input_node.index);
806  /* Disable interrupts */
808  vec_foreach_index (qid, vd->rxqs)
809  {
810  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
811  u32 thread_index;
812  u32 numa_node;
813 
814  vnet_hw_interface_assign_rx_thread (vnm, vd->hw_if_index, qid, ~0);
815  thread_index = vnet_get_device_input_thread_index (vnm, vd->hw_if_index,
816  qid);
817  numa_node = vlib_mains[thread_index]->numa_node;
818  rxq->buffer_pool_index =
820  vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
821  vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
822  }
823  vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
825 
826  vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
827  vd->link_speed * 1000);
828  if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
829  vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
831  else
832  vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
833  return;
834 
835 error:
836  vmxnet3_delete_if (vm, vd);
837  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
838  args->error = error;
839 }
840 
841 void
843 {
844  vnet_main_t *vnm = vnet_get_main ();
845  vmxnet3_main_t *vmxm = &vmxnet3_main;
846  u32 i, bi;
847  u16 desc_idx, qid;
848 
849  /* Quiesce the device */
850  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
851 
852  /* Reset the device */
853  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
854 
855  if (vd->hw_if_index)
856  {
858  vec_foreach_index (qid, vd->rxqs)
861  }
862 
864 
865  /* *INDENT-OFF* */
866  vec_foreach_index (i, vd->rxqs)
867  {
868  vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
869  u16 mask = rxq->size - 1;
870  u16 rid;
871 
872  for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
873  {
874  vmxnet3_rx_ring *ring;
875 
876  ring = &rxq->rx_ring[rid];
877  desc_idx = (ring->consume + 1) & mask;
878  vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
879  ring->fill);
880  vec_free (ring->bufs);
881  vlib_physmem_free (vm, rxq->rx_desc[rid]);
882  }
883  vlib_physmem_free (vm, rxq->rx_comp);
884  }
885  /* *INDENT-ON* */
886  vec_free (vd->rxqs);
887  vec_free (vd->rx_stats);
888 
889  /* *INDENT-OFF* */
890  vec_foreach_index (i, vd->txqs)
891  {
892  vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
893  u16 mask = txq->size - 1;
894  u16 end_idx;
895 
896  desc_idx = txq->tx_ring.consume;
897  end_idx = txq->tx_ring.produce;
898  while (desc_idx != end_idx)
899  {
900  bi = txq->tx_ring.bufs[desc_idx];
901  vlib_buffer_free_no_next (vm, &bi, 1);
902  desc_idx++;
903  desc_idx &= mask;
904  }
905  clib_spinlock_free (&txq->lock);
906  vec_free (txq->tx_ring.bufs);
907  vlib_physmem_free (vm, txq->tx_desc);
908  vlib_physmem_free (vm, txq->tx_comp);
909  }
910  /* *INDENT-ON* */
911  vec_free (vd->txqs);
912  vec_free (vd->tx_stats);
913 
915  vlib_physmem_free (vm, vd->queues);
916  vlib_physmem_free (vm, vd->rss);
917 
918  clib_error_free (vd->error);
919  clib_memset (vd, 0, sizeof (*vd));
920  pool_put (vmxm->devices, vd);
921 
922  if (vd->lro_enable)
924 }
925 
926 /*
927  * fd.io coding-style-patch-verification: ON
928  *
929  * Local Variables:
930  * eval: (c-set-style "gnu")
931  * End:
932  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
static char * vmxnet3_tx_func_error_strings[]
Definition: vmxnet3.c:129
vmrglw vmrglh hi
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:842
#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
u32 flags
Definition: vhost_user.h:141
#define clib_min(x, y)
Definition: clib.h:295
u8 lro_configured
Definition: vmxnet3.h:595
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:324
#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
vnet_interface_main_t interface_main
Definition: vnet.h:56
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:1275
#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
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
void vmxnet3_create_if(vlib_main_t *vm, vmxnet3_create_if_args_t *args)
Definition: vmxnet3.c:599
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:883
static void vmxnet3_event_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:543
vmxnet3_tx_stats * tx_stats
Definition: vmxnet3.h:586
u32 numa_node
Definition: main.h:199
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:450
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:236
vlib_main_t ** vlib_mains
Definition: buffer.c:321
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:68
#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:493
static void vmxnet3_rxq_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
Definition: vmxnet3.c:530
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:505
#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:602
#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:61
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:912
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:514
uword size
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:571
clib_error_t * vlib_pci_bind_to_uio(vlib_main_t *vm, vlib_pci_addr_t *addr, char *uio_drv_name)
Definition: pci.c:386
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
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:286
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:826
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
#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:882
static void vmxnet3_disable_interrupt(vmxnet3_device_t *vd)
Definition: vmxnet3.c:265
vlib_main_t * vm
Definition: buffer.c:312
#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:341
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
vl_api_vxlan_gbp_api_tunnel_mode_t mode
Definition: vxlan_gbp.api:44
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
static u8 vmxnet3_rx_queue_num_valid(u16 num)
Definition: vmxnet3.c:591
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:278
u32 instance
Definition: gre.api:48
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:501
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:1146
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:581
#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:1215
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