787dd7221d
Why I did it Add platform support for Debian 12 (Bookworm) on Mellanox Platform How I did it Update hw-management to v7.0030.2008 Deprecate the sfp_count == module_count approach in favour of asic init completion Ref: Mellanox/hw-mgmt@bf4f593 Add xxd package to base image which is required by hw-management scripts Add the non-upstream flag into linux kernel cache options Update the thermalctl logic based on new sysfs attributes Fix the integrate-mlnx-hw-mgmt script to not populate the arm64 Kconfig How to verify it Build kernel and run platform tests Signed-off-by: Vivek Reddy <vkarri@nvidia.com> Co-authored-by: Junchao-Mellanox <junchao@nvidia.com> Co-authored-by: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com>
241 lines
9.0 KiB
Diff
241 lines
9.0 KiB
Diff
From 4c1187581e9c7dc8cf354278c3257d8542209269 Mon Sep 17 00:00:00 2001
|
|
From: David Thompson <davthompson@nvidia.com>
|
|
Date: Thu, 12 Jan 2023 15:26:07 -0500
|
|
Subject: [PATCH backport 6.1.42 73/85] mlxbf_gige: support 10M/100M/1G speeds
|
|
on BlueField-3
|
|
|
|
BugLink: https://bugs.launchpad.net/bugs/2012649
|
|
|
|
The BlueField-3 OOB interface supports 10Mbps, 100Mbps, and 1Gbps speeds.
|
|
The external PHY is responsible for autonegotiating the speed with the
|
|
link partner. Once the autonegotiation is done, the BlueField PLU needs
|
|
to be configured accordingly.
|
|
|
|
This patch does two things:
|
|
1) Initialize the advertised control flow/duplex/speed in the probe
|
|
based on the BlueField SoC generation (2 or 3)
|
|
2) Adjust the PLU speed config in the PHY interrupt handler
|
|
|
|
Signed-off-by: David Thompson <davthompson@nvidia.com>
|
|
Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
(cherry picked from commit 20d03d4d9437771a9b6d38d4a6027a70d78d9865)
|
|
Signed-off-by: David Thompson <davthompson@nvidia.com>
|
|
Acked-by: Tim Gardner <tim.gardner@canonical.com>
|
|
Acked-by: Bartlomiej Zolnierkiewicz <bartlomiej.zolnierkiewicz@canonical.com>
|
|
Signed-off-by: Bartlomiej Zolnierkiewicz <bartlomiej.zolnierkiewicz@canonical.com>
|
|
---
|
|
.../ethernet/mellanox/mlxbf_gige/mlxbf_gige.h | 8 ++
|
|
.../mellanox/mlxbf_gige/mlxbf_gige_main.c | 105 +++++++++++++++---
|
|
.../mellanox/mlxbf_gige/mlxbf_gige_regs.h | 21 ++++
|
|
3 files changed, 119 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
|
|
index 421a0b1b766c..a453b9cd9033 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
|
|
@@ -14,6 +14,7 @@
|
|
#include <linux/irqreturn.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/irq.h>
|
|
+#include <linux/phy.h>
|
|
|
|
/* The silicon design supports a maximum RX ring size of
|
|
* 32K entries. Based on current testing this maximum size
|
|
@@ -84,6 +85,12 @@ struct mlxbf_gige_mdio_gw {
|
|
struct mlxbf_gige_reg_param st1;
|
|
};
|
|
|
|
+struct mlxbf_gige_link_cfg {
|
|
+ void (*set_phy_link_mode)(struct phy_device *phydev);
|
|
+ void (*adjust_link)(struct net_device *netdev);
|
|
+ phy_interface_t phy_mode;
|
|
+};
|
|
+
|
|
struct mlxbf_gige {
|
|
void __iomem *base;
|
|
void __iomem *llu_base;
|
|
@@ -121,6 +128,7 @@ struct mlxbf_gige {
|
|
struct mlxbf_gige_stats stats;
|
|
u8 hw_version;
|
|
struct mlxbf_gige_mdio_gw *mdio_gw;
|
|
+ int prev_speed;
|
|
};
|
|
|
|
/* Rx Work Queue Element definitions */
|
|
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 a3bd14d5dbff..0af086703bcd 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
|
|
@@ -263,13 +263,99 @@ static const struct net_device_ops mlxbf_gige_netdev_ops = {
|
|
.ndo_get_stats64 = mlxbf_gige_get_stats64,
|
|
};
|
|
|
|
-static void mlxbf_gige_adjust_link(struct net_device *netdev)
|
|
+static void mlxbf_gige_bf2_adjust_link(struct net_device *netdev)
|
|
{
|
|
struct phy_device *phydev = netdev->phydev;
|
|
|
|
phy_print_status(phydev);
|
|
}
|
|
|
|
+static void mlxbf_gige_bf3_adjust_link(struct net_device *netdev)
|
|
+{
|
|
+ struct mlxbf_gige *priv = netdev_priv(netdev);
|
|
+ struct phy_device *phydev = netdev->phydev;
|
|
+ u8 sgmii_mode;
|
|
+ u16 ipg_size;
|
|
+ u32 val;
|
|
+
|
|
+ if (phydev->link && phydev->speed != priv->prev_speed) {
|
|
+ switch (phydev->speed) {
|
|
+ case 1000:
|
|
+ ipg_size = MLXBF_GIGE_1G_IPG_SIZE;
|
|
+ sgmii_mode = MLXBF_GIGE_1G_SGMII_MODE;
|
|
+ break;
|
|
+ case 100:
|
|
+ ipg_size = MLXBF_GIGE_100M_IPG_SIZE;
|
|
+ sgmii_mode = MLXBF_GIGE_100M_SGMII_MODE;
|
|
+ break;
|
|
+ case 10:
|
|
+ ipg_size = MLXBF_GIGE_10M_IPG_SIZE;
|
|
+ sgmii_mode = MLXBF_GIGE_10M_SGMII_MODE;
|
|
+ break;
|
|
+ default:
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ val = readl(priv->plu_base + MLXBF_GIGE_PLU_TX_REG0);
|
|
+ val &= ~(MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK | MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK);
|
|
+ val |= FIELD_PREP(MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK, ipg_size);
|
|
+ val |= FIELD_PREP(MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK, sgmii_mode);
|
|
+ writel(val, priv->plu_base + MLXBF_GIGE_PLU_TX_REG0);
|
|
+
|
|
+ val = readl(priv->plu_base + MLXBF_GIGE_PLU_RX_REG0);
|
|
+ val &= ~MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK;
|
|
+ val |= FIELD_PREP(MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK, sgmii_mode);
|
|
+ writel(val, priv->plu_base + MLXBF_GIGE_PLU_RX_REG0);
|
|
+
|
|
+ priv->prev_speed = phydev->speed;
|
|
+ }
|
|
+
|
|
+ phy_print_status(phydev);
|
|
+}
|
|
+
|
|
+static void mlxbf_gige_bf2_set_phy_link_mode(struct phy_device *phydev)
|
|
+{
|
|
+ /* MAC only supports 1000T full duplex mode */
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
|
|
+
|
|
+ /* Only symmetric pause with flow control enabled is supported so no
|
|
+ * need to negotiate pause.
|
|
+ */
|
|
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising);
|
|
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising);
|
|
+}
|
|
+
|
|
+static void mlxbf_gige_bf3_set_phy_link_mode(struct phy_device *phydev)
|
|
+{
|
|
+ /* MAC only supports full duplex mode */
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
|
|
+ phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
|
|
+
|
|
+ /* Only symmetric pause with flow control enabled is supported so no
|
|
+ * need to negotiate pause.
|
|
+ */
|
|
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising);
|
|
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising);
|
|
+}
|
|
+
|
|
+static struct mlxbf_gige_link_cfg mlxbf_gige_link_cfgs[] = {
|
|
+ [MLXBF_GIGE_VERSION_BF2] = {
|
|
+ .set_phy_link_mode = mlxbf_gige_bf2_set_phy_link_mode,
|
|
+ .adjust_link = mlxbf_gige_bf2_adjust_link,
|
|
+ .phy_mode = PHY_INTERFACE_MODE_GMII
|
|
+ },
|
|
+ [MLXBF_GIGE_VERSION_BF3] = {
|
|
+ .set_phy_link_mode = mlxbf_gige_bf3_set_phy_link_mode,
|
|
+ .adjust_link = mlxbf_gige_bf3_adjust_link,
|
|
+ .phy_mode = PHY_INTERFACE_MODE_SGMII
|
|
+ }
|
|
+};
|
|
+
|
|
static int mlxbf_gige_probe(struct platform_device *pdev)
|
|
{
|
|
struct phy_device *phydev;
|
|
@@ -359,25 +445,14 @@ static int mlxbf_gige_probe(struct platform_device *pdev)
|
|
phydev->irq = phy_irq;
|
|
|
|
err = phy_connect_direct(netdev, phydev,
|
|
- mlxbf_gige_adjust_link,
|
|
- PHY_INTERFACE_MODE_GMII);
|
|
+ mlxbf_gige_link_cfgs[priv->hw_version].adjust_link,
|
|
+ mlxbf_gige_link_cfgs[priv->hw_version].phy_mode);
|
|
if (err) {
|
|
dev_err(&pdev->dev, "Could not attach to PHY\n");
|
|
goto out;
|
|
}
|
|
|
|
- /* MAC only supports 1000T full duplex mode */
|
|
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
|
|
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
|
|
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
|
|
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
|
|
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
|
|
-
|
|
- /* Only symmetric pause with flow control enabled is supported so no
|
|
- * need to negotiate pause.
|
|
- */
|
|
- linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising);
|
|
- linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising);
|
|
+ mlxbf_gige_link_cfgs[priv->hw_version].set_phy_link_mode(phydev);
|
|
|
|
/* Display information about attached PHY device */
|
|
phy_attached_info(phydev);
|
|
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 8d52dbef4adf..cd0973229c9b 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
|
|
@@ -8,6 +8,8 @@
|
|
#ifndef __MLXBF_GIGE_REGS_H__
|
|
#define __MLXBF_GIGE_REGS_H__
|
|
|
|
+#include <linux/bitfield.h>
|
|
+
|
|
#define MLXBF_GIGE_VERSION 0x0000
|
|
#define MLXBF_GIGE_VERSION_BF2 0x0
|
|
#define MLXBF_GIGE_VERSION_BF3 0x1
|
|
@@ -78,4 +80,23 @@
|
|
*/
|
|
#define MLXBF_GIGE_MMIO_REG_SZ (MLXBF_GIGE_MAC_CFG + 8)
|
|
|
|
+#define MLXBF_GIGE_PLU_TX_REG0 0x80
|
|
+#define MLXBF_GIGE_PLU_TX_IPG_SIZE_MASK GENMASK(11, 0)
|
|
+#define MLXBF_GIGE_PLU_TX_SGMII_MODE_MASK GENMASK(15, 14)
|
|
+
|
|
+#define MLXBF_GIGE_PLU_RX_REG0 0x10
|
|
+#define MLXBF_GIGE_PLU_RX_SGMII_MODE_MASK GENMASK(25, 24)
|
|
+
|
|
+#define MLXBF_GIGE_1G_SGMII_MODE 0x0
|
|
+#define MLXBF_GIGE_10M_SGMII_MODE 0x1
|
|
+#define MLXBF_GIGE_100M_SGMII_MODE 0x2
|
|
+
|
|
+/* ipg_size default value for 1G is fixed by HW to 11 + End = 12.
|
|
+ * So for 100M it is 12 * 10 - 1 = 119
|
|
+ * For 10M, it is 12 * 100 - 1 = 1199
|
|
+ */
|
|
+#define MLXBF_GIGE_1G_IPG_SIZE 11
|
|
+#define MLXBF_GIGE_100M_IPG_SIZE 119
|
|
+#define MLXBF_GIGE_10M_IPG_SIZE 1199
|
|
+
|
|
#endif /* !defined(__MLXBF_GIGE_REGS_H__) */
|
|
--
|
|
2.20.1
|
|
|