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