aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4103-modifying-link-and-led-state-with-respect-to-cable-c.patch
diff options
context:
space:
mode:
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.patch210
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
+