diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch new file mode 100644 index 00000000..447629ee --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch @@ -0,0 +1,210 @@ +From 89a9f6eee64e54ce282584cfc7bedcdd944f7c4b Mon Sep 17 00:00:00 2001 +From: Pavan Kumar Ramayanam <pavan.ramayanam@amd.com> +Date: Tue, 12 Nov 2019 18:15:16 +0530 +Subject: [PATCH 4103/4736] modifying link and led state with respect to cable + connection + + Enable Marvell PHY 10G linkup on Bilby. The current + 10G linkup happens only in backplane mode, meaning there will be no sideband + to talk to the external PHY connected onboard. So, when the driver reads the + port property as BACKPLANE, technically we are not supposed to go and read + what is the external PHY connected through MDIO. This changes are only a + workaround to read the external phy through MDIO in backplane mode. +--- + drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 30 ++++++-- + drivers/net/phy/marvell10g.c | 80 ++++++++++++++++++++- + 2 files changed, 105 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +index 9cddcc8433e1..a6fb6754984f 100755 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +@@ -156,6 +156,11 @@ + /* RRC frequency during link status check */ + #define XGBE_RRC_FREQUENCY 10 + ++/* Enable Marvell PHY writes by forcing the MDIO connections */ ++static int force_mdio_mv_bp_con = 1; ++module_param(force_mdio_mv_bp_con, uint, 0644); ++MODULE_PARM_DESC(force_mdio_mv_bp_con, ++ " Enable Marvell PHY writes by forcing the MDIO connections"); + enum xgbe_port_mode { + XGBE_PORT_MODE_RSVD = 0, + XGBE_PORT_MODE_BACKPLANE, +@@ -985,8 +990,15 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) + pdata->an_again = 0; + + /* Check for the use of an external PHY */ +- if (phy_data->phydev_mode == XGBE_MDIO_MODE_NONE) +- return 0; ++ if (phy_data->phydev_mode == XGBE_MDIO_MODE_NONE) { ++ if(force_mdio_mv_bp_con) { ++ phy_data->phydev_mode = XGBE_MDIO_MODE_CL45; ++ phy_data->conn_type = XGBE_CONN_TYPE_MDIO; ++ netif_dbg(pdata, drv, pdata->netdev, "*** DEBUG: %s - bypass phydev_mode check\n", __func__); ++ } else { ++ return 0; ++ } ++ } + + /* For SFP, only use an external PHY if available */ + if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) && +@@ -1011,7 +1023,7 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) + return -ENODEV; + } + netif_dbg(pdata, drv, pdata->netdev, "external PHY id is %#010x\n", +- phydev->phy_id); ++ (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45) ? phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] : phydev->phy_id); + + /*TODO: If c45, add request_module based on one of the MMD ids? */ + +@@ -1034,6 +1046,14 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) + + xgbe_phy_external_phy_quirks(pdata); + ++ if(force_mdio_mv_bp_con) { ++ phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; ++ phy_data->conn_type = XGBE_CONN_TYPE_BACKPLANE; ++ netif_dbg(pdata, drv, pdata->netdev, "phy_dev removed!\n"); ++ xgbe_phy_free_phy_device(pdata); ++ return 0; ++ } ++ + ethtool_convert_link_mode_to_legacy_u32(&advertising, + lks->link_modes.advertising); + phydev->advertising &= advertising; +@@ -2551,8 +2571,10 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) + return 0; + + if ((pdata->phy.autoneg == AUTONEG_ENABLE) && +- !phy_aneg_done(phy_data->phydev)) ++ !phy_aneg_done(phy_data->phydev)) { ++ netif_dbg(pdata, drv, pdata->netdev,"%s Ext phy AN not complete!\n", __func__); + return 0; ++ } + + if (!phy_data->phydev->link) + return 0; +diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c +index f77a2d9e7f9d..080272a3d2b6 100644 +--- a/drivers/net/phy/marvell10g.c ++++ b/drivers/net/phy/marvell10g.c +@@ -25,6 +25,7 @@ + #include <linux/hwmon.h> + #include <linux/marvell_phy.h> + #include <linux/phy.h> ++#include <linux/delay.h> + + enum { + MV_PCS_BASE_T = 0x0000, +@@ -48,7 +49,12 @@ enum { + MV_V2_TEMP_CTRL_MASK = 0xc000, + MV_V2_TEMP_CTRL_SAMPLE = 0x0000, + MV_V2_TEMP_CTRL_DISABLE = 0xc000, ++ MV_V2_MODE_CFG = 0xf000, ++ MV_V2_PORT_CTRL = 0xf001, ++ MV_V2_LED0_CTRL = 0xf020, + MV_V2_TEMP = 0xf08c, ++ MV_V2_HOST_KR_ENABLE = 0xf084, ++ MV_V2_HOST_KR_TUNE = 0xf07c, + MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */ + }; + +@@ -75,7 +81,7 @@ static int mv3310_modify(struct phy_device *phydev, int devad, u16 reg, + return ret < 0 ? ret : 1; + } + +-#ifdef CONFIG_HWMON ++#ifdef CONFIG_HWMON_MV + static umode_t mv3310_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +@@ -249,6 +255,77 @@ static int mv3310_resume(struct phy_device *phydev) + return mv3310_hwmon_config(phydev, true); + } + ++ ++/* Some PHYs within the Alaska family like 88x3310 has problems with the ++ * KR Auto-negotiation. marvell datasheet for 88x3310 section 6.2.11 says that ++ * KR auto-negotitaion can be enabled to adapt to the incoming SERDES by writing ++ * to autoneg registers and the PMA/PMD registers ++ */ ++static int mv3310_amd_quirk(struct phy_device *phydev) ++{ ++ int reg=0, count=0; ++ int version, subversion; ++ ++ version = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 0xC011); ++ subversion = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 0xC012); ++ dev_dbg(&phydev->mdio.dev,"%s: Marvell FW Version: %x.%x \n", __func__, version, subversion); ++ ++ if(subversion != 0x400) ++ return 0; ++ ++ reg = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MV_V2_HOST_KR_ENABLE); ++ reg |= 0x8000; ++ phy_write_mmd(phydev, MDIO_MMD_PHYXS, MV_V2_HOST_KR_ENABLE, reg); ++ ++ reg = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MV_V2_HOST_KR_TUNE); ++ reg = (reg & ~0x8000) | 0x4000; ++ phy_write_mmd(phydev, MDIO_MMD_PHYXS, MV_V2_HOST_KR_TUNE, reg); ++ ++ if((reg & BIT(8)) && (reg & BIT(11))) { ++ reg = phy_read_mmd(phydev, MDIO_MMD_AN, MV_PCS_BASE_R); ++ /* disable BASE-R */ ++ phy_write_mmd(phydev, MDIO_MMD_AN, MV_PCS_BASE_R, reg); ++ } else { ++ reg = phy_read_mmd(phydev, MDIO_MMD_AN, MV_PCS_BASE_R); ++ /* enable BASE-R for KR initiation */ ++ reg |= 0x1000; ++ phy_write_mmd(phydev, MDIO_MMD_AN, MV_PCS_BASE_R, reg); ++ } ++ ++ /* down the port if no link */ ++ reg = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_MODE_CFG); ++ reg &= 0xFFF7; ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_MODE_CFG, reg); ++ ++ /* reset port to effect above change */ ++ reg = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL); ++ reg |= 0x8000; ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, reg); ++ ++ /* wait till reset complete */ ++ count = 50; ++ do { ++ msleep(10); ++ reg = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL); ++ } while ((reg & 0x8000) && --count); ++ ++ if(reg & 0x8000){ ++ dev_warn(&phydev->mdio.dev,"%s: Port Reset taking long time\n", __func__); ++ return -ETIMEDOUT; ++ } ++ ++ /* LED0 Amber light On-Off settings [1:0]=01 */ ++ reg = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_LED0_CTRL); ++ if((reg & 0x3) != 0x1) { ++ reg &= 0xFFFC; ++ reg |= 0x1; ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_LED0_CTRL, reg); ++ } ++ ++ dev_dbg(&phydev->mdio.dev,"%s: quirk applied\n", __func__); ++ return 0; ++} ++ + static int mv3310_config_init(struct phy_device *phydev) + { + __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; +@@ -274,6 +351,7 @@ static int mv3310_config_init(struct phy_device *phydev) + __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, supported); + } + ++ mv3310_amd_quirk(phydev); + val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2); + if (val < 0) + return val; +-- +2.17.1 + |