[SRU][F][PULL][PATCH v2 13/23] Revert "UBUNTU: SAUCE: mlxbf_gige: address some general upstream comments"

Asmaa Mnebhi asmaa at nvidia.com
Fri Jul 9 19:08:20 UTC 2021


BugLink: https://bugs.launchpad.net/bugs/1934923

This reverts commit a7a667e31b5f301466459342832d1a2ae1d81b33.

Signed-off-by: Asmaa Mnebhi <asmaa at nvidia.com>
---
 .../net/ethernet/mellanox/mlxbf_gige/Kconfig  |   2 +-
 .../mellanox/mlxbf_gige/mlxbf_gige_main.c     | 130 +++++++++++++-----
 .../mellanox/mlxbf_gige/mlxbf_gige_regs.h     |   5 -
 3 files changed, 100 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig b/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
index 08a4487932fe..41c7a8997190 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
@@ -5,7 +5,7 @@
 
 config MLXBF_GIGE
 	tristate "Mellanox Technologies BlueField Gigabit Ethernet support"
-	depends on (ARM64 || COMPILE_TEST) && ACPI
+	depends on (ARM64 || COMPILE_TEST) && ACPI && INET
 	select PHYLIB
 	help
 	  The second generation BlueField SoC from Mellanox Technologies
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
index e488962bd411..0fd540bc50f7 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
@@ -10,7 +10,6 @@
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
@@ -19,7 +18,7 @@
 #include "mlxbf_gige_regs.h"
 
 #define DRV_NAME    "mlxbf_gige"
-#define DRV_VERSION "1.4"
+#define DRV_VERSION "1.3"
 
 static void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv,
 					 unsigned int index, u64 dmac)
@@ -146,6 +145,9 @@ static int mlxbf_gige_rx_init(struct mlxbf_gige *priv)
 	/* Write RX_WQE_PI with current number of replenished buffers */
 	writeq(priv->rx_q_entries, priv->base + MLXBF_GIGE_RX_WQE_PI);
 
+	/* Enable RX DMA to write new packets to memory */
+	writeq(MLXBF_GIGE_RX_DMA_EN, priv->base + MLXBF_GIGE_RX_DMA);
+
 	/* Enable removal of CRC during RX */
 	data = readq(priv->base + MLXBF_GIGE_RX);
 	data |= MLXBF_GIGE_RX_STRIP_CRC_EN;
@@ -158,15 +160,12 @@ static int mlxbf_gige_rx_init(struct mlxbf_gige *priv)
 	       priv->base + MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS);
 
 	/* Clear MLXBF_GIGE_INT_MASK 'receive pkt' bit to
-	 * indicate readiness to receive interrupts
+	 * indicate readiness to receive pkts
 	 */
 	data = readq(priv->base + MLXBF_GIGE_INT_MASK);
 	data &= ~MLXBF_GIGE_INT_MASK_RX_RECEIVE_PACKET;
 	writeq(data, priv->base + MLXBF_GIGE_INT_MASK);
 
-	/* Enable RX DMA to write new packets to memory */
-	writeq(MLXBF_GIGE_RX_DMA_EN, priv->base + MLXBF_GIGE_RX_DMA);
-
 	writeq(ilog2(priv->rx_q_entries),
 	       priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2);
 
@@ -207,6 +206,7 @@ static int mlxbf_gige_tx_init(struct mlxbf_gige *priv)
 	/* Allocate address for TX completion count */
 	priv->tx_cc = dma_alloc_coherent(priv->dev, MLXBF_GIGE_TX_CC_SZ,
 					 &priv->tx_cc_dma, GFP_KERNEL);
+
 	if (!priv->tx_cc) {
 		dma_free_coherent(priv->dev, size,
 				  priv->tx_wqe_base, priv->tx_wqe_base_dma);
@@ -300,13 +300,20 @@ static void mlxbf_gige_tx_deinit(struct mlxbf_gige *priv)
 /* Start of struct ethtool_ops functions */
 static int mlxbf_gige_get_regs_len(struct net_device *netdev)
 {
-	return MLXBF_GIGE_MMIO_REG_SZ;
+	/* Return size of MMIO register space (in bytes).
+	 *
+	 * NOTE: MLXBF_GIGE_MAC_CFG is the last defined register offset,
+	 * so use that plus size of single register to derive total size
+	 */
+	return MLXBF_GIGE_MAC_CFG + 8;
 }
 
 static void mlxbf_gige_get_regs(struct net_device *netdev,
 				struct ethtool_regs *regs, void *p)
 {
 	struct mlxbf_gige *priv = netdev_priv(netdev);
+	__be64 *buff = p;
+	int reg;
 
 	regs->version = MLXBF_GIGE_REGS_VERSION;
 
@@ -317,7 +324,8 @@ static void mlxbf_gige_get_regs(struct net_device *netdev,
 	 * NOTE: by design, a read to an offset without an existing
 	 *       register will be acknowledged and return zero.
 	 */
-	memcpy_fromio(p, priv->base, MLXBF_GIGE_MMIO_REG_SZ);
+	for (reg = 0; reg <= MLXBF_GIGE_MAC_CFG; reg += 8)
+		*buff++ = cpu_to_be64(readq(priv->base + reg));
 }
 
 static void mlxbf_gige_get_ringparam(struct net_device *netdev,
@@ -325,6 +333,7 @@ static void mlxbf_gige_get_ringparam(struct net_device *netdev,
 {
 	struct mlxbf_gige *priv = netdev_priv(netdev);
 
+	memset(ering, 0, sizeof(*ering));
 	ering->rx_max_pending = MLXBF_GIGE_MAX_RXQ_SZ;
 	ering->tx_max_pending = MLXBF_GIGE_MAX_TXQ_SZ;
 	ering->rx_pending = priv->rx_q_entries;
@@ -346,9 +355,11 @@ static int mlxbf_gige_set_ringparam(struct net_device *netdev,
 	new_rx_q_entries = roundup_pow_of_two(ering->rx_pending);
 	new_tx_q_entries = roundup_pow_of_two(ering->tx_pending);
 
-	/* Check against min values, core checks against max values */
+	/* Range check the new values */
 	if (new_tx_q_entries < MLXBF_GIGE_MIN_TXQ_SZ ||
-	    new_rx_q_entries < MLXBF_GIGE_MIN_RXQ_SZ)
+	    new_tx_q_entries > MLXBF_GIGE_MAX_TXQ_SZ ||
+	    new_rx_q_entries < MLXBF_GIGE_MIN_RXQ_SZ ||
+	    new_rx_q_entries > MLXBF_GIGE_MAX_RXQ_SZ)
 		return -EINVAL;
 
 	/* If queue sizes did not change, exit now */
@@ -368,9 +379,21 @@ static int mlxbf_gige_set_ringparam(struct net_device *netdev,
 	return 0;
 }
 
+static void mlxbf_gige_get_drvinfo(struct net_device *netdev,
+				   struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+	strlcpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info));
+}
+
 static const struct {
 	const char string[ETH_GSTRING_LEN];
 } mlxbf_gige_ethtool_stats_keys[] = {
+	{ "rx_bytes" },
+	{ "rx_packets" },
+	{ "tx_bytes" },
+	{ "tx_packets" },
 	{ "hw_access_errors" },
 	{ "tx_invalid_checksums" },
 	{ "tx_small_frames" },
@@ -408,6 +431,8 @@ static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
 	struct mlxbf_gige *priv = netdev_priv(netdev);
 	unsigned long flags;
 
+	spin_lock_irqsave(&priv->lock, flags);
+
 	/* Fill data array with interface statistics
 	 *
 	 * NOTE: the data writes must be in
@@ -423,6 +448,10 @@ static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
 	 *          rx_filter_passed_pkts
 	 *          rx_filter_discard_pkts
 	 */
+	*data++ = netdev->stats.rx_bytes;
+	*data++ = netdev->stats.rx_packets;
+	*data++ = netdev->stats.tx_bytes;
+	*data++ = netdev->stats.tx_packets;
 	*data++ = priv->stats.hw_access_errors;
 	*data++ = priv->stats.tx_invalid_checksums;
 	*data++ = priv->stats.tx_small_frames;
@@ -438,6 +467,8 @@ static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
 		   readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL));
 	*data++ = (priv->stats.rx_filter_discard_pkts +
 		   readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL));
+
+	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void mlxbf_gige_get_pauseparam(struct net_device *netdev,
@@ -451,6 +482,7 @@ static void mlxbf_gige_get_pauseparam(struct net_device *netdev,
 }
 
 static const struct ethtool_ops mlxbf_gige_ethtool_ops = {
+	.get_drvinfo		= mlxbf_gige_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
 	.get_ringparam		= mlxbf_gige_get_ringparam,
 	.set_ringparam		= mlxbf_gige_set_ringparam,
@@ -532,12 +564,18 @@ static irqreturn_t mlxbf_gige_rx_intr(int irq, void *dev_id)
 
 	priv->rx_intr_count++;
 
-	/* NOTE: GigE silicon automatically disables "packet rx" interrupt by
+	/* Driver has been interrupted because a new packet is available,
+	 * but do not process packets at this time.  Instead, disable any
+	 * further "packet rx" interrupts and tell the networking subsystem
+	 * to poll the driver to pick up all available packets.
+	 *
+	 * NOTE: GigE silicon automatically disables "packet rx" interrupt by
 	 *       setting MLXBF_GIGE_INT_MASK bit0 upon triggering the interrupt
 	 *       to the ARM cores.  Software needs to re-enable "packet rx"
 	 *       interrupts by clearing MLXBF_GIGE_INT_MASK bit0.
 	 */
 
+	/* Tell networking subsystem to poll GigE driver */
 	napi_schedule(&priv->napi);
 
 	return IRQ_HANDLED;
@@ -628,8 +666,9 @@ static bool mlxbf_gige_handle_tx_complete(struct mlxbf_gige *priv)
 	 * available the TX queue can be awakened.
 	 */
 	if (netif_queue_stopped(priv->netdev) &&
-	    mlxbf_gige_tx_buffs_avail(priv))
+	    mlxbf_gige_tx_buffs_avail(priv)) {
 		netif_wake_queue(priv->netdev);
+	}
 
 	return true;
 }
@@ -726,22 +765,25 @@ static int mlxbf_gige_request_irqs(struct mlxbf_gige *priv)
 {
 	int err;
 
-	err = request_irq(priv->error_irq, mlxbf_gige_error_intr, 0,
-			  "mlxbf_gige_error", priv);
+	err = devm_request_irq(priv->dev, priv->error_irq,
+			       mlxbf_gige_error_intr, 0, "mlxbf_gige_error",
+			       priv);
 	if (err) {
 		dev_err(priv->dev, "Request error_irq failure\n");
 		return err;
 	}
 
-	err = request_irq(priv->rx_irq, mlxbf_gige_rx_intr, 0,
-			  "mlxbf_gige_rx", priv);
+	err = devm_request_irq(priv->dev, priv->rx_irq,
+			       mlxbf_gige_rx_intr, 0, "mlxbf_gige_rx",
+			       priv);
 	if (err) {
 		dev_err(priv->dev, "Request rx_irq failure\n");
 		return err;
 	}
 
-	err = request_irq(priv->llu_plu_irq, mlxbf_gige_llu_plu_intr, 0,
-			  "mlxbf_gige_llu_plu", priv);
+	err = devm_request_irq(priv->dev, priv->llu_plu_irq,
+			       mlxbf_gige_llu_plu_intr, 0, "mlxbf_gige_llu_plu",
+			       priv);
 	if (err) {
 		dev_err(priv->dev, "Request llu_plu_irq failure\n");
 		return err;
@@ -761,9 +803,9 @@ static int mlxbf_gige_request_irqs(struct mlxbf_gige *priv)
 
 static void mlxbf_gige_free_irqs(struct mlxbf_gige *priv)
 {
-	free_irq(priv->error_irq, priv);
-	free_irq(priv->rx_irq, priv);
-	free_irq(priv->llu_plu_irq, priv);
+	devm_free_irq(priv->dev, priv->error_irq, priv);
+	devm_free_irq(priv->dev, priv->rx_irq, priv);
+	devm_free_irq(priv->dev, priv->llu_plu_irq, priv);
 	free_irq(priv->phy_irq, priv);
 }
 
@@ -783,18 +825,22 @@ static void mlxbf_gige_cache_stats(struct mlxbf_gige *priv)
 
 static void mlxbf_gige_clean_port(struct mlxbf_gige *priv)
 {
-	u64 control;
-	u64 temp;
-	int ret;
+	u64 control, status;
+	int cnt;
 
 	/* Set the CLEAN_PORT_EN bit to trigger SW reset */
 	control = readq(priv->base + MLXBF_GIGE_CONTROL);
 	control |= MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
 	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
 
-	ret = readq_poll_timeout_atomic(priv->base + MLXBF_GIGE_STATUS, temp,
-					(temp & MLXBF_GIGE_STATUS_READY),
-					100, 100000);
+	/* Loop waiting for status ready bit to assert */
+	cnt = 1000;
+	do {
+		status = readq(priv->base + MLXBF_GIGE_STATUS);
+		if (status & MLXBF_GIGE_STATUS_READY)
+			break;
+		usleep_range(50, 100);
+	} while (--cnt > 0);
 
 	/* Clear the CLEAN_PORT_EN bit at end of this loop */
 	control = readq(priv->base + MLXBF_GIGE_CONTROL);
@@ -1020,6 +1066,28 @@ static const struct net_device_ops mlxbf_gige_netdev_ops = {
 	.ndo_set_rx_mode        = mlxbf_gige_set_rx_mode,
 };
 
+static u64 mlxbf_gige_mac_to_u64(u8 *addr)
+{
+	u64 mac = 0;
+	int i;
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		mac <<= 8;
+		mac |= addr[i];
+	}
+	return mac;
+}
+
+static void mlxbf_gige_u64_to_mac(u8 *addr, u64 mac)
+{
+	int i;
+
+	for (i = ETH_ALEN; i > 0; i--) {
+		addr[i - 1] = mac & 0xFF;
+		mac >>= 8;
+	}
+}
+
 static void mlxbf_gige_initial_mac(struct mlxbf_gige *priv)
 {
 	u8 mac[ETH_ALEN];
@@ -1027,7 +1095,7 @@ static void mlxbf_gige_initial_mac(struct mlxbf_gige *priv)
 
 	mlxbf_gige_get_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX,
 				     &local_mac);
-	u64_to_ether_addr(local_mac, mac);
+	mlxbf_gige_u64_to_mac(mac, local_mac);
 
 	if (is_valid_ether_addr(mac)) {
 		ether_addr_copy(priv->netdev->dev_addr, mac);
@@ -1038,7 +1106,7 @@ static void mlxbf_gige_initial_mac(struct mlxbf_gige *priv)
 		eth_hw_addr_random(priv->netdev);
 	}
 
-	local_mac = ether_addr_to_u64(priv->netdev->dev_addr);
+	local_mac = mlxbf_gige_mac_to_u64(priv->netdev->dev_addr);
 	mlxbf_gige_set_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX,
 				     local_mac);
 }
@@ -1222,7 +1290,7 @@ static struct platform_driver mlxbf_gige_driver = {
 module_platform_driver(mlxbf_gige_driver);
 
 MODULE_DESCRIPTION("Mellanox BlueField SoC Gigabit Ethernet Driver");
-MODULE_AUTHOR("David Thompson <davthompson at nvidia.com>");
-MODULE_AUTHOR("Asmaa Mnebhi <asmaa at nvidia.com>");
+MODULE_AUTHOR("David Thompson <dthompson at mellanox.com>");
+MODULE_AUTHOR("Asmaa Mnebhi <asmaa at mellanox.com>");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
index 41e4450bd290..06e3c7145bbd 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
@@ -70,9 +70,4 @@
 #define MLXBF_GIGE_RX_CQE_PACKET_CI                   0x05b0
 #define MLXBF_GIGE_MAC_CFG                            0x05e8
 
-/* NOTE: MLXBF_GIGE_MAC_CFG is the last defined register offset,
- * so use that plus size of single register to derive total size
- */
-#define MLXBF_GIGE_MMIO_REG_SZ                        (MLXBF_GIGE_MAC_CFG+8)
-
 #endif /* !defined(__MLXBF_GIGE_REGS_H__) */
-- 
2.30.1




More information about the kernel-team mailing list