On Thu, Apr 29, 2021 at 02:21:27PM +0800, DENG Qingfang wrote: > Add support for MediaTek PHYs found in MT7530 and MT7531 switches. > The initialization procedure is from the vendor driver, but due to lack > of documentation, the function of some register values remains unknown. > > Signed-off-by: DENG Qingfang <dqfext@xxxxxxxxx> > --- > RFC v4 -> PATCH v1: > - No changes. > > drivers/net/phy/Kconfig | 5 ++ > drivers/net/phy/Makefile | 1 + > drivers/net/phy/mediatek.c | 112 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 118 insertions(+) > create mode 100644 drivers/net/phy/mediatek.c > > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig > index 288bf405ebdb..9db39fb443e6 100644 > --- a/drivers/net/phy/Kconfig > +++ b/drivers/net/phy/Kconfig > @@ -207,6 +207,11 @@ config MARVELL_88X2222_PHY > Support for the Marvell 88X2222 Dual-port Multi-speed Ethernet > Transceiver. > > +config MEDIATEK_PHY > + tristate "MediaTek PHYs" > + help > + Supports the MediaTek switch integrated PHYs. > + > config MICREL_PHY > tristate "Micrel PHYs" > help > diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile > index bcda7ed2455d..ab512cb3592b 100644 > --- a/drivers/net/phy/Makefile > +++ b/drivers/net/phy/Makefile > @@ -64,6 +64,7 @@ obj-$(CONFIG_LXT_PHY) += lxt.o > obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o > obj-$(CONFIG_MARVELL_PHY) += marvell.o > obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o > +obj-$(CONFIG_MEDIATEK_PHY) += mediatek.o > obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o > obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o > obj-$(CONFIG_MICREL_PHY) += micrel.o > diff --git a/drivers/net/phy/mediatek.c b/drivers/net/phy/mediatek.c > new file mode 100644 > index 000000000000..86e6c466b0e9 > --- /dev/null > +++ b/drivers/net/phy/mediatek.c > @@ -0,0 +1,112 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +#include <linux/bitfield.h> > +#include <linux/module.h> > +#include <linux/phy.h> > + > +#define MTK_EXT_PAGE_ACCESS 0x1f > +#define MTK_PHY_PAGE_STANDARD 0x0000 > +#define MTK_PHY_PAGE_EXTENDED 0x0001 > +#define MTK_PHY_PAGE_EXTENDED_2 0x0002 > +#define MTK_PHY_PAGE_EXTENDED_3 0x0003 > +#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 > +#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 > + > +static int mtk_phy_read_page(struct phy_device *phydev) > +{ > + return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); > +} > + > +static int mtk_phy_write_page(struct phy_device *phydev, int page) > +{ > + return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); > +} > + > +static void mtk_phy_config_init(struct phy_device *phydev) > +{ > + /* Disable EEE */ > + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); Is there any ERR around this (i.e. is the feature universally broken or just on your setup)? There is a function called of_set_phy_eee_broken, you can let the PHY core disable EEE advertisement based on device tree. > + > + /* Enable HW auto downshift */ > + phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); > + > + /* Increase SlvDPSready time */ > + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); > + __phy_write(phydev, 0x10, 0xafae); > + __phy_write(phydev, 0x12, 0x2f); > + __phy_write(phydev, 0x10, 0x8fae); > + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); > + > + /* Adjust 100_mse_threshold */ > + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff); > + > + /* Disable mcc */ > + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); > +}