vmxnet3: Add hardware link status handling 35/14935/3
authorSteven <sluong@cisco.com>
Fri, 21 Sep 2018 14:55:07 +0000 (07:55 -0700)
committerDamjan Marion <dmarion@me.com>
Fri, 21 Sep 2018 18:17:12 +0000 (18:17 +0000)
Added an interrupt line for monitoring and notifying hardware link status
Displayed additional information for show hardware for vmxnet3 interface
Fixed possible garbage display on interface name for show vmxnet3

Change-Id: If457bfe7c216287fb3a4e2630f00434d595f387b
Signed-off-by: Steven <sluong@cisco.com>
src/plugins/vmxnet3/README.md
src/plugins/vmxnet3/cli.c
src/plugins/vmxnet3/format.c
src/plugins/vmxnet3/output.c
src/plugins/vmxnet3/vmxnet3.c
src/plugins/vmxnet3/vmxnet3.h

index a496713..4f03c15 100644 (file)
@@ -34,7 +34,7 @@ echo Y | sudo tee /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
 
 3. Bind interface to vfio-pci
 ```
-dpdk-devbind.py --bind vfio-pci 0b:00.0
+sudo dpdk-devbind.py --bind vfio-pci 0b:00.0
 ```
 
 ### Interface Creation
index 3a7e5d9..1e4ac4a 100644 (file)
@@ -206,8 +206,9 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
     {
       hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
       vd = vec_elt_at_index (vmxm->devices, hi->dev_instance);
-      vlib_cli_output (vm, "Interface: %s (ifindex %d)",
-                      hi->name, hw_if_indices[i]);
+      vlib_cli_output (vm, "Interface: %U (ifindex %d)",
+                      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, "  PCI Address: %U", format_vlib_pci_addr,
                       &vd->pci_addr);
index 8ee812e..5690465 100644 (file)
@@ -62,6 +62,7 @@ format_vmxnet3_device (u8 * s, va_list * args)
   vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
 
   s = format (s, "flags: %U", format_vmxnet3_device_flags, vd);
+  s = format (s, "\n%Uspeed %u", format_white_space, indent, vd->link_speed);
   s = format (s, "\n%Urx queues %u, rx desc %u, tx queues %u, tx desc %u",
              format_white_space, indent,
              vd->num_rx_queues, rxq->size, vd->num_tx_queues, txq->size);
index 2ca1cc9..32b77de 100644 (file)
@@ -115,8 +115,15 @@ VNET_DEVICE_CLASS_TX_FN (vmxnet3_device_class) (vlib_main_t * vm,
   u16 qid = thread_index;
   u16 n_retry = 5;
 
-  txq = vec_elt_at_index (vd->txqs, qid % vd->num_tx_queues);
+  if (PREDICT_FALSE (!(vd->flags & VMXNET3_DEVICE_F_LINK_UP)))
+    {
+      vlib_buffer_free (vm, buffers, n_left);
+      vlib_error_count (vm, node->node_index, VMXNET3_TX_ERROR_LINK_DOWN,
+                       n_left);
+      return (0);
+    }
 
+  txq = vec_elt_at_index (vd->txqs, qid % vd->num_tx_queues);
   clib_spinlock_lock_if_init (&txq->lock);
 
 retry:
index 74e6003..2ff6d79 100644 (file)
@@ -185,6 +185,7 @@ vmxnet3_provision_driver_shared (vlib_main_t * vm, vmxnet3_device_t * vd)
   shared->misc.num_tx_queues = vd->num_tx_queues;
   shared->misc.num_rx_queues = vd->num_rx_queues;
   shared->interrupt.num_intrs = vd->num_intrs;
+  shared->interrupt.event_intr_index = 1;
   shared->interrupt.control = VMXNET3_IC_DISABLE_ALL;
   shared->rx_filter.mode = VMXNET3_RXMODE_UCAST | VMXNET3_RXMODE_BCAST |
     VMXNET3_RXMODE_ALL_MULTI;
@@ -309,7 +310,7 @@ vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
 
   vd->num_tx_queues = 1;
   vd->num_rx_queues = 1;
-  vd->num_intrs = 1;
+  vd->num_intrs = 2;
 
   /* Quiesce the device */
   vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
@@ -351,6 +352,18 @@ vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
       return error;
     }
 
+  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
+  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
+  if (ret & 1)
+    {
+      vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
+      vd->link_speed = ret >> 16;
+    }
+  else
+    {
+      vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
+    }
+
   /* Get the mac address */
   ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_MACL);
   clib_memcpy (vd->mac_addr, &ret, 4);
@@ -413,7 +426,7 @@ vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
 }
 
 static void
-vmxnet3_irq_handler (vlib_pci_dev_handle_t h, u16 line)
+vmxnet3_irq_0_handler (vlib_pci_dev_handle_t h, u16 line)
 {
   vnet_main_t *vnm = vnet_get_main ();
   vmxnet3_main_t *vmxm = &vmxnet3_main;
@@ -425,6 +438,31 @@ vmxnet3_irq_handler (vlib_pci_dev_handle_t h, u16 line)
     vnet_device_input_set_interrupt_pending (vnm, vd->hw_if_index, qid);
 }
 
+static void
+vmxnet3_irq_1_handler (vlib_pci_dev_handle_t h, u16 line)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vmxnet3_main_t *vmxm = &vmxnet3_main;
+  uword pd = vlib_pci_get_private_data (h);
+  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, pd);
+  u32 ret;
+
+  vmxnet3_reg_write (vd, 1, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
+  ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
+  if (ret & 1)
+    {
+      vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
+      vd->link_speed = ret >> 16;
+      vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
+                                  VNET_HW_INTERFACE_FLAG_LINK_UP);
+    }
+  else
+    {
+      vd->flags &= ~VMXNET3_DEVICE_F_LINK_UP;
+      vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
+    }
+}
+
 static u8
 vmxnet3_queue_size_valid (u16 qsz)
 {
@@ -504,10 +542,14 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
     goto error;
 
   if ((error = vlib_pci_register_msix_handler (h, 0, 1,
-                                              &vmxnet3_irq_handler)))
+                                              &vmxnet3_irq_0_handler)))
     goto error;
 
-  if ((error = vlib_pci_enable_msix_irq (h, 0, 1)))
+  if ((error = vlib_pci_register_msix_handler (h, 1, 1,
+                                              &vmxnet3_irq_1_handler)))
+    goto error;
+
+  if ((error = vlib_pci_enable_msix_irq (h, 0, 2)))
     goto error;
 
   if ((error = vlib_pci_intr_enable (h)))
@@ -533,6 +575,11 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
   vnet_hw_interface_set_input_node (vnm, vd->hw_if_index,
                                    vmxnet3_input_node.index);
   vnet_hw_interface_assign_rx_thread (vnm, vd->hw_if_index, 0, ~0);
+  if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
+    vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
+                                VNET_HW_INTERFACE_FLAG_LINK_UP);
+  else
+    vnet_hw_interface_set_flags (vnm, vd->hw_if_index, 0);
   return;
 
 error:
index 666dec7..f3868a8 100644 (file)
@@ -18,6 +18,7 @@
 
 #define foreach_vmxnet3_tx_func_error         \
   _(ERROR_PACKETS, "error packets") \
+  _(LINK_DOWN, "link down") \
   _(NO_FREE_SLOTS, "no free tx slots")
 
 typedef enum
@@ -472,6 +473,7 @@ typedef struct
 
   vmxnet3_dma *dma;
 
+  u32 link_speed;
 } vmxnet3_device_t;
 
 typedef struct