MTU: Setting of MTU on software interface (instead of hardware interface)
[vpp.git] / src / plugins / dpdk / device / init.c
index cc30c8d..ac20edc 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;
@@ -407,6 +416,7 @@ dpdk_lib_init (dpdk_main_t * dm)
 
            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:
@@ -466,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);
@@ -583,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,
@@ -606,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;
@@ -655,10 +696,10 @@ 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);
-
-      rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
+      vnet_sw_interface_set_mtu (dm->vnet_main, sw->sw_if_index,
+                                xd->port_conf.rxmode.max_rx_pkt_len -
+                                sizeof (ethernet_header_t));
+      rte_eth_dev_set_mtu (xd->device_index, mtu);
     }
 
   if (nb_desc > dm->conf->num_mbufs)
@@ -1354,12 +1395,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:
@@ -1465,9 +1527,10 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
 
                    /* Init l3 packet size allowed on bonded interface */
                    bhi->max_packet_bytes = ETHERNET_MAX_PACKET_BYTES;
-                   bhi->max_l3_packet_bytes[VLIB_RX] =
-                     bhi->max_l3_packet_bytes[VLIB_TX] =
-                     ETHERNET_MAX_PACKET_BYTES - sizeof (ethernet_header_t);
+                   vnet_sw_interface_set_mtu (vnm, bhi->sw_if_index,
+                                              ETHERNET_MAX_PACKET_BYTES -
+                                              sizeof (ethernet_header_t));
+
                    while (nlink >= 1)
                      {         /* for all slave links */
                        int slave = slink[--nlink];
@@ -1505,11 +1568,13 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                        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_l3_packet_bytes[VLIB_RX] >
-                           shi->max_l3_packet_bytes[VLIB_RX])
-                         bhi->max_l3_packet_bytes[VLIB_RX] =
-                           bhi->max_l3_packet_bytes[VLIB_TX] =
-                           shi->max_l3_packet_bytes[VLIB_RX];
+                       vnet_sw_interface_t *bsi =
+                         vnet_get_sw_interface (vnm, bhi->sw_if_index);
+                       if (bsi->max_l3_packet_bytes[VLIB_RX] >
+                           ssi->max_l3_packet_bytes[VLIB_RX])
+                         bsi->max_l3_packet_bytes[VLIB_RX] =
+                           bsi->max_l3_packet_bytes[VLIB_TX] =
+                           ssi->max_l3_packet_bytes[VLIB_RX];
                        /* Set max 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;