net/enetc: support MTU update and jumbo frames
authorGagandeep Singh <g.singh@nxp.com>
Fri, 12 Apr 2019 12:29:05 +0000 (12:29 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 19 Apr 2019 12:51:54 +0000 (14:51 +0200)
Enable the jumbo frames and MTU update feature.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
doc/guides/nics/enetc.rst
doc/guides/nics/features/enetc.ini
doc/guides/rel_notes/release_19_05.rst
drivers/net/enetc/base/enetc_hw.h
drivers/net/enetc/enetc.h
drivers/net/enetc/enetc_ethdev.c

index ab13211..eeb0752 100644 (file)
@@ -49,6 +49,7 @@ ENETC Features
 - Basic stats
 - Promiscuous
 - Multicast
+- Jumbo packets
 
 NIC Driver (PMD)
 ~~~~~~~~~~~~~~~~
index 6b7bbfb..0eed2cb 100644 (file)
@@ -9,6 +9,8 @@ Link status          = Y
 Basic stats          = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
+MTU update           = Y
+Jumbo frame          = Y
 Linux VFIO           = Y
 ARMv8                = Y
 Usage doc            = Y
index 6039a17..7e9a790 100644 (file)
@@ -150,6 +150,8 @@ New Features
   * Added SXGMII interface support
   * Added basic statistics support
   * Added promiscuous and allmulticast mode support
+  * Added MTU update support
+  * Added jumbo frame support
 
 * **Updated the QuickAssist Technology PMD.**
 
index 90a383a..2eb1df3 100644 (file)
@@ -99,7 +99,11 @@ enum enetc_bdr_type {TX, RX};
 #define ENETC_PM0_RX_EN                        BIT(1)
 
 #define ENETC_PM0_MAXFRM               0x08014
-#define ENETC_SET_MAXFRM(val)          ((val) << 16)
+#define ENETC_SET_TX_MTU(val)          ((val) << 16)
+#define ENETC_SET_MAXFRM(val)          ((val) & 0xffff)
+#define ENETC_PTXMBAR                  0x0608
+/* n = TC index [0..7] */
+#define ENETC_PTCMSDUR(n)              (0x2020 + (n) * 4)
 
 #define ENETC_PM0_STATUS               0x08304
 #define ENETC_LINK_MODE                        0x0000000000080000ULL
index 56454dc..e494eb8 100644 (file)
 /* BD ALIGN */
 #define BD_ALIGN       8
 
+/* minimum frame size supported */
+#define ENETC_MAC_MINFRM_SIZE  68
+/* maximum frame size supported */
+#define ENETC_MAC_MAXFRM_SIZE  9600
+
 /*
  * upper_32_bits - return bits 32-63 of a number
  * @n: the number we're accessing
index a7dddc5..66cbf74 100644 (file)
 
 int enetc_logtype_pmd;
 
-static int
-enetc_dev_configure(struct rte_eth_dev *dev __rte_unused)
-{
-       PMD_INIT_FUNC_TRACE();
-       return 0;
-}
-
 static int
 enetc_dev_start(struct rte_eth_dev *dev)
 {
@@ -168,7 +161,8 @@ enetc_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
        };
        dev_info->max_rx_queues = MAX_RX_RINGS;
        dev_info->max_tx_queues = MAX_TX_RINGS;
-       dev_info->max_rx_pktlen = 1500;
+       dev_info->max_rx_pktlen = ENETC_MAC_MAXFRM_SIZE;
+       dev_info->rx_offload_capa = DEV_RX_OFFLOAD_JUMBO_FRAME;
 }
 
 static int
@@ -597,6 +591,76 @@ enetc_allmulticast_disable(struct rte_eth_dev *dev)
        enetc_port_wr(enetc_hw, ENETC_PSIPMR, psipmr);
 }
 
+static int
+enetc_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+       struct enetc_eth_hw *hw =
+               ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct enetc_hw *enetc_hw = &hw->hw;
+       uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+
+       /* check that mtu is within the allowed range */
+       if (mtu < ENETC_MAC_MINFRM_SIZE || frame_size > ENETC_MAC_MAXFRM_SIZE)
+               return -EINVAL;
+
+       /*
+        * Refuse mtu that requires the support of scattered packets
+        * when this feature has not been enabled before.
+        */
+       if (dev->data->min_rx_buf_size &&
+               !dev->data->scattered_rx && frame_size >
+               dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) {
+               ENETC_PMD_ERR("SG not enabled, will not fit in one buffer");
+               return -EINVAL;
+       }
+
+       if (frame_size > ETHER_MAX_LEN)
+               dev->data->dev_conf.rxmode.offloads &=
+                                               DEV_RX_OFFLOAD_JUMBO_FRAME;
+       else
+               dev->data->dev_conf.rxmode.offloads &=
+                                               ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+
+       enetc_port_wr(enetc_hw, ENETC_PTCMSDUR(0), ENETC_MAC_MAXFRM_SIZE);
+       enetc_port_wr(enetc_hw, ENETC_PTXMBAR, 2 * ENETC_MAC_MAXFRM_SIZE);
+
+       dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+
+       /*setting the MTU*/
+       enetc_port_wr(enetc_hw, ENETC_PM0_MAXFRM, ENETC_SET_MAXFRM(frame_size) |
+                     ENETC_SET_TX_MTU(ENETC_MAC_MAXFRM_SIZE));
+
+       return 0;
+}
+
+static int
+enetc_dev_configure(struct rte_eth_dev *dev)
+{
+       struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
+       uint64_t rx_offloads = eth_conf->rxmode.offloads;
+       struct enetc_eth_hw *hw =
+               ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct enetc_hw *enetc_hw = &hw->hw;
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
+               uint32_t max_len;
+
+               max_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
+
+               enetc_port_wr(enetc_hw, ENETC_PM0_MAXFRM,
+                             ENETC_SET_MAXFRM(max_len));
+               enetc_port_wr(enetc_hw, ENETC_PTCMSDUR(0),
+                             ENETC_MAC_MAXFRM_SIZE);
+               enetc_port_wr(enetc_hw, ENETC_PTXMBAR,
+                             2 * ENETC_MAC_MAXFRM_SIZE);
+               dev->data->mtu = ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN;
+       }
+
+       return 0;
+}
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -620,6 +684,7 @@ static const struct eth_dev_ops enetc_ops = {
        .allmulticast_enable  = enetc_allmulticast_enable,
        .allmulticast_disable = enetc_allmulticast_disable,
        .dev_infos_get        = enetc_dev_infos_get,
+       .mtu_set              = enetc_mtu_set,
        .rx_queue_setup       = enetc_rx_queue_setup,
        .rx_queue_release     = enetc_rx_queue_release,
        .tx_queue_setup       = enetc_tx_queue_setup,
@@ -674,6 +739,11 @@ enetc_dev_init(struct rte_eth_dev *eth_dev)
        ether_addr_copy((struct ether_addr *)hw->mac.addr,
                        &eth_dev->data->mac_addrs[0]);
 
+       /* Set MTU */
+       enetc_port_wr(&hw->hw, ENETC_PM0_MAXFRM,
+                     ENETC_SET_MAXFRM(ETHER_MAX_LEN));
+       eth_dev->data->mtu = ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN;
+
        ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
                        eth_dev->data->port_id, pci_dev->id.vendor_id,
                        pci_dev->id.device_id);