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