interface: refactor interface capabilities code, part 2
[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 (vnm, vd->hw_if_index,
576                                         vd->link_speed * 1000);
577       vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
578                                    VNET_HW_INTERFACE_FLAG_LINK_UP);
579     }
580   else
581     {
582       vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
583       vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
584     }
585 }
586
587 static u8
588 vmxnet3_queue_size_valid (u16 qsz)
589 {
590   if (qsz < 64 || qsz > 4096)
591     return 0;
592   if ((qsz % 64) != 0)
593     return 0;
594   return 1;
595 }
596
597 static u8
598 vmxnet3_tx_queue_num_valid (u16 num)
599 {
600   vlib_thread_main_t *tm = vlib_get_thread_main ();
601
602   if ((num > VMXNET3_TXQ_MAX) || (num > tm->n_vlib_mains))
603     return 0;
604   return 1;
605 }
606
607 static u8
608 vmxnet3_rx_queue_num_valid (u16 num)
609 {
610   if (num > VMXNET3_RXQ_MAX)
611     return 0;
612   return 1;
613 }
614
615 void
616 vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
617 {
618   vnet_main_t *vnm = vnet_get_main ();
619   vmxnet3_main_t *vmxm = &vmxnet3_main;
620   vnet_eth_interface_registration_t eir = {};
621
622   vmxnet3_device_t *vd;
623   vlib_pci_dev_handle_t h;
624   vnet_hw_if_caps_change_t cc = {};
625   clib_error_t *error = 0;
626   u16 qid;
627   u32 num_intr;
628
629   if (args->txq_num == 0)
630     args->txq_num = 1;
631   if (args->rxq_num == 0)
632     args->rxq_num = 1;
633   if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
634     {
635       args->rv = VNET_API_ERROR_INVALID_VALUE;
636       args->error =
637         clib_error_return (error, "number of rx queues must be <= %u",
638                            VMXNET3_RXQ_MAX);
639       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
640                 format_vlib_pci_addr, &args->addr,
641                 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
642       return;
643     }
644
645   if (!vmxnet3_tx_queue_num_valid (args->txq_num))
646     {
647       args->rv = VNET_API_ERROR_INVALID_VALUE;
648       args->error =
649         clib_error_return (error,
650                            "number of tx queues must be <= %u and <= number of "
651                            "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
652       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
653                 format_vlib_pci_addr, &args->addr,
654                 "number of tx queues must be <= %u and <= number of "
655                 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
656       return;
657     }
658   if (args->rxq_size == 0)
659     args->rxq_size = VMXNET3_NUM_RX_DESC;
660   if (args->txq_size == 0)
661     args->txq_size = VMXNET3_NUM_TX_DESC;
662
663   if (!vmxnet3_queue_size_valid (args->rxq_size) ||
664       !vmxnet3_queue_size_valid (args->txq_size))
665     {
666       args->rv = VNET_API_ERROR_INVALID_VALUE;
667       args->error =
668         clib_error_return (error,
669                            "queue size must be <= 4096, >= 64, "
670                            "and multiples of 64");
671       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
672                 format_vlib_pci_addr, &args->addr,
673                 "queue size must be <= 4096, >= 64, and multiples of 64");
674       return;
675     }
676
677   /* *INDENT-OFF* */
678   pool_foreach (vd, vmxm->devices)  {
679     if (vd->pci_addr.as_u32 == args->addr.as_u32)
680       {
681         args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
682         args->error =
683           clib_error_return (error, "%U: %s", format_vlib_pci_addr,
684                              &args->addr, "pci address in use");
685         vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
686                   format_vlib_pci_addr, &args->addr, "pci address in use");
687         return;
688       }
689   }
690   /* *INDENT-ON* */
691
692   if (args->bind)
693     {
694       error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
695       if (error)
696         {
697           args->rv = VNET_API_ERROR_INVALID_INTERFACE;
698           args->error =
699             clib_error_return (error, "%U: %s", format_vlib_pci_addr,
700                                &args->addr,
701                                "error encountered on binding pci device");
702           vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
703                     format_vlib_pci_addr, &args->addr,
704                     "error encountered on binding pci devicee");
705           return;
706         }
707     }
708
709   if ((error =
710        vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
711     {
712       args->rv = VNET_API_ERROR_INVALID_INTERFACE;
713       args->error =
714         clib_error_return (error, "%U: %s", format_vlib_pci_addr,
715                            &args->addr,
716                            "error encountered on pci device open");
717       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
718                 format_vlib_pci_addr, &args->addr,
719                 "error encountered on pci device open");
720       return;
721     }
722
723   /*
724    * Do not use vmxnet3_log_error prior to this line since the macro
725    * references vd->pci_dev_handle
726    */
727   pool_get (vmxm->devices, vd);
728   vd->num_tx_queues = args->txq_num;
729   vd->num_rx_queues = args->rxq_num;
730   vd->dev_instance = vd - vmxm->devices;
731   vd->per_interface_next_index = ~0;
732   vd->pci_addr = args->addr;
733
734   if (args->enable_elog)
735     vd->flags |= VMXNET3_DEVICE_F_ELOG;
736
737   vd->pci_dev_handle = h;
738   vd->numa_node = vlib_pci_get_numa_node (vm, h);
739   vd->num_intrs = vd->num_rx_queues + 1;        // +1 for the event interrupt
740
741   vlib_pci_set_private_data (vm, h, vd->dev_instance);
742
743   if ((error = vlib_pci_bus_master_enable (vm, h)))
744     {
745       vmxnet3_log_error (vd, "error encountered on pci bus master enable");
746       goto error;
747     }
748
749   if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
750     {
751       vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
752       goto error;
753     }
754
755   if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
756     {
757       vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
758       goto error;
759     }
760
761   num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
762   if (num_intr < vd->num_rx_queues + 1)
763     {
764       vmxnet3_log_error (vd,
765                          "No sufficient interrupt lines (%u) for rx queues",
766                          num_intr);
767       error =
768         clib_error_return (0,
769                            "No sufficient interrupt lines (%u) for rx queues",
770                            num_intr);
771       goto error;
772     }
773   if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
774                                                &vmxnet3_rxq_irq_handler)))
775     {
776       vmxnet3_log_error (vd,
777                          "error encountered on pci register msix handler 0");
778       goto error;
779     }
780
781   if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
782                                                &vmxnet3_event_irq_handler)))
783     {
784       vmxnet3_log_error (vd,
785                          "error encountered on pci register msix handler 1");
786       goto error;
787     }
788
789   if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
790     {
791       vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
792       goto error;
793     }
794
795   if ((error = vlib_pci_intr_enable (vm, h)))
796     {
797       vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
798       goto error;
799     }
800
801   if ((error = vmxnet3_device_init (vm, vd, args)))
802     {
803       vmxnet3_log_error (vd, "error encountered on device init");
804       goto error;
805     }
806
807   /* create interface */
808   eir.dev_class_index = vmxnet3_device_class.index;
809   eir.dev_instance = vd->dev_instance;
810   eir.address = vd->mac_addr;
811   eir.cb.flag_change = vmxnet3_flag_change;
812   vd->hw_if_index = vnet_eth_register_interface (vnm, &eir);
813
814   vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
815   vd->sw_if_index = sw->sw_if_index;
816   args->sw_if_index = sw->sw_if_index;
817
818   cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO |
819             VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
820   if (vd->gso_enable)
821     cc.val = cc.mask;
822   else
823     cc.val = VNET_HW_IF_CAP_INT_MODE;
824
825   vnet_hw_if_change_caps (vnm, vd->hw_if_index, &cc);
826
827   vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
828   /* Disable interrupts */
829   vmxnet3_disable_interrupt (vd);
830   vec_foreach_index (qid, vd->rxqs)
831   {
832     vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
833     u32 qi, fi;
834     vmxnet3_per_thread_data_t *ptd;
835
836     qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
837                                        VNET_HW_IF_RXQ_THREAD_ANY);
838     fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
839     vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
840     rxq->queue_index = qi;
841     rxq->thread_index =
842       vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
843     if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
844       {
845         ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
846         ptd->polling_q_count++;
847       }
848     rxq->buffer_pool_index =
849       vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
850     vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
851     vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
852   }
853
854   vec_foreach_index (qid, vd->txqs)
855     {
856       vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
857       txq->queue_index =
858         vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
859     }
860   for (u32 i = 0; i < vlib_get_n_threads (); i++)
861     {
862       u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
863       vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
864     }
865   vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
866
867   vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
868   vmxnet3_enable_interrupt (vd);
869
870   vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
871                                     vd->link_speed * 1000);
872   if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
873     vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
874                                  VNET_HW_INTERFACE_FLAG_LINK_UP);
875   else
876     vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
877   return;
878
879 error:
880   vmxnet3_delete_if (vm, vd);
881   args->rv = VNET_API_ERROR_INVALID_INTERFACE;
882   args->error = error;
883 }
884
885 void
886 vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * vd)
887 {
888   vnet_main_t *vnm = vnet_get_main ();
889   vmxnet3_main_t *vmxm = &vmxnet3_main;
890   u32 i, bi;
891   u16 desc_idx;
892
893   /* Quiesce the device */
894   vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
895
896   /* Reset the device */
897   vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
898
899   if (vd->hw_if_index)
900     {
901       vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
902       ethernet_delete_interface (vnm, vd->hw_if_index);
903     }
904
905   vlib_pci_device_close (vm, vd->pci_dev_handle);
906
907   /* *INDENT-OFF* */
908   vec_foreach_index (i, vd->rxqs)
909     {
910       vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, i);
911       u16 mask = rxq->size - 1;
912       u16 rid;
913       vmxnet3_per_thread_data_t *ptd =
914         vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
915
916       if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
917         {
918           ASSERT (ptd->polling_q_count != 0);
919           ptd->polling_q_count--;
920         }
921       for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
922         {
923           vmxnet3_rx_ring *ring;
924
925           ring = &rxq->rx_ring[rid];
926           desc_idx = (ring->consume + 1) & mask;
927           vlib_buffer_free_from_ring (vm, ring->bufs, desc_idx, rxq->size,
928                                       ring->fill);
929           vec_free (ring->bufs);
930           vlib_physmem_free (vm, rxq->rx_desc[rid]);
931         }
932       vlib_physmem_free (vm, rxq->rx_comp);
933     }
934   /* *INDENT-ON* */
935   vec_free (vd->rxqs);
936   vec_free (vd->rx_stats);
937
938   /* *INDENT-OFF* */
939   vec_foreach_index (i, vd->txqs)
940     {
941       vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, i);
942       u16 mask = txq->size - 1;
943       u16 end_idx;
944
945       desc_idx = txq->tx_ring.consume;
946       end_idx = txq->tx_ring.produce;
947       while (desc_idx != end_idx)
948         {
949           bi = txq->tx_ring.bufs[desc_idx];
950           vlib_buffer_free_no_next (vm, &bi, 1);
951           desc_idx++;
952           desc_idx &= mask;
953         }
954       clib_spinlock_free (&txq->lock);
955       vec_free (txq->tx_ring.bufs);
956       vlib_physmem_free (vm, txq->tx_desc);
957       vlib_physmem_free (vm, txq->tx_comp);
958     }
959   /* *INDENT-ON* */
960   vec_free (vd->txqs);
961   vec_free (vd->tx_stats);
962
963   vlib_physmem_free (vm, vd->driver_shared);
964   vlib_physmem_free (vm, vd->queues);
965   vlib_physmem_free (vm, vd->rss);
966
967   clib_error_free (vd->error);
968   clib_memset (vd, 0, sizeof (*vd));
969   pool_put (vmxm->devices, vd);
970
971 }
972
973 /*
974  * fd.io coding-style-patch-verification: ON
975  *
976  * Local Variables:
977  * eval: (c-set-style "gnu")
978  * End:
979  */