vmxnet3: per interface gso support
[vpp.git] / src / plugins / vmxnet3 / cli.c
index 1e4ac4a..fd97c36 100644 (file)
@@ -32,23 +32,31 @@ vmxnet3_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
 {
   unformat_input_t _line_input, *line_input = &_line_input;
   vmxnet3_create_if_args_t args;
-  u32 tmp;
+  u32 size;
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
 
-  memset (&args, 0, sizeof (args));
+  clib_memset (&args, 0, sizeof (args));
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
       if (unformat (line_input, "%U", unformat_vlib_pci_addr, &args.addr))
        ;
+      else if (unformat (line_input, "gso"))
+       args.enable_gso = 1;
       else if (unformat (line_input, "elog"))
        args.enable_elog = 1;
-      else if (unformat (line_input, "rx-queue-size %u", &tmp))
-       args.rxq_size = tmp;
-      else if (unformat (line_input, "tx-queue-size %u", &tmp))
-       args.txq_size = tmp;
+      else if (unformat (line_input, "bind"))
+       args.bind = 1;
+      else if (unformat (line_input, "rx-queue-size %u", &size))
+       args.rxq_size = size;
+      else if (unformat (line_input, "tx-queue-size %u", &size))
+       args.txq_size = size;
+      else if (unformat (line_input, "num-tx-queues %u", &size))
+       args.txq_num = size;
+      else if (unformat (line_input, "num-rx-queues %u", &size))
+       args.rxq_num = size;
       else
        return clib_error_return (0, "unknown input `%U'",
                                  format_unformat_error, input);
@@ -65,7 +73,9 @@ vmxnet3_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
 VLIB_CLI_COMMAND (vmxnet3_create_command, static) = {
   .path = "create interface vmxnet3",
   .short_help = "create interface vmxnet3 <pci-address>"
-                "[rx-queue-size <size>] [tx-queue-size <size>]",
+                " [rx-queue-size <size>] [tx-queue-size <size>]"
+                " [num-tx-queues <number>] [num-rx-queues <number>] [bind]"
+                " [gso]",
   .function = vmxnet3_create_command_fn,
 };
 /* *INDENT-ON* */
@@ -102,7 +112,7 @@ vmxnet3_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a vmxnet3 interface");
 
@@ -159,7 +169,7 @@ vmxnet3_test_command_fn (vlib_main_t * vm, unformat_input_t * input,
     return clib_error_return (0,
                              "please specify interface name or sw_if_index");
 
-  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
   if (hw == NULL || vmxnet3_device_class.index != hw->dev_class_index)
     return clib_error_return (0, "not a vmxnet3 interface");
 
@@ -184,7 +194,8 @@ VLIB_CLI_COMMAND (vmxnet3_test_command, static) = {
 /* *INDENT-ON* */
 
 static void
-show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
+show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr,
+             u8 show_one_table, u32 which, u8 show_one_slot, u32 slot)
 {
   u32 i, desc_idx;
   vmxnet3_device_t *vd;
@@ -210,6 +221,7 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
                       format_vnet_hw_if_index_name, vnm, hw_if_indices[i],
                       hw_if_indices[i]);
       vlib_cli_output (vm, "  Version: %u", vd->version);
+      vlib_cli_output (vm, "  GSO enable: %u", vd->gso_enable);
       vlib_cli_output (vm, "  PCI Address: %U", format_vlib_pci_addr,
                       &vd->pci_addr);
       vlib_cli_output (vm, "  Mac Address: %U", format_ethernet_address,
@@ -226,6 +238,10 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
        vlib_cli_output (vm, "  Queue %u (RX)", qid);
        vlib_cli_output (vm, "    RX completion next index %u",
                         rxq->rx_comp_ring.next);
+       vlib_cli_output (vm, "    RX completion generation flag 0x%x",
+                        rxq->rx_comp_ring.gen);
+
+       /* RX descriptors tables */
        for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
          {
            vmxnet3_rx_ring *ring = &rxq->rx_ring[rid];
@@ -246,26 +262,82 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
                    vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x",
                                     desc_idx, rxd->address, rxd->flags);
                  }
+             }
+           else if (show_one_table)
+             {
+               if (((which == VMXNET3_SHOW_RX_DESC0) && (rid == 0)) ||
+                   ((which == VMXNET3_SHOW_RX_DESC1) && (rid == 1)))
+                 {
+                   vlib_cli_output (vm, "RX descriptors table");
+                   vlib_cli_output (vm, "  %5s  %18s  %10s",
+                                    "slot", "address", "flags");
+                   if (show_one_slot)
+                     {
+                       rxd = &rxq->rx_desc[rid][slot];
+                       vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x",
+                                        slot, rxd->address, rxd->flags);
+                     }
+                   else
+                     for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
+                       {
+                         rxd = &rxq->rx_desc[rid][desc_idx];
+                         vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x",
+                                          desc_idx, rxd->address,
+                                          rxd->flags);
+                       }
+                 }
+             }
+         }
+
+       /* RX completion table */
+       if (show_descr)
+         {
+           vlib_cli_output (vm, "RX completion descriptors table");
+           vlib_cli_output (vm, "  %5s  %10s  %10s  %10s  %10s",
+                            "slot", "index", "rss", "len", "flags");
+           for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
+             {
+               rx_comp = &rxq->rx_comp[desc_idx];
+               vlib_cli_output (vm, "  %5u  0x%08x  %10u  %10u  0x%08x",
+                                desc_idx, rx_comp->index, rx_comp->rss,
+                                rx_comp->len, rx_comp->flags);
+             }
+         }
+       else if (show_one_table)
+         {
+           if (which == VMXNET3_SHOW_RX_COMP)
+             {
                vlib_cli_output (vm, "RX completion descriptors table");
                vlib_cli_output (vm, "  %5s  %10s  %10s  %10s  %10s",
                                 "slot", "index", "rss", "len", "flags");
-               for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
+               if (show_one_slot)
                  {
-                   rx_comp = &rxq->rx_comp[desc_idx];
+                   rx_comp = &rxq->rx_comp[slot];
                    vlib_cli_output (vm, "  %5u  0x%08x  %10u  %10u  0x%08x",
-                                    desc_idx, rx_comp->index, rx_comp->rss,
+                                    slot, rx_comp->index, rx_comp->rss,
                                     rx_comp->len, rx_comp->flags);
                  }
+               else
+                 for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
+                   {
+                     rx_comp = &rxq->rx_comp[desc_idx];
+                     vlib_cli_output (vm,
+                                      "  %5u  0x%08x  %10u  %10u  0x%08x",
+                                      desc_idx, rx_comp->index, rx_comp->rss,
+                                      rx_comp->len, rx_comp->flags);
+                   }
              }
          }
       }
 
-      vec_foreach_index (qid, vd->rxqs)
+      vec_foreach_index (qid, vd->txqs)
       {
-       txq = vec_elt_at_index (vd->txqs, 0);
+       txq = vec_elt_at_index (vd->txqs, qid);
        vlib_cli_output (vm, "  Queue %u (TX)", qid);
        vlib_cli_output (vm, "    TX completion next index %u",
                         txq->tx_comp_ring.next);
+       vlib_cli_output (vm, "    TX completion generation flag 0x%x",
+                        txq->tx_comp_ring.gen);
        vlib_cli_output (vm, "    size %u consume %u produce %u",
                         txq->size, txq->tx_ring.consume,
                         txq->tx_ring.produce);
@@ -281,6 +353,7 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
                                 desc_idx, txd->address, txd->flags[0],
                                 txd->flags[1]);
              }
+
            vlib_cli_output (vm, "TX completion descriptors table");
            vlib_cli_output (vm, "  %5s  %10s  %10s",
                             "slot", "index", "flags");
@@ -291,6 +364,50 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
                                 desc_idx, tx_comp->index, tx_comp->flags);
              }
          }
+       else if (show_one_table)
+         {
+           if (which == VMXNET3_SHOW_TX_DESC)
+             {
+               vlib_cli_output (vm, "TX descriptors table");
+               vlib_cli_output (vm, "  %5s  %18s  %10s  %10s",
+                                "slot", "address", "flags0", "flags1");
+               if (show_one_slot)
+                 {
+                   txd = &txq->tx_desc[slot];
+                   vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x  0x%08x",
+                                    slot, txd->address, txd->flags[0],
+                                    txd->flags[1]);
+                 }
+               else
+                 for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
+                   {
+                     txd = &txq->tx_desc[desc_idx];
+                     vlib_cli_output (vm, "  %5u  0x%016llx  0x%08x  0x%08x",
+                                      desc_idx, txd->address, txd->flags[0],
+                                      txd->flags[1]);
+                   }
+             }
+           else if (which == VMXNET3_SHOW_TX_COMP)
+             {
+               vlib_cli_output (vm, "TX completion descriptors table");
+               vlib_cli_output (vm, "  %5s  %10s  %10s",
+                                "slot", "index", "flags");
+               if (show_one_slot)
+                 {
+                   tx_comp = &txq->tx_comp[slot];
+                   vlib_cli_output (vm, "  %5u  0x%08x  0x%08x",
+                                    slot, tx_comp->index, tx_comp->flags);
+                 }
+               else
+                 for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
+                   {
+                     tx_comp = &txq->tx_comp[desc_idx];
+                     vlib_cli_output (vm, "  %5u  0x%08x  0x%08x",
+                                      desc_idx, tx_comp->index,
+                                      tx_comp->flags);
+                   }
+             }
+         }
       }
     }
 }
@@ -304,8 +421,9 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
   vmxnet3_device_t *vd;
   clib_error_t *error = 0;
   u32 hw_if_index, *hw_if_indices = 0;
-  vnet_hw_interface_t *hi;
-  u8 show_descr = 0;
+  vnet_hw_interface_t *hi = 0;
+  u8 show_descr = 0, show_one_table = 0, show_one_slot = 0;
+  u32 which = ~0, slot;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -321,8 +439,110 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
            }
          vec_add1 (hw_if_indices, hw_if_index);
        }
-      else if (unformat (input, "descriptors") || unformat (input, "desc"))
+      else if (unformat (input, "desc"))
        show_descr = 1;
+      else if (hi)
+       {
+         vmxnet3_device_t *vd =
+           vec_elt_at_index (vmxm->devices, hi->dev_instance);
+
+         if (unformat (input, "rx-comp"))
+           {
+             show_one_table = 1;
+             which = VMXNET3_SHOW_RX_COMP;
+             if (unformat (input, "%u", &slot))
+               {
+                 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
+
+                 if (slot >= rxq->size)
+                   {
+                     error = clib_error_return (0,
+                                                "slot size must be < rx queue "
+                                                "size %u", rxq->size);
+                     goto done;
+                   }
+                 show_one_slot = 1;
+               }
+           }
+         else if (unformat (input, "rx-desc-0"))
+           {
+             show_one_table = 1;
+             which = VMXNET3_SHOW_RX_DESC0;
+             if (unformat (input, "%u", &slot))
+               {
+                 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
+
+                 if (slot >= rxq->size)
+                   {
+                     error = clib_error_return (0,
+                                                "slot size must be < rx queue "
+                                                "size %u", rxq->size);
+                     goto done;
+                   }
+                 show_one_slot = 1;
+               }
+           }
+         else if (unformat (input, "rx-desc-1"))
+           {
+             show_one_table = 1;
+             which = VMXNET3_SHOW_RX_DESC1;
+             if (unformat (input, "%u", &slot))
+               {
+                 vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
+
+                 if (slot >= rxq->size)
+                   {
+                     error = clib_error_return (0,
+                                                "slot size must be < rx queue "
+                                                "size %u", rxq->size);
+                     goto done;
+                   }
+                 show_one_slot = 1;
+               }
+           }
+         else if (unformat (input, "tx-comp"))
+           {
+             show_one_table = 1;
+             which = VMXNET3_SHOW_TX_COMP;
+             if (unformat (input, "%u", &slot))
+               {
+                 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
+
+                 if (slot >= txq->size)
+                   {
+                     error = clib_error_return (0,
+                                                "slot size must be < tx queue "
+                                                "size %u", txq->size);
+                     goto done;
+                   }
+                 show_one_slot = 1;
+               }
+           }
+         else if (unformat (input, "tx-desc"))
+           {
+             show_one_table = 1;
+             which = VMXNET3_SHOW_TX_DESC;
+             if (unformat (input, "%u", &slot))
+               {
+                 vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
+
+                 if (slot >= txq->size)
+                   {
+                     error = clib_error_return (0,
+                                                "slot size must be < tx queue "
+                                                "size %u", txq->size);
+                     goto done;
+                   }
+                 show_one_slot = 1;
+               }
+           }
+         else
+           {
+             error = clib_error_return (0, "unknown input `%U'",
+                                        format_unformat_error, input);
+             goto done;
+           }
+       }
       else
        {
          error = clib_error_return (0, "unknown input `%U'",
@@ -338,7 +558,8 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
        );
     }
 
-  show_vmxnet3 (vm, hw_if_indices, show_descr);
+  show_vmxnet3 (vm, hw_if_indices, show_descr, show_one_table, which,
+               show_one_slot, slot);
 
 done:
   vec_free (hw_if_indices);
@@ -348,7 +569,8 @@ done:
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
   .path = "show vmxnet3",
-  .short_help = "show vmxnet3 [<interface>]",
+  .short_help = "show vmxnet3 [[<interface>] ([desc] | ([rx-comp] | "
+  "[rx-desc-0] | [rx-desc-1] | [tx-comp] | [tx-desc]) [<slot>])]",
   .function = show_vmxnet3_fn,
 };
 /* *INDENT-ON* */
@@ -356,9 +578,12 @@ VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
 clib_error_t *
 vmxnet3_cli_init (vlib_main_t * vm)
 {
+  vmxnet3_main_t *vmxm = &vmxnet3_main;
+
   /* initialize binary API */
   vmxnet3_plugin_api_hookup (vm);
 
+  vmxm->log_default = vlib_log_register_class ("vmxnet3", 0);
   return 0;
 }