gso: remove the interface count
[vpp.git] / src / plugins / dpdk / device / init.c
index db4316b..5a6262c 100644 (file)
@@ -158,7 +158,7 @@ dpdk_port_crc_strip_enabled (dpdk_device_t * xd)
   return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
 }
 
-/* The funciton check_l3cache helps check if Level 3 cache exists or not on current CPUs
+/* The function check_l3cache helps check if Level 3 cache exists or not on current CPUs
   return value 1: exist.
   return value 0: not exist.
 */
@@ -181,7 +181,7 @@ check_l3cache ()
          u8 *p = NULL;
          int level_cache = -1;
 
-         p = format (p, "%s/%s/%s", sys_cache_dir, dp->d_name, "level");
+         p = format (p, "%s/%s/%s%c", sys_cache_dir, dp->d_name, "level", 0);
          if ((err = clib_sysfs_read ((char *) p, "%d", &level_cache)))
            clib_error_free (err);
 
@@ -219,7 +219,6 @@ dpdk_lib_init (dpdk_main_t * dm)
 
   u32 next_hqos_cpu = 0;
   u8 af_packet_instance_num = 0;
-  u8 bond_ether_instance_num = 0;
   last_pci_addr.as_u32 = ~0;
 
   dm->hqos_cpu_first_index = 0;
@@ -242,7 +241,7 @@ dpdk_lib_init (dpdk_main_t * dm)
 
   if (nports < 1)
     {
-      dpdk_log_notice ("DPDK drivers found no ports...");
+      dpdk_log_notice ("DPDK drivers found no Ethernet devices...");
     }
 
   if (CLIB_DEBUG > 0)
@@ -267,10 +266,11 @@ dpdk_lib_init (dpdk_main_t * dm)
   RTE_ETH_FOREACH_DEV(i)
     {
       u8 addr[6];
-      u8 vlan_strip = 0;
+      int vlan_off;
       struct rte_eth_dev_info dev_info;
       struct rte_pci_device *pci_dev;
       struct rte_eth_link l;
+      dpdk_portid_t next_port_id;
       dpdk_device_config_t *devconf = 0;
       vlib_pci_addr_t pci_addr;
       uword *p = 0;
@@ -283,14 +283,14 @@ dpdk_lib_init (dpdk_main_t * dm)
 
       if (dev_info.device == 0)
        {
-         clib_warning ("DPDK bug: missing device info. Skipping %s device",
+         dpdk_log_notice ("DPDK bug: missing device info. Skipping %s device",
                        dev_info.driver_name);
          continue;
        }
 
       pci_dev = dpdk_get_pci_device (&dev_info);
 
-      if (pci_dev)     /* bonded interface has no pci info */
+      if (pci_dev)
        {
          pci_addr.domain = pci_dev->addr.domain;
          pci_addr.bus = pci_dev->addr.bus;
@@ -316,13 +316,14 @@ dpdk_lib_init (dpdk_main_t * dm)
        devconf = &dm->conf->default_devconf;
 
       /* Handle interface naming for devices with multiple ports sharing same PCI ID */
-      if (pci_dev)
+      if (pci_dev &&
+         ((next_port_id = rte_eth_find_next (i + 1)) != RTE_MAX_ETHPORTS))
        {
          struct rte_eth_dev_info di = { 0 };
          struct rte_pci_device *next_pci_dev;
-         rte_eth_dev_info_get (i + 1, &di);
+         rte_eth_dev_info_get (next_port_id, &di);
          next_pci_dev = di.device ? RTE_DEV_TO_PCI (di.device) : 0;
-         if (pci_dev && next_pci_dev &&
+         if (next_pci_dev &&
              pci_addr.as_u32 != last_pci_addr.as_u32 &&
              memcmp (&pci_dev->addr, &next_pci_dev->addr,
                      sizeof (struct rte_pci_addr)) == 0)
@@ -453,6 +454,7 @@ dpdk_lib_init (dpdk_main_t * dm)
            case VNET_DPDK_PMD_MLX4:
            case VNET_DPDK_PMD_MLX5:
            case VNET_DPDK_PMD_QEDE:
+           case VNET_DPDK_PMD_BNXT:
              xd->port_type = port_type_from_speed_capa (&dev_info);
              break;
 
@@ -461,6 +463,14 @@ dpdk_lib_init (dpdk_main_t * dm)
            case VNET_DPDK_PMD_IXGBEVF:
            case VNET_DPDK_PMD_I40EVF:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
+             if (dm->conf->no_tx_checksum_offload == 0)
+               {
+                 xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+                 xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+                 xd->flags |=
+                   DPDK_DEVICE_FLAG_TX_OFFLOAD |
+                   DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+               }
              break;
 
            case VNET_DPDK_PMD_THUNDERX:
@@ -511,11 +521,6 @@ dpdk_lib_init (dpdk_main_t * dm)
              xd->af_packet_instance_num = af_packet_instance_num++;
              break;
 
-           case VNET_DPDK_PMD_BOND:
-             xd->port_type = VNET_DPDK_PORT_TYPE_ETH_BOND;
-             xd->bond_instance_num = bond_ether_instance_num++;
-             break;
-
            case VNET_DPDK_PMD_VIRTIO_USER:
              xd->port_type = VNET_DPDK_PORT_TYPE_VIRTIO_USER;
              break;
@@ -579,7 +584,7 @@ dpdk_lib_init (dpdk_main_t * dm)
          addr[1] = 0xfe;
        }
       else
-       rte_eth_macaddr_get (i, (struct ether_addr *) addr);
+       rte_eth_macaddr_get (i, (void *) addr);
 
       if (xd->tx_q_used < tm->n_vlib_mains)
        dpdk_device_lock_init (xd);
@@ -736,12 +741,28 @@ dpdk_lib_init (dpdk_main_t * dm)
        {
          hi->max_packet_bytes = mtu;
          hi->max_supported_packet_bytes = max_rx_frame;
+         hi->numa_node = xd->cpu_socket;
        }
 
       if (dm->conf->no_tx_checksum_offload == 0)
        if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL)
          hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
 
+      if (devconf->tso == DPDK_DEVICE_TSO_ON && hi != NULL)
+       {
+         /*tcp_udp checksum must be enabled*/
+         if ((dm->conf->enable_tcp_udp_checksum) &&
+             (hi->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD))
+           {
+               hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+               xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO |
+                 DEV_TX_OFFLOAD_UDP_TSO;
+           }
+         else
+           clib_warning ("%s: TCP/UDP checksum offload must be enabled",
+             hi->name);
+       }
+
       dpdk_device_setup (xd);
 
       if (vec_len (xd->errors))
@@ -781,29 +802,33 @@ dpdk_lib_init (dpdk_main_t * dm)
        * VLAN stripping: default to VLAN strip disabled, unless specified
        * otherwise in the startup config.
        */
-      if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
-       vlan_strip = 1;
 
-      if (vlan_strip)
+      vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
+      if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
        {
-         int vlan_off;
-         vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
          vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
-          if (vlan_off)
-           xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
-         else
-           xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
-         if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) == 0)
+         if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
            dpdk_log_info ("VLAN strip enabled for interface\n");
          else
            dpdk_log_warn ("VLAN strip cannot be supported by interface\n");
+         xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
+       }
+      else
+       {
+         if (vlan_off & ETH_VLAN_STRIP_OFFLOAD)
+           {
+             vlan_off &= ~ETH_VLAN_STRIP_OFFLOAD;
+             if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
+               dpdk_log_warn ("set VLAN offload failed\n");
+           }
+         xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
        }
 
       if (hi)
        hi->max_packet_bytes = xd->port_conf.rxmode.max_rx_pkt_len
          - sizeof (ethernet_header_t);
       else
-       clib_warning ("hi NULL");
+       dpdk_log_warn ("hi NULL");
 
       if (dm->conf->no_multi_seg)
        mtu = mtu > ETHER_MAX_LEN ? ETHER_MAX_LEN : mtu;
@@ -914,7 +939,8 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
       ;
     /* all Intel QAT devices VFs */
     else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_PROCESSOR_CO &&
-        (d->device_id == 0x0443 || d->device_id == 0x37c9 || d->device_id == 0x19e3))
+        (d->device_id == 0x0443 || d->device_id == 0x18a1 || d->device_id == 0x19e3 ||
+        d->device_id == 0x37c9 || d->device_id == 0x6f55))
       ;
     /* Cisco VIC */
     else if (d->vendor_id == 0x1137 &&
@@ -923,7 +949,7 @@ 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 */
+    /* Amazon Elastic Network Adapter */
     else if (d->vendor_id == 0x1d0f && d->device_id >= 0xec20 && d->device_id <= 0xec21)
       ;
     /* Cavium Network Adapter */
@@ -942,6 +968,19 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
       {
         continue;
       }
+    /* Broadcom NetXtreme S, and E series only */
+    else if (d->vendor_id == 0x14e4 &&
+       ((d->device_id >= 0x16c0 &&
+               d->device_id != 0x16c6 && d->device_id != 0x16c7 &&
+               d->device_id != 0x16dd && d->device_id != 0x16f7 &&
+               d->device_id != 0x16fd && d->device_id != 0x16fe &&
+               d->device_id != 0x170d && d->device_id != 0x170c &&
+               d->device_id != 0x170e && d->device_id != 0x1712 &&
+               d->device_id != 0x1713) ||
+       (d->device_id == 0x1604 || d->device_id == 0x1605 ||
+        d->device_id == 0x1614 || d->device_id == 0x1606 ||
+        d->device_id == 0x1609 || d->device_id == 0x1614)))
+      ;
     else
       {
         dpdk_log_warn ("Unsupported PCI device 0x%04x:0x%04x found "
@@ -1022,6 +1061,7 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
 
   devconf->pci_addr.as_u32 = pci_addr.as_u32;
   devconf->hqos_enabled = 0;
+  devconf->tso = DPDK_DEVICE_TSO_DEFAULT;
 #if 0
   dpdk_device_config_hqos_default (&devconf->hqos);
 #endif
@@ -1070,6 +1110,14 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
        {
          devconf->hqos_enabled = 1;
        }
+      else if (unformat (input, "tso on"))
+       {
+         devconf->tso = DPDK_DEVICE_TSO_ON;
+       }
+      else if (unformat (input, "tso off"))
+       {
+         devconf->tso = DPDK_DEVICE_TSO_OFF;
+       }
       else
        {
          error = clib_error_return (0, "unknown input `%U'",
@@ -1351,6 +1399,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       vec_insert (conf->eal_init_args, 2, 3);
       conf->eal_init_args[3] = (u8 *) "-n";
       tmp = format (0, "%d", conf->nchannels);
+      vec_terminate_c_string (tmp);
       conf->eal_init_args[4] = tmp;
     }
 
@@ -1370,6 +1419,15 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
     /* default per-device config items */
     foreach_dpdk_device_config_item
 
+    /* copy vlan_strip config from default device */
+       if (devconf->vlan_strip_offload == 0 &&
+               conf->default_devconf.vlan_strip_offload > 0)
+               devconf->vlan_strip_offload =
+                       conf->default_devconf.vlan_strip_offload;
+
+       /* copy tso config from default device */
+       _(tso)
+
     /* add DPDK EAL whitelist/blacklist entry */
     if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
       {
@@ -1435,6 +1493,8 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
     conf->eal_init_args_str = format (conf->eal_init_args_str, "%s ",
                                      conf->eal_init_args[i]);
 
+  vec_terminate_c_string (conf->eal_init_args_str);
+
   dpdk_log_warn ("EAL init args: %s", conf->eal_init_args_str);
   ret = rte_eal_init (vec_len (conf->eal_init_args),
                      (char **) conf->eal_init_args);
@@ -1497,15 +1557,7 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
       ed->new_link_state = (u8) xd->link.link_status;
     }
 
-  if ((xd->flags & (DPDK_DEVICE_FLAG_ADMIN_UP | DPDK_DEVICE_FLAG_BOND_SLAVE))
-      && ((xd->link.link_status != 0) ^
-         vnet_hw_interface_is_link_up (vnm, xd->hw_if_index)))
-    {
-      hw_flags_chg = 1;
-      hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
-    }
-
-  if (hw_flags_chg || (xd->link.link_duplex != prev_link.link_duplex))
+  if ((xd->link.link_duplex != prev_link.link_duplex))
     {
       hw_flags_chg = 1;
       switch (xd->link.link_duplex)
@@ -1524,6 +1576,14 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
     vnet_hw_interface_set_link_speed (vnm, xd->hw_if_index,
                                      xd->link.link_speed * 1000);
 
+  if (xd->link.link_status != prev_link.link_status)
+    {
+      hw_flags_chg = 1;
+
+      if (xd->link.link_status)
+       hw_flags |= VNET_HW_INTERFACE_FLAG_LINK_UP;
+    }
+
   if (hw_flags_chg)
     {
       if (LINK_STATE_ELOGS)
@@ -1553,13 +1613,9 @@ static uword
 dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
 {
   clib_error_t *error;
-  vnet_main_t *vnm = vnet_get_main ();
   dpdk_main_t *dm = &dpdk_main;
-  ethernet_main_t *em = &ethernet_main;
   dpdk_device_t *xd;
   vlib_thread_main_t *tm = vlib_get_thread_main ();
-  int i;
-  int j;
 
   error = dpdk_lib_init (dm);
 
@@ -1574,110 +1630,6 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
     dpdk_update_link_state (xd, now);
   }
 
-  {
-    /*
-     * Extra set up for bond interfaces:
-     *  1. Setup MACs for bond interfaces and their slave links which was set
-     *     in dpdk_device_setup() but needs to be done again here to take
-     *     effect.
-     *  2. Set up info and register slave link state change callback handling.
-     *  3. Set up info for bond interface related CLI support.
-     */
-    int nports = rte_eth_dev_count_avail ();
-    if (nports > 0)
-      {
-       /* *INDENT-OFF* */
-       RTE_ETH_FOREACH_DEV(i)
-         {
-           xd = NULL;
-           for (j = 0; j < nports; j++)
-             {
-               if (dm->devices[j].port_id == i)
-                 {
-                   xd = &dm->devices[j];
-                 }
-             }
-           if (xd != NULL && xd->pmd == VNET_DPDK_PMD_BOND)
-             {
-               u8 addr[6];
-               dpdk_portid_t slink[16];
-               int nlink = rte_eth_bond_slaves_get (i, slink, 16);
-               if (nlink > 0)
-                 {
-                   vnet_hw_interface_t *bhi;
-                   ethernet_interface_t *bei;
-                   int rv;
-
-                   /* Get MAC of 1st slave link */
-                   rte_eth_macaddr_get
-                     (slink[0], (struct ether_addr *) addr);
-
-                   /* Set MAC of bounded interface to that of 1st slave link */
-                   dpdk_log_info ("Set MAC for bond port %d BondEthernet%d",
-                                  i, xd->bond_instance_num);
-                   rv = rte_eth_bond_mac_address_set
-                     (i, (struct ether_addr *) addr);
-                   if (rv)
-                     dpdk_log_warn ("Set MAC addr failure rv=%d", rv);
-
-                   /* Populate MAC of bonded interface in VPP hw tables */
-                   bhi = vnet_get_hw_interface
-                     (vnm, dm->devices[i].hw_if_index);
-                   bei = pool_elt_at_index
-                     (em->interfaces, bhi->hw_instance);
-                   clib_memcpy (bhi->hw_address, addr, 6);
-                   clib_memcpy (bei->address, addr, 6);
-
-                   /* Init l3 packet size allowed on bonded interface */
-                   bhi->max_packet_bytes = ETHERNET_MAX_PACKET_BYTES;
-                   while (nlink >= 1)
-                     {         /* for all slave links */
-                       int slave = slink[--nlink];
-                       dpdk_device_t *sdev = &dm->devices[slave];
-                       vnet_hw_interface_t *shi;
-                       vnet_sw_interface_t *ssi;
-                       ethernet_interface_t *sei;
-                       /* Add MAC to all slave links except the first one */
-                       if (nlink)
-                         {
-                           dpdk_log_info ("Add MAC for slave port %d",
-                                          slave);
-                           rv = rte_eth_dev_mac_addr_add
-                             (slave, (struct ether_addr *) addr, 0);
-                           if (rv)
-                             dpdk_log_warn ("Add MAC addr failure rv=%d",
-                                            rv);
-                         }
-                       /* Setup slave link state change callback handling */
-                       rte_eth_dev_callback_register
-                         (slave, RTE_ETH_EVENT_INTR_LSC,
-                          dpdk_port_state_callback, NULL);
-                       dpdk_device_t *sxd = &dm->devices[slave];
-                       sxd->flags |= DPDK_DEVICE_FLAG_BOND_SLAVE;
-                       sxd->bond_port = i;
-                       /* Set slaves bitmap for bonded interface */
-                       bhi->bond_info = clib_bitmap_set
-                         (bhi->bond_info, sdev->hw_if_index, 1);
-                       /* Set MACs and slave link flags on slave interface */
-                       shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
-                       ssi = vnet_get_sw_interface (vnm, sdev->sw_if_index);
-                       sei = pool_elt_at_index
-                         (em->interfaces, shi->hw_instance);
-                       shi->bond_info = VNET_HW_INTERFACE_BOND_INFO_SLAVE;
-                       ssi->flags |= VNET_SW_INTERFACE_FLAG_BOND_SLAVE;
-                       clib_memcpy (shi->hw_address, addr, 6);
-                       clib_memcpy (sei->address, addr, 6);
-                       /* Set l3 packet size allowed as the lowest of slave */
-                       if (bhi->max_packet_bytes > shi->max_packet_bytes)
-                         bhi->max_packet_bytes = shi->max_packet_bytes;
-                     }
-                 }
-             }
-         }
-       /* *INDENT-ON* */
-      }
-  }
-
   while (1)
     {
       /*
@@ -1732,6 +1684,8 @@ dpdk_init (vlib_main_t * vm)
   STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES,
                 "DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES");
 
+  dpdk_cli_reference ();
+
   dm->vlib_main = vm;
   dm->vnet_main = vnet_get_main ();
   dm->conf = &dpdk_config_main;
@@ -1749,10 +1703,6 @@ dpdk_init (vlib_main_t * vm)
   dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
   dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;
 
-  /* init CLI */
-  if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
-    return error;
-
   dm->log_default = vlib_log_register_class ("dpdk", 0);
 
   return error;
@@ -1760,7 +1710,6 @@ dpdk_init (vlib_main_t * vm)
 
 VLIB_INIT_FUNCTION (dpdk_init);
 
-
 /*
  * fd.io coding-style-patch-verification: ON
  *