Revert "MTU: Setting of MTU on software interface (instead of hardware interface)"
[vpp.git] / src / plugins / dpdk / device / init.c
index 314a2e9..76d122d 100755 (executable)
@@ -62,14 +62,22 @@ port_type_from_speed_capa (struct rte_eth_dev_info *dev_info)
 
   if (dev_info->speed_capa & ETH_LINK_SPEED_100G)
     return VNET_DPDK_PORT_TYPE_ETH_100G;
+  else if (dev_info->speed_capa & ETH_LINK_SPEED_56G)
+    return VNET_DPDK_PORT_TYPE_ETH_56G;
   else if (dev_info->speed_capa & ETH_LINK_SPEED_50G)
     return VNET_DPDK_PORT_TYPE_ETH_50G;
   else if (dev_info->speed_capa & ETH_LINK_SPEED_40G)
     return VNET_DPDK_PORT_TYPE_ETH_40G;
   else if (dev_info->speed_capa & ETH_LINK_SPEED_25G)
     return VNET_DPDK_PORT_TYPE_ETH_25G;
+  else if (dev_info->speed_capa & ETH_LINK_SPEED_20G)
+    return VNET_DPDK_PORT_TYPE_ETH_20G;
   else if (dev_info->speed_capa & ETH_LINK_SPEED_10G)
     return VNET_DPDK_PORT_TYPE_ETH_10G;
+  else if (dev_info->speed_capa & ETH_LINK_SPEED_5G)
+    return VNET_DPDK_PORT_TYPE_ETH_5G;
+  else if (dev_info->speed_capa & ETH_LINK_SPEED_2_5G)
+    return VNET_DPDK_PORT_TYPE_ETH_2_5G;
   else if (dev_info->speed_capa & ETH_LINK_SPEED_1G)
     return VNET_DPDK_PORT_TYPE_ETH_1G;
 
@@ -180,6 +188,7 @@ static clib_error_t *
 dpdk_lib_init (dpdk_main_t * dm)
 {
   u32 nports;
+  u32 mtu, max_rx_frame;
   u32 nb_desc = 0;
   int i;
   clib_error_t *error;
@@ -224,15 +233,6 @@ dpdk_lib_init (dpdk_main_t * dm)
   if (CLIB_DEBUG > 0)
     clib_warning ("DPDK drivers found %d ports...", nports);
 
-  /*
-   * All buffers are all allocated from the same rte_mempool.
-   * Thus they all have the same number of data bytes.
-   */
-  dm->vlib_buffer_free_list_index =
-    vlib_buffer_get_or_create_free_list (vm,
-                                        VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES,
-                                        "dpdk rx");
-
   if (dm->conf->enable_tcp_udp_checksum)
     dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT
                                   | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED);
@@ -314,9 +314,6 @@ dpdk_lib_init (dpdk_main_t * dm)
       clib_memcpy (&xd->tx_conf, &dev_info.default_txconf,
                   sizeof (struct rte_eth_txconf));
 
-      if (dm->conf->no_tx_checksum_offload == 0)
-       xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOXSUMS;
-
       if (dm->conf->no_multi_seg)
        {
          xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
@@ -388,8 +385,14 @@ dpdk_lib_init (dpdk_main_t * dm)
            case VNET_DPDK_PMD_IXGBE:
            case VNET_DPDK_PMD_I40E:
              xd->port_type = port_type_from_speed_capa (&dev_info);
-             xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
-               DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+             if (dm->conf->no_tx_checksum_offload == 0)
+               {
+                 xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOXSUMS;
+                 xd->flags |=
+                   DPDK_DEVICE_FLAG_TX_OFFLOAD |
+                   DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+               }
+
 
              break;
            case VNET_DPDK_PMD_CXGBE:
@@ -411,6 +414,11 @@ dpdk_lib_init (dpdk_main_t * dm)
              xd->port_conf.rxmode.hw_strip_crc = 1;
              break;
 
+           case VNET_DPDK_PMD_ENA:
+             xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
+             xd->port_conf.rxmode.enable_scatter = 0;
+             break;
+
            case VNET_DPDK_PMD_DPAA2:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
              break;
@@ -468,39 +476,6 @@ dpdk_lib_init (dpdk_main_t * dm)
            xd->nb_tx_desc = devconf->num_tx_desc;
        }
 
-      /*
-       * Ensure default mtu is not > the mtu read from the hardware.
-       * Otherwise rte_eth_dev_configure() will fail and the port will
-       * not be available.
-       */
-      if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
-       {
-         /*
-          * This device does not support the platforms's max frame
-          * size. Use it's advertised mru instead.
-          */
-         xd->port_conf.rxmode.max_rx_pkt_len = dev_info.max_rx_pktlen;
-       }
-      else
-       {
-         xd->port_conf.rxmode.max_rx_pkt_len = ETHERNET_MAX_PACKET_BYTES;
-
-         /*
-          * Some platforms do not account for Ethernet FCS (4 bytes) in
-          * MTU calculations. To interop with them increase mru but only
-          * if the device's settings can support it.
-          */
-         if ((dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)) &&
-             xd->port_conf.rxmode.hw_strip_crc)
-           {
-             /*
-              * Allow additional 4 bytes (for Ethernet FCS). These bytes are
-              * stripped by h/w and so will not consume any buffer memory.
-              */
-             xd->port_conf.rxmode.max_rx_pkt_len += 4;
-           }
-       }
-
       if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
        {
          f64 now = vlib_time_now (vm);
@@ -522,34 +497,26 @@ dpdk_lib_init (dpdk_main_t * dm)
       xd->per_interface_next_index = ~0;
 
       /* assign interface to input thread */
-      dpdk_device_and_queue_t *dq;
       int q;
 
       if (devconf->hqos_enabled)
        {
          xd->flags |= DPDK_DEVICE_FLAG_HQOS;
 
+         int cpu;
          if (devconf->hqos.hqos_thread_valid)
            {
-             int cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
-
              if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
                return clib_error_return (0, "invalid HQoS thread index");
 
-             vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
-             dq->device = xd->device_index;
-             dq->queue_id = 0;
+             cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
            }
          else
            {
-             int cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
-
              if (dm->hqos_cpu_count == 0)
                return clib_error_return (0, "no HQoS threads available");
 
-             vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
-             dq->device = xd->device_index;
-             dq->queue_id = 0;
+             cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
 
              next_hqos_cpu++;
              if (next_hqos_cpu == dm->hqos_cpu_count)
@@ -558,6 +525,11 @@ dpdk_lib_init (dpdk_main_t * dm)
              devconf->hqos.hqos_thread_valid = 1;
              devconf->hqos.hqos_thread = cpu;
            }
+
+         dpdk_device_and_queue_t *dq;
+         vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
+         dq->device = xd->device_index;
+         dq->queue_id = 0;
        }
 
       vec_validate_aligned (xd->tx_vectors, tm->n_vlib_mains,
@@ -578,10 +550,6 @@ dpdk_lib_init (dpdk_main_t * dm)
          vec_reset_length (xd->rx_vectors[j]);
        }
 
-      vec_validate_aligned (xd->d_trace_buffers, tm->n_vlib_mains,
-                           CLIB_CACHE_LINE_BYTES);
-
-
       /* count the number of descriptors used for this device */
       nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
 
@@ -592,6 +560,61 @@ dpdk_lib_init (dpdk_main_t * dm)
       if (error)
        return error;
 
+      /*
+       * Ensure default mtu is not > the mtu read from the hardware.
+       * Otherwise rte_eth_dev_configure() will fail and the port will
+       * not be available.
+       * Calculate max_frame_size and mtu supported by NIC
+       */
+      if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
+       {
+         /*
+          * This device does not support the platforms's max frame
+          * size. Use it's advertised mru instead.
+          */
+         max_rx_frame = dev_info.max_rx_pktlen;
+         mtu = dev_info.max_rx_pktlen - sizeof (ethernet_header_t);
+       }
+      else
+       {
+         /* VPP treats MTU and max_rx_pktlen both equal to
+          * ETHERNET_MAX_PACKET_BYTES, if dev_info.max_rx_pktlen >=
+          * ETHERNET_MAX_PACKET_BYTES + sizeof(ethernet_header_t)
+          */
+         if (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
+                                        sizeof (ethernet_header_t)))
+           {
+             mtu = ETHERNET_MAX_PACKET_BYTES;
+             max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
+
+             /*
+              * Some platforms do not account for Ethernet FCS (4 bytes) in
+              * MTU calculations. To interop with them increase mru but only
+              * if the device's settings can support it.
+              */
+             if (xd->port_conf.rxmode.hw_strip_crc &&
+                 (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
+                                             sizeof (ethernet_header_t) +
+                                             4)))
+               {
+                 max_rx_frame += 4;
+               }
+           }
+         else
+           {
+             max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
+             mtu = ETHERNET_MAX_PACKET_BYTES - sizeof (ethernet_header_t);
+
+             if (xd->port_conf.rxmode.hw_strip_crc &&
+                 (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)))
+               {
+                 max_rx_frame += 4;
+               }
+           }
+       }
+      /*Set port rxmode config */
+      xd->port_conf.rxmode.max_rx_pkt_len = max_rx_frame;
+
       sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
       xd->vlib_sw_if_index = sw->sw_if_index;
       vnet_hw_interface_set_input_node (dm->vnet_main, xd->hw_if_index,
@@ -615,8 +638,17 @@ dpdk_lib_init (dpdk_main_t * dm)
                                                ~1);
          }
 
+      /*Get vnet hardware interface */
       hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index);
 
+      /*Override default max_packet_bytes and max_supported_bytes set in
+       * ethernet_register_interface() above*/
+      if (hi)
+       {
+         hi->max_packet_bytes = max_rx_frame;
+         hi->max_supported_packet_bytes = max_rx_frame;
+       }
+
       if (dm->conf->no_tx_checksum_offload == 0)
        if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD)
          hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
@@ -664,10 +696,13 @@ dpdk_lib_init (dpdk_main_t * dm)
            clib_warning ("VLAN strip cannot be supported by interface\n");
        }
 
-      hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] =
-       xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t);
+      if (hi)
+       hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] =
+         xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t);
+      else
+       clib_warning ("hi NULL");
 
-      rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
+      rte_eth_dev_set_mtu (xd->device_index, mtu);
     }
 
   if (nb_desc > dm->conf->num_mbufs)
@@ -680,24 +715,37 @@ dpdk_lib_init (dpdk_main_t * dm)
 static void
 dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
 {
-  vlib_pci_main_t *pm = &pci_main;
   clib_error_t *error;
-  vlib_pci_device_t *d;
   u8 *pci_addr = 0;
   int num_whitelisted = vec_len (conf->dev_confs);
+  vlib_pci_device_info_t *d = 0;
+  vlib_pci_addr_t *addr = 0, *addrs;
 
+  addrs = vlib_pci_get_all_dev_addrs ();
   /* *INDENT-OFF* */
-  pool_foreach (d, pm->pci_devs, ({
+  vec_foreach (addr, addrs)
+    {
     dpdk_device_config_t * devconf = 0;
     vec_reset_length (pci_addr);
-    pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
+    pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, addr, 0);
+    if (d)
+    {
+      vlib_pci_free_device_info (d);
+      d = 0;
+      }
+    d = vlib_pci_get_device_info (addr, &error);
+    if (error)
+    {
+      clib_error_report (error);
+      continue;
+    }
 
     if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && d->device_class != PCI_CLASS_PROCESSOR_CO)
       continue;
 
     if (num_whitelisted)
       {
-       uword * p = hash_get (conf->device_config_index_by_pci_addr, d->bus_address.as_u32);
+       uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
 
        if (!p)
          continue;
@@ -726,6 +774,9 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
     /* Chelsio T4/T5 */
     else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
       ;
+    /* Amazen Elastic Network Adapter */
+    else if (d->vendor_id == 0x1d0f && d->device_id >= 0xec20 && d->device_id <= 0xec21)
+      ;
     /* Mellanox  */
     else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1013 && d->device_id <= 0x101a)
       {
@@ -739,23 +790,24 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
         continue;
       }
 
-    error = vlib_pci_bind_to_uio (d, (char *) conf->uio_driver_name);
+    error = vlib_pci_bind_to_uio (addr, (char *) conf->uio_driver_name);
 
     if (error)
       {
        if (devconf == 0)
          {
            pool_get (conf->dev_confs, devconf);
-           hash_set (conf->device_config_index_by_pci_addr, d->bus_address.as_u32,
+           hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
                      devconf - conf->dev_confs);
-           devconf->pci_addr.as_u32 = d->bus_address.as_u32;
+           devconf->pci_addr.as_u32 = addr->as_u32;
          }
        devconf->is_blacklisted = 1;
        clib_error_report (error);
       }
-  }));
+  }
   /* *INDENT-ON* */
   vec_free (pci_addr);
+  vlib_pci_free_device_info (d);
 }
 
 static clib_error_t *
@@ -1017,7 +1069,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
     }
 
   if (!conf->uio_driver_name)
-    conf->uio_driver_name = format (0, "uio_pci_generic%c", 0);
+    conf->uio_driver_name = format (0, "auto%c", 0);
 
   /*
    * Use 1G huge pages if available.
@@ -1346,12 +1398,33 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
        case ETH_SPEED_NUM_1G:
          hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_1G;
          break;
+       case ETH_SPEED_NUM_2_5G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_2_5G;
+         break;
+       case ETH_SPEED_NUM_5G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_5G;
+         break;
        case ETH_SPEED_NUM_10G:
          hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_10G;
          break;
+       case ETH_SPEED_NUM_20G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_20G;
+         break;
+       case ETH_SPEED_NUM_25G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_25G;
+         break;
        case ETH_SPEED_NUM_40G:
          hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_40G;
          break;
+       case ETH_SPEED_NUM_50G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_50G;
+         break;
+       case ETH_SPEED_NUM_56G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_56G;
+         break;
+       case ETH_SPEED_NUM_100G:
+         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_100G;
+         break;
        case 0:
          break;
        default: