Line data Source code
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 0 : vmxnet3_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
31 : vlib_cli_command_t * cmd)
32 : {
33 0 : unformat_input_t _line_input, *line_input = &_line_input;
34 : vmxnet3_create_if_args_t args;
35 : u32 size;
36 :
37 : /* Get a line of input. */
38 0 : if (!unformat_user (input, unformat_line_input, line_input))
39 0 : return 0;
40 :
41 0 : clib_memset (&args, 0, sizeof (args));
42 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
43 : {
44 0 : if (unformat (line_input, "%U", unformat_vlib_pci_addr, &args.addr))
45 : ;
46 0 : else if (unformat (line_input, "gso"))
47 0 : args.enable_gso = 1;
48 0 : else if (unformat (line_input, "elog"))
49 0 : args.enable_elog = 1;
50 0 : else if (unformat (line_input, "bind force"))
51 0 : args.bind = VMXNET3_BIND_FORCE;
52 0 : else if (unformat (line_input, "bind"))
53 0 : args.bind = VMXNET3_BIND_DEFAULT;
54 0 : else if (unformat (line_input, "rx-queue-size %u", &size))
55 0 : args.rxq_size = size;
56 0 : else if (unformat (line_input, "tx-queue-size %u", &size))
57 0 : args.txq_size = size;
58 0 : else if (unformat (line_input, "num-tx-queues %u", &size))
59 0 : args.txq_num = size;
60 0 : else if (unformat (line_input, "num-rx-queues %u", &size))
61 0 : args.rxq_num = size;
62 : else
63 : {
64 0 : unformat_free (line_input);
65 0 : return clib_error_return (0, "unknown input `%U'",
66 : format_unformat_error, input);
67 : }
68 : }
69 0 : unformat_free (line_input);
70 :
71 0 : vmxnet3_create_if (vm, &args);
72 0 : if (args.error == 0)
73 0 : vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
74 : vnet_get_main (), args.sw_if_index);
75 :
76 0 : return args.error;
77 : }
78 :
79 : /* *INDENT-OFF* */
80 11199 : VLIB_CLI_COMMAND (vmxnet3_create_command, static) = {
81 : .path = "create interface vmxnet3",
82 : .short_help =
83 : "create interface vmxnet3 <pci-address>"
84 : " [rx-queue-size <size>] [tx-queue-size <size>]"
85 : " [num-tx-queues <number>] [num-rx-queues <number>] [bind [force]]"
86 : " [gso]",
87 : .function = vmxnet3_create_command_fn,
88 : };
89 : /* *INDENT-ON* */
90 :
91 : static clib_error_t *
92 0 : vmxnet3_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
93 : vlib_cli_command_t * cmd)
94 : {
95 0 : unformat_input_t _line_input, *line_input = &_line_input;
96 0 : u32 sw_if_index = ~0;
97 : vnet_hw_interface_t *hw;
98 0 : vmxnet3_main_t *vmxm = &vmxnet3_main;
99 : vmxnet3_device_t *vd;
100 0 : vnet_main_t *vnm = vnet_get_main ();
101 :
102 : /* Get a line of input. */
103 0 : if (!unformat_user (input, unformat_line_input, line_input))
104 0 : return 0;
105 :
106 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
107 : {
108 0 : if (unformat (line_input, "sw_if_index %d", &sw_if_index))
109 : ;
110 0 : else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
111 : vnm, &sw_if_index))
112 : ;
113 : else
114 0 : return clib_error_return (0, "unknown input `%U'",
115 : format_unformat_error, input);
116 : }
117 0 : unformat_free (line_input);
118 :
119 0 : if (sw_if_index == ~0)
120 0 : return clib_error_return (0,
121 : "please specify interface name or sw_if_index");
122 :
123 0 : hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
124 0 : if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
125 0 : return clib_error_return (0, "not a vmxnet3 interface");
126 :
127 0 : vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
128 :
129 0 : vmxnet3_delete_if (vm, vd);
130 :
131 0 : return 0;
132 : }
133 :
134 : /* *INDENT-OFF* */
135 11199 : VLIB_CLI_COMMAND (vmxnet3_delete_command, static) = {
136 : .path = "delete interface vmxnet3",
137 : .short_help = "delete interface vmxnet3 "
138 : "{<interface> | sw_if_index <sw_idx>}",
139 : .function = vmxnet3_delete_command_fn,
140 : };
141 : /* *INDENT-ON* */
142 :
143 : static clib_error_t *
144 0 : vmxnet3_test_command_fn (vlib_main_t * vm, unformat_input_t * input,
145 : vlib_cli_command_t * cmd)
146 : {
147 0 : unformat_input_t _line_input, *line_input = &_line_input;
148 0 : u32 sw_if_index = ~0;
149 : vnet_hw_interface_t *hw;
150 0 : vmxnet3_main_t *vmxm = &vmxnet3_main;
151 : vmxnet3_device_t *vd;
152 0 : vnet_main_t *vnm = vnet_get_main ();
153 0 : int enable_elog = 0, disable_elog = 0;
154 :
155 : /* Get a line of input. */
156 0 : if (!unformat_user (input, unformat_line_input, line_input))
157 0 : return 0;
158 :
159 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
160 : {
161 0 : if (unformat (line_input, "sw_if_index %d", &sw_if_index))
162 : ;
163 0 : else if (unformat (line_input, "elog-on"))
164 0 : enable_elog = 1;
165 0 : else if (unformat (line_input, "elog-off"))
166 0 : disable_elog = 1;
167 0 : else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
168 : vnm, &sw_if_index))
169 : ;
170 : else
171 0 : return clib_error_return (0, "unknown input `%U'",
172 : format_unformat_error, input);
173 : }
174 0 : unformat_free (line_input);
175 :
176 0 : if (sw_if_index == ~0)
177 0 : return clib_error_return (0,
178 : "please specify interface name or sw_if_index");
179 :
180 0 : hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
181 0 : if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
182 0 : return clib_error_return (0, "not a vmxnet3 interface");
183 :
184 0 : vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
185 :
186 0 : if (enable_elog)
187 0 : vd->flags |= VMXNET3_DEVICE_F_ELOG;
188 :
189 0 : if (disable_elog)
190 0 : vd->flags &= ~VMXNET3_DEVICE_F_ELOG;
191 :
192 0 : return 0;
193 : }
194 :
195 : /* *INDENT-OFF* */
196 11199 : VLIB_CLI_COMMAND (vmxnet3_test_command, static) = {
197 : .path = "test vmxnet3",
198 : .short_help = "test vmxnet3 <interface> | sw_if_index <sw_idx> [irq] "
199 : "[elog-on] [elog-off]",
200 : .function = vmxnet3_test_command_fn,
201 : };
202 : /* *INDENT-ON* */
203 :
204 : static void
205 0 : show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr,
206 : u8 show_one_table, u32 which, u8 show_one_slot, u32 slot)
207 : {
208 : u32 i, desc_idx;
209 : vmxnet3_device_t *vd;
210 0 : vnet_main_t *vnm = &vnet_main;
211 0 : vmxnet3_main_t *vmxm = &vmxnet3_main;
212 : vnet_hw_interface_t *hi;
213 : vmxnet3_rxq_t *rxq;
214 : vmxnet3_rx_desc *rxd;
215 : vmxnet3_rx_comp *rx_comp;
216 : vmxnet3_txq_t *txq;
217 : vmxnet3_tx_desc *txd;
218 : vmxnet3_tx_comp *tx_comp;
219 : u16 qid;
220 :
221 0 : vlib_cli_output (vm, "Global:");
222 0 : for (u32 tid = 0; tid <= vlib_num_workers (); tid++)
223 : {
224 0 : vmxnet3_per_thread_data_t *ptd =
225 0 : vec_elt_at_index (vmxm->per_thread_data, tid);
226 0 : vlib_cli_output (vm, " Thread %u: polling queue count %u", tid,
227 : ptd->polling_q_count);
228 : }
229 :
230 0 : if (!hw_if_indices)
231 0 : return;
232 :
233 0 : for (i = 0; i < vec_len (hw_if_indices); i++)
234 : {
235 0 : hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
236 0 : vd = vec_elt_at_index (vmxm->devices, hi->dev_instance);
237 0 : vlib_cli_output (vm, "Interface: %U (ifindex %d)",
238 0 : format_vnet_hw_if_index_name, vnm, hw_if_indices[i],
239 0 : hw_if_indices[i]);
240 0 : vlib_cli_output (vm, " Version: %u", vd->version);
241 0 : vlib_cli_output (vm, " GSO enable: %u", vd->gso_enable);
242 0 : vlib_cli_output (vm, " PCI Address: %U", format_vlib_pci_addr,
243 : &vd->pci_addr);
244 0 : vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address,
245 0 : vd->mac_addr);
246 0 : vlib_cli_output (vm, " hw if index: %u", vd->hw_if_index);
247 0 : vlib_cli_output (vm, " Device instance: %u", vd->dev_instance);
248 0 : vlib_cli_output (vm, " Number of interrupts: %u", vd->num_intrs);
249 :
250 0 : vec_foreach_index (qid, vd->rxqs)
251 : {
252 0 : rxq = vec_elt_at_index (vd->rxqs, qid);
253 : u16 rid;
254 :
255 0 : vlib_cli_output (vm, " Queue %u (RX)", qid);
256 0 : vlib_cli_output (vm, " RX completion next index %u",
257 0 : rxq->rx_comp_ring.next);
258 0 : vlib_cli_output (vm, " RX completion generation flag 0x%x",
259 : rxq->rx_comp_ring.gen);
260 :
261 : /* RX descriptors tables */
262 0 : for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
263 : {
264 0 : vmxnet3_rx_ring *ring = &rxq->rx_ring[rid];
265 :
266 0 : vlib_cli_output (vm,
267 : " ring %u size %u fill %u "
268 : "consume %u produce %u", rid,
269 0 : rxq->size, ring->fill, ring->consume,
270 0 : ring->produce);
271 0 : if (show_descr)
272 : {
273 0 : vlib_cli_output (vm, "RX descriptors table");
274 0 : vlib_cli_output (vm, " %5s %18s %10s",
275 : "slot", "address", "flags");
276 0 : for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
277 : {
278 0 : rxd = &rxq->rx_desc[rid][desc_idx];
279 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
280 : desc_idx, rxd->address, rxd->flags);
281 : }
282 : }
283 0 : else if (show_one_table)
284 : {
285 0 : if (((which == VMXNET3_SHOW_RX_DESC0) && (rid == 0)) ||
286 0 : ((which == VMXNET3_SHOW_RX_DESC1) && (rid == 1)))
287 : {
288 0 : vlib_cli_output (vm, "RX descriptors table");
289 0 : vlib_cli_output (vm, " %5s %18s %10s",
290 : "slot", "address", "flags");
291 0 : if (show_one_slot)
292 : {
293 0 : rxd = &rxq->rx_desc[rid][slot];
294 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
295 : slot, rxd->address, rxd->flags);
296 : }
297 : else
298 0 : for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
299 : {
300 0 : rxd = &rxq->rx_desc[rid][desc_idx];
301 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
302 : desc_idx, rxd->address,
303 : rxd->flags);
304 : }
305 : }
306 : }
307 : }
308 :
309 : /* RX completion table */
310 0 : if (show_descr)
311 : {
312 0 : vlib_cli_output (vm, "RX completion descriptors table");
313 0 : vlib_cli_output (vm, " %5s %10s %10s %10s %10s",
314 : "slot", "index", "rss", "len", "flags");
315 0 : for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
316 : {
317 0 : rx_comp = &rxq->rx_comp[desc_idx];
318 0 : vlib_cli_output (vm, " %5u 0x%08x %10u %10u 0x%08x",
319 : desc_idx, rx_comp->index, rx_comp->rss,
320 : rx_comp->len, rx_comp->flags);
321 : }
322 : }
323 0 : else if (show_one_table)
324 : {
325 0 : if (which == VMXNET3_SHOW_RX_COMP)
326 : {
327 0 : vlib_cli_output (vm, "RX completion descriptors table");
328 0 : vlib_cli_output (vm, " %5s %10s %10s %10s %10s",
329 : "slot", "index", "rss", "len", "flags");
330 0 : if (show_one_slot)
331 : {
332 0 : rx_comp = &rxq->rx_comp[slot];
333 0 : vlib_cli_output (vm, " %5u 0x%08x %10u %10u 0x%08x",
334 : slot, rx_comp->index, rx_comp->rss,
335 : rx_comp->len, rx_comp->flags);
336 : }
337 : else
338 0 : for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
339 : {
340 0 : rx_comp = &rxq->rx_comp[desc_idx];
341 0 : vlib_cli_output (vm,
342 : " %5u 0x%08x %10u %10u 0x%08x",
343 : desc_idx, rx_comp->index, rx_comp->rss,
344 : rx_comp->len, rx_comp->flags);
345 : }
346 : }
347 : }
348 : }
349 :
350 0 : vec_foreach_index (qid, vd->txqs)
351 : {
352 0 : txq = vec_elt_at_index (vd->txqs, qid);
353 0 : vlib_cli_output (vm, " Queue %u (TX)", qid);
354 0 : vlib_cli_output (vm, " TX completion next index %u",
355 0 : txq->tx_comp_ring.next);
356 0 : vlib_cli_output (vm, " TX completion generation flag 0x%x",
357 : txq->tx_comp_ring.gen);
358 0 : vlib_cli_output (vm, " size %u consume %u produce %u",
359 0 : txq->size, txq->tx_ring.consume,
360 0 : txq->tx_ring.produce);
361 0 : if (show_descr)
362 : {
363 0 : vlib_cli_output (vm, "TX descriptors table");
364 0 : vlib_cli_output (vm, " %5s %18s %10s %10s",
365 : "slot", "address", "flags0", "flags1");
366 0 : for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
367 : {
368 0 : txd = &txq->tx_desc[desc_idx];
369 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x 0x%08x",
370 : desc_idx, txd->address, txd->flags[0],
371 : txd->flags[1]);
372 : }
373 :
374 0 : vlib_cli_output (vm, "TX completion descriptors table");
375 0 : vlib_cli_output (vm, " %5s %10s %10s",
376 : "slot", "index", "flags");
377 0 : for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
378 : {
379 0 : tx_comp = &txq->tx_comp[desc_idx];
380 0 : vlib_cli_output (vm, " %5u 0x%08x 0x%08x",
381 : desc_idx, tx_comp->index, tx_comp->flags);
382 : }
383 : }
384 0 : else if (show_one_table)
385 : {
386 0 : if (which == VMXNET3_SHOW_TX_DESC)
387 : {
388 0 : vlib_cli_output (vm, "TX descriptors table");
389 0 : vlib_cli_output (vm, " %5s %18s %10s %10s",
390 : "slot", "address", "flags0", "flags1");
391 0 : if (show_one_slot)
392 : {
393 0 : txd = &txq->tx_desc[slot];
394 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x 0x%08x",
395 : slot, txd->address, txd->flags[0],
396 : txd->flags[1]);
397 : }
398 : else
399 0 : for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
400 : {
401 0 : txd = &txq->tx_desc[desc_idx];
402 0 : vlib_cli_output (vm, " %5u 0x%016llx 0x%08x 0x%08x",
403 : desc_idx, txd->address, txd->flags[0],
404 : txd->flags[1]);
405 : }
406 : }
407 0 : else if (which == VMXNET3_SHOW_TX_COMP)
408 : {
409 0 : vlib_cli_output (vm, "TX completion descriptors table");
410 0 : vlib_cli_output (vm, " %5s %10s %10s",
411 : "slot", "index", "flags");
412 0 : if (show_one_slot)
413 : {
414 0 : tx_comp = &txq->tx_comp[slot];
415 0 : vlib_cli_output (vm, " %5u 0x%08x 0x%08x",
416 : slot, tx_comp->index, tx_comp->flags);
417 : }
418 : else
419 0 : for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
420 : {
421 0 : tx_comp = &txq->tx_comp[desc_idx];
422 0 : vlib_cli_output (vm, " %5u 0x%08x 0x%08x",
423 : desc_idx, tx_comp->index,
424 : tx_comp->flags);
425 : }
426 : }
427 : }
428 : }
429 : }
430 : }
431 :
432 : static clib_error_t *
433 0 : show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
434 : vlib_cli_command_t * cmd)
435 : {
436 0 : vmxnet3_main_t *vmxm = &vmxnet3_main;
437 0 : vnet_main_t *vnm = &vnet_main;
438 : vmxnet3_device_t *vd;
439 0 : clib_error_t *error = 0;
440 0 : u32 hw_if_index, *hw_if_indices = 0;
441 0 : vnet_hw_interface_t *hi = 0;
442 0 : u8 show_descr = 0, show_one_table = 0, show_one_slot = 0;
443 0 : u32 which = ~0, slot;
444 :
445 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
446 : {
447 0 : if (unformat
448 : (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
449 : {
450 0 : hi = vnet_get_hw_interface (vnm, hw_if_index);
451 0 : if (vmxnet3_device_class.index != hi->dev_class_index)
452 : {
453 0 : error = clib_error_return (0, "unknown input `%U'",
454 : format_unformat_error, input);
455 0 : goto done;
456 : }
457 0 : vec_add1 (hw_if_indices, hw_if_index);
458 : }
459 0 : else if (unformat (input, "desc"))
460 0 : show_descr = 1;
461 0 : else if (hi)
462 : {
463 0 : vmxnet3_device_t *vd =
464 0 : vec_elt_at_index (vmxm->devices, hi->dev_instance);
465 :
466 0 : if (unformat (input, "rx-comp"))
467 : {
468 0 : show_one_table = 1;
469 0 : which = VMXNET3_SHOW_RX_COMP;
470 0 : if (unformat (input, "%u", &slot))
471 : {
472 0 : vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
473 :
474 0 : if (slot >= rxq->size)
475 : {
476 0 : error = clib_error_return (0,
477 : "slot size must be < rx queue "
478 : "size %u", rxq->size);
479 0 : goto done;
480 : }
481 0 : show_one_slot = 1;
482 : }
483 : }
484 0 : else if (unformat (input, "rx-desc-0"))
485 : {
486 0 : show_one_table = 1;
487 0 : which = VMXNET3_SHOW_RX_DESC0;
488 0 : if (unformat (input, "%u", &slot))
489 : {
490 0 : vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
491 :
492 0 : if (slot >= rxq->size)
493 : {
494 0 : error = clib_error_return (0,
495 : "slot size must be < rx queue "
496 : "size %u", rxq->size);
497 0 : goto done;
498 : }
499 0 : show_one_slot = 1;
500 : }
501 : }
502 0 : else if (unformat (input, "rx-desc-1"))
503 : {
504 0 : show_one_table = 1;
505 0 : which = VMXNET3_SHOW_RX_DESC1;
506 0 : if (unformat (input, "%u", &slot))
507 : {
508 0 : vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
509 :
510 0 : if (slot >= rxq->size)
511 : {
512 0 : error = clib_error_return (0,
513 : "slot size must be < rx queue "
514 : "size %u", rxq->size);
515 0 : goto done;
516 : }
517 0 : show_one_slot = 1;
518 : }
519 : }
520 0 : else if (unformat (input, "tx-comp"))
521 : {
522 0 : show_one_table = 1;
523 0 : which = VMXNET3_SHOW_TX_COMP;
524 0 : if (unformat (input, "%u", &slot))
525 : {
526 0 : vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
527 :
528 0 : if (slot >= txq->size)
529 : {
530 0 : error = clib_error_return (0,
531 : "slot size must be < tx queue "
532 : "size %u", txq->size);
533 0 : goto done;
534 : }
535 0 : show_one_slot = 1;
536 : }
537 : }
538 0 : else if (unformat (input, "tx-desc"))
539 : {
540 0 : show_one_table = 1;
541 0 : which = VMXNET3_SHOW_TX_DESC;
542 0 : if (unformat (input, "%u", &slot))
543 : {
544 0 : vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
545 :
546 0 : if (slot >= txq->size)
547 : {
548 0 : error = clib_error_return (0,
549 : "slot size must be < tx queue "
550 : "size %u", txq->size);
551 0 : goto done;
552 : }
553 0 : show_one_slot = 1;
554 : }
555 : }
556 : else
557 : {
558 0 : error = clib_error_return (0, "unknown input `%U'",
559 : format_unformat_error, input);
560 0 : goto done;
561 : }
562 : }
563 : else
564 : {
565 0 : error = clib_error_return (0, "unknown input `%U'",
566 : format_unformat_error, input);
567 0 : goto done;
568 : }
569 : }
570 :
571 0 : if (vec_len (hw_if_indices) == 0)
572 : {
573 0 : pool_foreach (vd, vmxm->devices)
574 0 : vec_add1 (hw_if_indices, vd->hw_if_index);
575 : }
576 :
577 0 : show_vmxnet3 (vm, hw_if_indices, show_descr, show_one_table, which,
578 : show_one_slot, slot);
579 :
580 0 : done:
581 0 : vec_free (hw_if_indices);
582 0 : return error;
583 : }
584 :
585 : /* *INDENT-OFF* */
586 11199 : VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
587 : .path = "show vmxnet3",
588 : .short_help = "show vmxnet3 [[<interface>] ([desc] | ([rx-comp] | "
589 : "[rx-desc-0] | [rx-desc-1] | [tx-comp] | [tx-desc]) [<slot>])]",
590 : .function = show_vmxnet3_fn,
591 : };
592 : /* *INDENT-ON* */
593 :
594 : clib_error_t *
595 559 : vmxnet3_cli_init (vlib_main_t * vm)
596 : {
597 559 : vmxnet3_main_t *vmxm = &vmxnet3_main;
598 559 : vlib_thread_main_t *tm = vlib_get_thread_main ();
599 :
600 : /* initialize binary API */
601 559 : vmxnet3_plugin_api_hookup (vm);
602 :
603 559 : vmxm->log_default = vlib_log_register_class ("vmxnet3", 0);
604 :
605 559 : vec_validate (vmxm->per_thread_data, tm->n_vlib_mains - 1);
606 559 : return 0;
607 : }
608 :
609 1119 : VLIB_INIT_FUNCTION (vmxnet3_cli_init);
610 :
611 : /*
612 : * fd.io coding-style-patch-verification: ON
613 : *
614 : * Local Variables:
615 : * eval: (c-set-style "gnu")
616 : * End:
617 : */
|