vmxnet3: set RX interrupt pending only when needed
[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   vmxnet3_device_t *vd;
621   vlib_pci_dev_handle_t h;
622   clib_error_t *error = 0;
623   u16 qid;
624   u32 num_intr;
625
626   if (args->txq_num == 0)
627     args->txq_num = 1;
628   if (args->rxq_num == 0)
629     args->rxq_num = 1;
630   if (!vmxnet3_rx_queue_num_valid (args->rxq_num))
631     {
632       args->rv = VNET_API_ERROR_INVALID_VALUE;
633       args->error =
634         clib_error_return (error, "number of rx queues must be <= %u",
635                            VMXNET3_RXQ_MAX);
636       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
637                 format_vlib_pci_addr, &args->addr,
638                 "number of rx queues must be <= %u", VMXNET3_RXQ_MAX);
639       return;
640     }
641
642   if (!vmxnet3_tx_queue_num_valid (args->txq_num))
643     {
644       args->rv = VNET_API_ERROR_INVALID_VALUE;
645       args->error =
646         clib_error_return (error,
647                            "number of tx queues must be <= %u and <= number of "
648                            "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
649       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
650                 format_vlib_pci_addr, &args->addr,
651                 "number of tx queues must be <= %u and <= number of "
652                 "CPU's assigned to VPP", VMXNET3_TXQ_MAX);
653       return;
654     }
655   if (args->rxq_size == 0)
656     args->rxq_size = VMXNET3_NUM_RX_DESC;
657   if (args->txq_size == 0)
658     args->txq_size = VMXNET3_NUM_TX_DESC;
659
660   if (!vmxnet3_queue_size_valid (args->rxq_size) ||
661       !vmxnet3_queue_size_valid (args->txq_size))
662     {
663       args->rv = VNET_API_ERROR_INVALID_VALUE;
664       args->error =
665         clib_error_return (error,
666                            "queue size must be <= 4096, >= 64, "
667                            "and multiples of 64");
668       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
669                 format_vlib_pci_addr, &args->addr,
670                 "queue size must be <= 4096, >= 64, and multiples of 64");
671       return;
672     }
673
674   /* *INDENT-OFF* */
675   pool_foreach (vd, vmxm->devices)  {
676     if (vd->pci_addr.as_u32 == args->addr.as_u32)
677       {
678         args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
679         args->error =
680           clib_error_return (error, "%U: %s", format_vlib_pci_addr,
681                              &args->addr, "pci address in use");
682         vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
683                   format_vlib_pci_addr, &args->addr, "pci address in use");
684         return;
685       }
686   }
687   /* *INDENT-ON* */
688
689   if (args->bind)
690     {
691       error = vlib_pci_bind_to_uio (vm, &args->addr, (char *) "auto");
692       if (error)
693         {
694           args->rv = VNET_API_ERROR_INVALID_INTERFACE;
695           args->error =
696             clib_error_return (error, "%U: %s", format_vlib_pci_addr,
697                                &args->addr,
698                                "error encountered on binding pci device");
699           vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
700                     format_vlib_pci_addr, &args->addr,
701                     "error encountered on binding pci devicee");
702           return;
703         }
704     }
705
706   if ((error =
707        vlib_pci_device_open (vm, &args->addr, vmxnet3_pci_device_ids, &h)))
708     {
709       args->rv = VNET_API_ERROR_INVALID_INTERFACE;
710       args->error =
711         clib_error_return (error, "%U: %s", format_vlib_pci_addr,
712                            &args->addr,
713                            "error encountered on pci device open");
714       vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
715                 format_vlib_pci_addr, &args->addr,
716                 "error encountered on pci device open");
717       return;
718     }
719
720   /*
721    * Do not use vmxnet3_log_error prior to this line since the macro
722    * references vd->pci_dev_handle
723    */
724   pool_get (vmxm->devices, vd);
725   vd->num_tx_queues = args->txq_num;
726   vd->num_rx_queues = args->rxq_num;
727   vd->dev_instance = vd - vmxm->devices;
728   vd->per_interface_next_index = ~0;
729   vd->pci_addr = args->addr;
730
731   if (args->enable_elog)
732     vd->flags |= VMXNET3_DEVICE_F_ELOG;
733
734   vd->pci_dev_handle = h;
735   vd->numa_node = vlib_pci_get_numa_node (vm, h);
736   vd->num_intrs = vd->num_rx_queues + 1;        // +1 for the event interrupt
737
738   vlib_pci_set_private_data (vm, h, vd->dev_instance);
739
740   if ((error = vlib_pci_bus_master_enable (vm, h)))
741     {
742       vmxnet3_log_error (vd, "error encountered on pci bus master enable");
743       goto error;
744     }
745
746   if ((error = vlib_pci_map_region (vm, h, 0, (void **) &vd->bar[0])))
747     {
748       vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
749       goto error;
750     }
751
752   if ((error = vlib_pci_map_region (vm, h, 1, (void **) &vd->bar[1])))
753     {
754       vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
755       goto error;
756     }
757
758   num_intr = vlib_pci_get_num_msix_interrupts (vm, h);
759   if (num_intr < vd->num_rx_queues + 1)
760     {
761       vmxnet3_log_error (vd,
762                          "No sufficient interrupt lines (%u) for rx queues",
763                          num_intr);
764       error =
765         clib_error_return (0,
766                            "No sufficient interrupt lines (%u) for rx queues",
767                            num_intr);
768       goto error;
769     }
770   if ((error = vlib_pci_register_msix_handler (vm, h, 0, vd->num_rx_queues,
771                                                &vmxnet3_rxq_irq_handler)))
772     {
773       vmxnet3_log_error (vd,
774                          "error encountered on pci register msix handler 0");
775       goto error;
776     }
777
778   if ((error = vlib_pci_register_msix_handler (vm, h, vd->num_rx_queues, 1,
779                                                &vmxnet3_event_irq_handler)))
780     {
781       vmxnet3_log_error (vd,
782                          "error encountered on pci register msix handler 1");
783       goto error;
784     }
785
786   if ((error = vlib_pci_enable_msix_irq (vm, h, 0, vd->num_rx_queues + 1)))
787     {
788       vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
789       goto error;
790     }
791
792   if ((error = vlib_pci_intr_enable (vm, h)))
793     {
794       vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
795       goto error;
796     }
797
798   if ((error = vmxnet3_device_init (vm, vd, args)))
799     {
800       vmxnet3_log_error (vd, "error encountered on device init");
801       goto error;
802     }
803
804   /* create interface */
805   error = ethernet_register_interface (vnm, vmxnet3_device_class.index,
806                                        vd->dev_instance, vd->mac_addr,
807                                        &vd->hw_if_index, vmxnet3_flag_change);
808
809   if (error)
810     {
811       vmxnet3_log_error (vd,
812                          "error encountered on ethernet register interface");
813       goto error;
814     }
815
816   vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
817   vd->sw_if_index = sw->sw_if_index;
818   args->sw_if_index = sw->sw_if_index;
819
820   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vd->hw_if_index);
821   hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE;
822   if (vd->gso_enable)
823     {
824       hw->caps |= (VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
825                    VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
826                    VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM);
827     }
828
829   vnet_hw_if_set_input_node (vnm, vd->hw_if_index, vmxnet3_input_node.index);
830   /* Disable interrupts */
831   vmxnet3_disable_interrupt (vd);
832   vec_foreach_index (qid, vd->rxqs)
833   {
834     vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, qid);
835     u32 qi, fi;
836     vmxnet3_per_thread_data_t *ptd;
837
838     qi = vnet_hw_if_register_rx_queue (vnm, vd->hw_if_index, qid,
839                                        VNET_HW_IF_RXQ_THREAD_ANY);
840     fi = vlib_pci_get_msix_file_index (vm, vd->pci_dev_handle, qid);
841     vnet_hw_if_set_rx_queue_file_index (vnm, qi, fi);
842     rxq->queue_index = qi;
843     rxq->thread_index =
844       vnet_hw_if_get_rx_queue_thread_index (vnm, rxq->queue_index);
845     if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
846       {
847         ptd = vec_elt_at_index (vmxm->per_thread_data, rxq->thread_index);
848         ptd->polling_q_count++;
849       }
850     rxq->buffer_pool_index =
851       vnet_hw_if_get_rx_queue_numa_node (vnm, rxq->queue_index);
852     vmxnet3_rxq_refill_ring0 (vm, vd, rxq);
853     vmxnet3_rxq_refill_ring1 (vm, vd, rxq);
854   }
855
856   vec_foreach_index (qid, vd->txqs)
857     {
858       vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, qid);
859       txq->queue_index =
860         vnet_hw_if_register_tx_queue (vnm, vd->hw_if_index, qid);
861     }
862   for (u32 i = 0; i < vlib_get_n_threads (); i++)
863     {
864       u32 qi = vd->txqs[i % vd->num_tx_queues].queue_index;
865       vnet_hw_if_tx_queue_assign_thread (vnm, qi, i);
866     }
867   vnet_hw_if_update_runtime_data (vnm, vd->hw_if_index);
868
869   vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
870   vmxnet3_enable_interrupt (vd);
871
872   vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
873                                     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  */