[v4,09/13] net/enetc: add MTU update and jumbo frames support
diff mbox series

Message ID 20190412122840.1908-10-g.singh@nxp.com
State Accepted, archived
Delegated to: Ferruh Yigit
Headers show
Series
  • ENETC PMD basic features and bug fixes
Related show

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Gagandeep Singh April 12, 2019, 12:29 p.m. UTC
Enable the jumbo frames and mtu update feature.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 doc/guides/nics/enetc.rst          |  1 +
 doc/guides/nics/features/enetc.ini |  2 +
 drivers/net/enetc/base/enetc_hw.h  |  6 ++-
 drivers/net/enetc/enetc.h          |  5 ++
 drivers/net/enetc/enetc_ethdev.c   | 86 +++++++++++++++++++++++++++---
 5 files changed, 91 insertions(+), 9 deletions(-)

Patch
diff mbox series

diff --git a/doc/guides/nics/enetc.rst b/doc/guides/nics/enetc.rst
index ab13211a5..eeb07523d 100644
--- a/doc/guides/nics/enetc.rst
+++ b/doc/guides/nics/enetc.rst
@@ -49,6 +49,7 @@  ENETC Features
 - Basic stats
 - Promiscuous
 - Multicast
+- Jumbo packets
 
 NIC Driver (PMD)
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/nics/features/enetc.ini b/doc/guides/nics/features/enetc.ini
index 6b7bbfb3d..0eed2cb9b 100644
--- a/doc/guides/nics/features/enetc.ini
+++ b/doc/guides/nics/features/enetc.ini
@@ -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
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index 90a383a8b..2eb1df30e 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -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
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 56454dc9d..e494eb8b8 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -24,6 +24,11 @@ 
 /* 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
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index a7dddc5cb..66cbf74d0 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -10,13 +10,6 @@ 
 
 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);