vmxnet3: fix clang initialization error
[vpp.git] / src / plugins / vmxnet3 / cli.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 #include <stdint.h>
18 #include <net/if.h>
19 #include <sys/ioctl.h>
20 #include <inttypes.h>
21
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vlib/pci/pci.h>
25 #include <vnet/ethernet/ethernet.h>
26
27 #include <vmxnet3/vmxnet3.h>
28
29 static clib_error_t *
30 vmxnet3_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
31                            vlib_cli_command_t * cmd)
32 {
33   unformat_input_t _line_input, *line_input = &_line_input;
34   vmxnet3_create_if_args_t args;
35   u32 tmp;
36
37   /* Get a line of input. */
38   if (!unformat_user (input, unformat_line_input, line_input))
39     return 0;
40
41   memset (&args, 0, sizeof (args));
42   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
43     {
44       if (unformat (line_input, "%U", unformat_vlib_pci_addr, &args.addr))
45         ;
46       else if (unformat (line_input, "elog"))
47         args.enable_elog = 1;
48       else if (unformat (line_input, "rx-queue-size %u", &tmp))
49         args.rxq_size = tmp;
50       else if (unformat (line_input, "tx-queue-size %u", &tmp))
51         args.txq_size = tmp;
52       else
53         return clib_error_return (0, "unknown input `%U'",
54                                   format_unformat_error, input);
55     }
56   unformat_free (line_input);
57
58
59   vmxnet3_create_if (vm, &args);
60
61   return args.error;
62 }
63
64 /* *INDENT-OFF* */
65 VLIB_CLI_COMMAND (vmxnet3_create_command, static) = {
66   .path = "create interface vmxnet3",
67   .short_help = "create interface vmxnet3 <pci-address>"
68                 "[rx-queue-size <size>] [tx-queue-size <size>]",
69   .function = vmxnet3_create_command_fn,
70 };
71 /* *INDENT-ON* */
72
73 static clib_error_t *
74 vmxnet3_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
75                            vlib_cli_command_t * cmd)
76 {
77   unformat_input_t _line_input, *line_input = &_line_input;
78   u32 sw_if_index = ~0;
79   vnet_hw_interface_t *hw;
80   vmxnet3_main_t *vmxm = &vmxnet3_main;
81   vmxnet3_device_t *vd;
82   vnet_main_t *vnm = vnet_get_main ();
83
84   /* Get a line of input. */
85   if (!unformat_user (input, unformat_line_input, line_input))
86     return 0;
87
88   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
89     {
90       if (unformat (line_input, "sw_if_index %d", &sw_if_index))
91         ;
92       else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
93                          vnm, &sw_if_index))
94         ;
95       else
96         return clib_error_return (0, "unknown input `%U'",
97                                   format_unformat_error, input);
98     }
99   unformat_free (line_input);
100
101   if (sw_if_index == ~0)
102     return clib_error_return (0,
103                               "please specify interface name or sw_if_index");
104
105   hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
106   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
107     return clib_error_return (0, "not a vmxnet3 interface");
108
109   vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
110
111   vmxnet3_delete_if (vm, vd);
112
113   return 0;
114 }
115
116 /* *INDENT-OFF* */
117 VLIB_CLI_COMMAND (vmxnet3_delete_command, static) = {
118   .path = "delete interface vmxnet3",
119   .short_help = "delete interface vmxnet3 "
120     "{<interface> | sw_if_index <sw_idx>}",
121   .function = vmxnet3_delete_command_fn,
122 };
123 /* *INDENT-ON* */
124
125 static clib_error_t *
126 vmxnet3_test_command_fn (vlib_main_t * vm, unformat_input_t * input,
127                          vlib_cli_command_t * cmd)
128 {
129   unformat_input_t _line_input, *line_input = &_line_input;
130   u32 sw_if_index = ~0;
131   vnet_hw_interface_t *hw;
132   vmxnet3_main_t *vmxm = &vmxnet3_main;
133   vmxnet3_device_t *vd;
134   vnet_main_t *vnm = vnet_get_main ();
135   int enable_elog = 0, disable_elog = 0;
136
137   /* Get a line of input. */
138   if (!unformat_user (input, unformat_line_input, line_input))
139     return 0;
140
141   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
142     {
143       if (unformat (line_input, "sw_if_index %d", &sw_if_index))
144         ;
145       else if (unformat (line_input, "elog-on"))
146         enable_elog = 1;
147       else if (unformat (line_input, "elog-off"))
148         disable_elog = 1;
149       else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
150                          vnm, &sw_if_index))
151         ;
152       else
153         return clib_error_return (0, "unknown input `%U'",
154                                   format_unformat_error, input);
155     }
156   unformat_free (line_input);
157
158   if (sw_if_index == ~0)
159     return clib_error_return (0,
160                               "please specify interface name or sw_if_index");
161
162   hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
163   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
164     return clib_error_return (0, "not a vmxnet3 interface");
165
166   vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
167
168   if (enable_elog)
169     vd->flags |= VMXNET3_DEVICE_F_ELOG;
170
171   if (disable_elog)
172     vd->flags &= ~VMXNET3_DEVICE_F_ELOG;
173
174   return 0;
175 }
176
177 /* *INDENT-OFF* */
178 VLIB_CLI_COMMAND (vmxnet3_test_command, static) = {
179   .path = "test vmxnet3",
180   .short_help = "test vmxnet3 <interface> | sw_if_index <sw_idx> [irq] "
181     "[elog-on] [elog-off]",
182   .function = vmxnet3_test_command_fn,
183 };
184 /* *INDENT-ON* */
185
186 static void
187 show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
188 {
189   u32 i, desc_idx;
190   vmxnet3_device_t *vd;
191   vnet_main_t *vnm = &vnet_main;
192   vmxnet3_main_t *vmxm = &vmxnet3_main;
193   vnet_hw_interface_t *hi;
194   vmxnet3_rxq_t *rxq;
195   vmxnet3_rx_desc *rxd;
196   vmxnet3_rx_comp *rx_comp;
197   vmxnet3_txq_t *txq;
198   vmxnet3_tx_desc *txd;
199   vmxnet3_tx_comp *tx_comp;
200   u16 qid;
201
202   if (!hw_if_indices)
203     return;
204
205   for (i = 0; i < vec_len (hw_if_indices); i++)
206     {
207       hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
208       vd = vec_elt_at_index (vmxm->devices, hi->dev_instance);
209       vlib_cli_output (vm, "Interface: %s (ifindex %d)",
210                        hi->name, hw_if_indices[i]);
211       vlib_cli_output (vm, "  Version: %u", vd->version);
212       vlib_cli_output (vm, "  PCI Address: %U", format_vlib_pci_addr,
213                        &vd->pci_addr);
214       vlib_cli_output (vm, "  Mac Address: %U", format_ethernet_address,
215                        vd->mac_addr);
216       vlib_cli_output (vm, "  hw if index: %u", vd->hw_if_index);
217       vlib_cli_output (vm, "  Device instance: %u", vd->dev_instance);
218       vlib_cli_output (vm, "  Number of interrupts: %u", vd->num_intrs);
219
220       vec_foreach_index (qid, vd->rxqs)
221       {
222         rxq = vec_elt_at_index (vd->rxqs, qid);
223         u16 rid;
224
225         vlib_cli_output (vm, "  Queue %u (RX)", qid);
226         vlib_cli_output (vm, "    RX completion next index %u",
227                          rxq->rx_comp_ring.next);
228         for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
229           {
230             vmxnet3_rx_ring *ring = &rxq->rx_ring[rid];
231
232             vlib_cli_output (vm,
233                              "    ring %u size %u fill %u "
234                              "consume %u produce %u", rid,
235                              rxq->size, ring->fill, ring->consume,
236                              ring->produce);
237             if (show_descr)
238               {
239                 vlib_cli_output (vm, "RX descriptors table");
240                 vlib_cli_output (vm, "  %5s  %18s  %10s",
241                                  "slot", "address", "flags");
242                 for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
243                   {
244                     rxd = &rxq->rx_desc[rid][desc_idx];
245                     vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x",
246                                      desc_idx, rxd->address, rxd->flags);
247                   }
248                 vlib_cli_output (vm, "RX completion descriptors table");
249                 vlib_cli_output (vm, "  %5s  %10s  %10s  %10s  %10s",
250                                  "slot", "index", "rss", "len", "flags");
251                 for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
252                   {
253                     rx_comp = &rxq->rx_comp[desc_idx];
254                     vlib_cli_output (vm, "  %5u  0x%08x  %10u  %10u  0x%08x",
255                                      desc_idx, rx_comp->index, rx_comp->rss,
256                                      rx_comp->len, rx_comp->flags);
257                   }
258               }
259           }
260       }
261
262       vec_foreach_index (qid, vd->rxqs)
263       {
264         txq = vec_elt_at_index (vd->txqs, 0);
265         vlib_cli_output (vm, "  Queue %u (TX)", qid);
266         vlib_cli_output (vm, "    TX completion next index %u",
267                          txq->tx_comp_ring.next);
268         vlib_cli_output (vm, "    size %u consume %u produce %u",
269                          txq->size, txq->tx_ring.consume,
270                          txq->tx_ring.produce);
271         if (show_descr)
272           {
273             vlib_cli_output (vm, "TX descriptors table");
274             vlib_cli_output (vm, "  %5s  %18s  %10s  %10s",
275                              "slot", "address", "flags0", "flags1");
276             for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
277               {
278                 txd = &txq->tx_desc[desc_idx];
279                 vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x  0x%08x",
280                                  desc_idx, txd->address, txd->flags[0],
281                                  txd->flags[1]);
282               }
283             vlib_cli_output (vm, "TX completion descriptors table");
284             vlib_cli_output (vm, "  %5s  %10s  %10s",
285                              "slot", "index", "flags");
286             for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
287               {
288                 tx_comp = &txq->tx_comp[desc_idx];
289                 vlib_cli_output (vm, "  %5u  0x%08x  0x%08x",
290                                  desc_idx, tx_comp->index, tx_comp->flags);
291               }
292           }
293       }
294     }
295 }
296
297 static clib_error_t *
298 show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
299                  vlib_cli_command_t * cmd)
300 {
301   vmxnet3_main_t *vmxm = &vmxnet3_main;
302   vnet_main_t *vnm = &vnet_main;
303   vmxnet3_device_t *vd;
304   clib_error_t *error = 0;
305   u32 hw_if_index, *hw_if_indices = 0;
306   vnet_hw_interface_t *hi;
307   u8 show_descr = 0;
308
309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
310     {
311       if (unformat
312           (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
313         {
314           hi = vnet_get_hw_interface (vnm, hw_if_index);
315           if (vmxnet3_device_class.index != hi->dev_class_index)
316             {
317               error = clib_error_return (0, "unknown input `%U'",
318                                          format_unformat_error, input);
319               goto done;
320             }
321           vec_add1 (hw_if_indices, hw_if_index);
322         }
323       else if (unformat (input, "descriptors") || unformat (input, "desc"))
324         show_descr = 1;
325       else
326         {
327           error = clib_error_return (0, "unknown input `%U'",
328                                      format_unformat_error, input);
329           goto done;
330         }
331     }
332
333   if (vec_len (hw_if_indices) == 0)
334     {
335       pool_foreach (vd, vmxm->devices,
336                     vec_add1 (hw_if_indices, vd->hw_if_index);
337         );
338     }
339
340   show_vmxnet3 (vm, hw_if_indices, show_descr);
341
342 done:
343   vec_free (hw_if_indices);
344   return error;
345 }
346
347 /* *INDENT-OFF* */
348 VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
349   .path = "show vmxnet3",
350   .short_help = "show vmxnet3 [<interface>]",
351   .function = show_vmxnet3_fn,
352 };
353 /* *INDENT-ON* */
354
355 clib_error_t *
356 vmxnet3_cli_init (vlib_main_t * vm)
357 {
358   /* initialize binary API */
359   vmxnet3_plugin_api_hookup (vm);
360
361   return 0;
362 }
363
364 VLIB_INIT_FUNCTION (vmxnet3_cli_init);
365
366 /*
367  * fd.io coding-style-patch-verification: ON
368  *
369  * Local Variables:
370  * eval: (c-set-style "gnu")
371  * End:
372  */