27f15d40e1
- Why I did it 1. Update Mellanox HW-MGMT package to newer version V.7.0030.1011 2. Replace the SONiC PMON Thermal control algorithm with the one inside the HW-MGMT package on all Nvidia platforms 3. Support Spectrum-4 systems - How I did it 1. Update the HW-MGMT package version number and submodule pointer 2. Remove the thermal control algorithm implementation from Mellanox platform API 3. Revise the patch to HW-MGMT package which will disable HW-MGMT from running on SIMX 4. Update the downstream kernel patch list Signed-off-by: Kebo Liu <kebol@nvidia.com>
238 lines
8.7 KiB
Diff
238 lines
8.7 KiB
Diff
From b9f0d98629a7720d2b6e34aed529f943cf421c04 Mon Sep 17 00:00:00 2001
|
|
From: David Thompson <davthompson@nvidia.com>
|
|
Date: Tue, 25 Oct 2022 17:19:27 -0400
|
|
Subject: [PATCH backport 5.10 41/63] UBUNTU: SAUCE: mlxbf_gige: support
|
|
10M/100M/1G speeds on BlueField-3
|
|
|
|
BugLink: https://bugs.launchpad.net/bugs/1995148
|
|
|
|
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>
|
|
---
|
|
.../ethernet/mellanox/mlxbf_gige/mlxbf_gige.h | 8 ++
|
|
.../mellanox/mlxbf_gige/mlxbf_gige_main.c | 109 +++++++++++++++---
|
|
.../mellanox/mlxbf_gige/mlxbf_gige_regs.h | 21 ++++
|
|
3 files changed, 123 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 421a0b1b7..a453b9cd9 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 49695f3e9..106b83bd6 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
|
|
@@ -270,13 +270,103 @@ 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;
|
|
+ unsigned long flags;
|
|
+ u8 sgmii_mode;
|
|
+ u16 ipg_size;
|
|
+ u32 val;
|
|
+
|
|
+ spin_lock_irqsave(&priv->lock, flags);
|
|
+ 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:
|
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
|
+ 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;
|
|
+ }
|
|
+ spin_unlock_irqrestore(&priv->lock, flags);
|
|
+
|
|
+ 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;
|
|
@@ -395,25 +485,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 8d52dbef4..cd0973229 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
|
|
|