From bedbef8ad3e75a304af6361af235302bcc61d06b Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 14 May 2024 06:39:01 +0000 Subject: [PATCH] 修改内核路径 --- kernel/drivers/net/phy/microchip.c | 83 +++++++++++++++++++++++++---------------- 1 files changed, 51 insertions(+), 32 deletions(-) diff --git a/kernel/drivers/net/phy/microchip.c b/kernel/drivers/net/phy/microchip.c index 2d67937..375bbd6 100644 --- a/kernel/drivers/net/phy/microchip.c +++ b/kernel/drivers/net/phy/microchip.c @@ -1,18 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Microchip Technology - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/module.h> @@ -88,7 +76,7 @@ /* Save current page */ save_page = phy_save_page(phydev); if (save_page < 0) { - pr_warn("Failed to get current page\n"); + phydev_warn(phydev, "Failed to get current page\n"); goto err; } @@ -98,14 +86,14 @@ ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA, (data & 0xFFFF)); if (ret < 0) { - pr_warn("Failed to write TR low data\n"); + phydev_warn(phydev, "Failed to write TR low data\n"); goto err; } ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA, (data & 0x00FF0000) >> 16); if (ret < 0) { - pr_warn("Failed to write TR high data\n"); + phydev_warn(phydev, "Failed to write TR high data\n"); goto err; } @@ -115,14 +103,15 @@ ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf); if (ret < 0) { - pr_warn("Failed to write data in reg\n"); + phydev_warn(phydev, "Failed to write data in reg\n"); goto err; } usleep_range(1000, 2000);/* Wait for Data to be written */ val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR); if (!(val & 0x8000)) - pr_warn("TR Register[0x%X] configuration failed\n", regaddr); + phydev_warn(phydev, "TR Register[0x%X] configuration failed\n", + regaddr); err: return phy_restore_page(phydev, save_page, ret); } @@ -137,7 +126,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A); if (err < 0) - pr_warn("Failed to Set Register[0x0F82]\n"); + phydev_warn(phydev, "Failed to Set Register[0x0F82]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x06. * Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv, @@ -145,7 +134,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F); if (err < 0) - pr_warn("Failed to Set Register[0x168C]\n"); + phydev_warn(phydev, "Failed to Set Register[0x168C]\n"); /* Get access to Channel b'10, Node b'1111, Register 0x11. * Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh @@ -153,7 +142,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620); if (err < 0) - pr_warn("Failed to Set Register[0x17A2]\n"); + phydev_warn(phydev, "Failed to Set Register[0x17A2]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x10. * Write 24-bit value 0xEEFFDD to register. Setting @@ -162,7 +151,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD); if (err < 0) - pr_warn("Failed to Set Register[0x16A0]\n"); + phydev_warn(phydev, "Failed to Set Register[0x16A0]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x13. * Write 24-bit value 0x071448 to register. Setting @@ -170,7 +159,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448); if (err < 0) - pr_warn("Failed to Set Register[0x16A6]\n"); + phydev_warn(phydev, "Failed to Set Register[0x16A6]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x12. * Write 24-bit value 0x13132F to register. Setting @@ -178,7 +167,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F); if (err < 0) - pr_warn("Failed to Set Register[0x16A4]\n"); + phydev_warn(phydev, "Failed to Set Register[0x16A4]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x14. * Write 24-bit value 0x0 to register. Setting eee_3level_delay, @@ -186,7 +175,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0); if (err < 0) - pr_warn("Failed to Set Register[0x16A8]\n"); + phydev_warn(phydev, "Failed to Set Register[0x16A8]\n"); /* Get access to Channel b'01, Node b'1111, Register 0x34. * Write 24-bit value 0x91B06C to register. Setting @@ -195,7 +184,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C); if (err < 0) - pr_warn("Failed to Set Register[0x0FE8]\n"); + phydev_warn(phydev, "Failed to Set Register[0x0FE8]\n"); /* Get access to Channel b'01, Node b'1111, Register 0x3E. * Write 24-bit value 0xC0A028 to register. Setting @@ -204,7 +193,7 @@ */ err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028); if (err < 0) - pr_warn("Failed to Set Register[0x0FFC]\n"); + phydev_warn(phydev, "Failed to Set Register[0x0FFC]\n"); /* Get access to Channel b'01, Node b'1111, Register 0x35. * Write 24-bit value 0x041600 to register. Setting @@ -213,14 +202,14 @@ */ err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600); if (err < 0) - pr_warn("Failed to Set Register[0x0FEA]\n"); + phydev_warn(phydev, "Failed to Set Register[0x0FEA]\n"); /* Get access to Channel b'10, Node b'1101, Register 0x03. * Write 24-bit value 0x000004 to register. Setting TrFreeze bits. */ err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004); if (err < 0) - pr_warn("Failed to Set Register[0x1686]\n"); + phydev_warn(phydev, "Failed to Set Register[0x1686]\n"); } static int lan88xx_probe(struct phy_device *phydev) @@ -316,7 +305,6 @@ { int val; - genphy_config_init(phydev); /*Zerodetect delay enable */ val = phy_read_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG); @@ -338,20 +326,51 @@ return genphy_config_aneg(phydev); } +static void lan88xx_link_change_notify(struct phy_device *phydev) +{ + int temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ + if (!phydev->autoneg && phydev->speed == 100) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ + temp |= BMCR_SPEED100; + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ + + /* clear pending interrupt generated while workaround */ + temp = phy_read(phydev, LAN88XX_INT_STS); + + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + } +} + static struct phy_driver microchip_phy_driver[] = { { .phy_id = 0x0007c130, .phy_id_mask = 0xfffffff0, .name = "Microchip LAN88xx", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, + /* PHY_GBIT_FEATURES */ .probe = lan88xx_probe, .remove = lan88xx_remove, .config_init = lan88xx_config_init, .config_aneg = lan88xx_config_aneg, + .link_change_notify = lan88xx_link_change_notify, .ack_interrupt = lan88xx_phy_ack_interrupt, .config_intr = lan88xx_phy_config_intr, -- Gitblit v1.6.2