kernel: Backport mv88e6xxx patch to keep pvid at 0 if VLAN-unaware and remove hack
[openwrt/openwrt.git] / target / linux / generic / backport-5.10 / 771-v5.14-net-phy-add-MediaTek-Gigabit-Ethernet-PHY-driver.patch
1 From e40d2cca01893c1941f5959b14bb0cd0d4f4d099 Mon Sep 17 00:00:00 2001
2 From: DENG Qingfang <dqfext@gmail.com>
3 Date: Wed, 19 May 2021 11:31:59 +0800
4 Subject: [PATCH] net: phy: add MediaTek Gigabit Ethernet PHY driver
5
6 Add support for MediaTek Gigabit Ethernet PHYs found in MT7530 and
7 MT7531 switches.
8 The initialization procedure is from the vendor driver, but due to lack
9 of documentation, the function of some register values remains unknown.
10
11 Signed-off-by: DENG Qingfang <dqfext@gmail.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 ---
14 drivers/net/phy/Kconfig | 5 ++
15 drivers/net/phy/Makefile | 1 +
16 drivers/net/phy/mediatek-ge.c | 116 ++++++++++++++++++++++++++++++++++
17 3 files changed, 122 insertions(+)
18 create mode 100644 drivers/net/phy/mediatek-ge.c
19
20 --- a/drivers/net/phy/Kconfig
21 +++ b/drivers/net/phy/Kconfig
22 @@ -201,6 +201,11 @@ config MARVELL_10G_PHY
23 help
24 Support for the Marvell Alaska MV88X3310 and compatible PHYs.
25
26 +config MEDIATEK_GE_PHY
27 + tristate "MediaTek PHYs"
28 + help
29 + Supports the MediaTek switch integrated PHYs.
30 +
31 config MICREL_PHY
32 tristate "Micrel PHYs"
33 help
34 --- a/drivers/net/phy/Makefile
35 +++ b/drivers/net/phy/Makefile
36 @@ -63,6 +63,7 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c
37 obj-$(CONFIG_LXT_PHY) += lxt.o
38 obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
39 obj-$(CONFIG_MARVELL_PHY) += marvell.o
40 +obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
41 obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
42 obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
43 obj-$(CONFIG_MICREL_PHY) += micrel.o
44 --- /dev/null
45 +++ b/drivers/net/phy/mediatek-ge.c
46 @@ -0,0 +1,113 @@
47 +// SPDX-License-Identifier: GPL-2.0+
48 +#include <linux/bitfield.h>
49 +#include <linux/module.h>
50 +#include <linux/phy.h>
51 +
52 +#define MTK_T10_TEST_CONTROL 0x145
53 +#define MTK_PHY_TP_MASK GENMASK(4, 3)
54 +#define MTK_PHY_TP_AUTO 0
55 +#define MTK_PHY_TP_MDI 2
56 +#define MTK_PHY_TP_MDIX 3
57 +
58 +#define MTK_EXT_PAGE_ACCESS 0x1f
59 +#define MTK_PHY_PAGE_STANDARD 0x0000
60 +#define MTK_PHY_PAGE_EXTENDED 0x0001
61 +#define MTK_PHY_PAGE_EXTENDED_2 0x0002
62 +#define MTK_PHY_PAGE_EXTENDED_3 0x0003
63 +#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
64 +#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
65 +
66 +static int mtk_gephy_read_page(struct phy_device *phydev)
67 +{
68 + return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
69 +}
70 +
71 +static int mtk_gephy_write_page(struct phy_device *phydev, int page)
72 +{
73 + return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
74 +}
75 +
76 +static void mtk_gephy_config_init(struct phy_device *phydev)
77 +{
78 + /* Disable EEE */
79 + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
80 +
81 + /* Enable HW auto downshift */
82 + phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
83 +
84 + /* Increase SlvDPSready time */
85 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
86 + __phy_write(phydev, 0x10, 0xafae);
87 + __phy_write(phydev, 0x12, 0x2f);
88 + __phy_write(phydev, 0x10, 0x8fae);
89 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
90 +
91 + /* Adjust 100_mse_threshold */
92 + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
93 +
94 + /* Disable mcc */
95 + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
96 +}
97 +
98 +static int mt7530_phy_config_init(struct phy_device *phydev)
99 +{
100 + mtk_gephy_config_init(phydev);
101 +
102 + /* Increase post_update_timer */
103 + phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
104 +
105 + return 0;
106 +}
107 +
108 +static int mt7531_phy_config_init(struct phy_device *phydev)
109 +{
110 + mtk_gephy_config_init(phydev);
111 +
112 + /* PHY link down power saving enable */
113 + phy_set_bits(phydev, 0x17, BIT(4));
114 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
115 +
116 + /* Set TX Pair delay selection */
117 + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
118 + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
119 +
120 + return 0;
121 +}
122 +
123 +static struct phy_driver mtk_gephy_driver[] = {
124 + {
125 + PHY_ID_MATCH_EXACT(0x03a29412),
126 + .name = "MediaTek MT7530 PHY",
127 + .config_init = mt7530_phy_config_init,
128 + /* Interrupts are handled by the switch, not the PHY
129 + * itself.
130 + */
131 + .config_intr = genphy_no_config_intr,
132 + .ack_interrupt = genphy_no_ack_interrupt,
133 + .suspend = genphy_suspend,
134 + .resume = genphy_resume,
135 + .read_page = mtk_gephy_read_page,
136 + .write_page = mtk_gephy_write_page,
137 + },
138 + {
139 + PHY_ID_MATCH_EXACT(0x03a29441),
140 + .name = "MediaTek MT7531 PHY",
141 + .config_init = mt7531_phy_config_init,
142 + /* Interrupts are handled by the switch, not the PHY
143 + * itself.
144 + */
145 + .config_intr = genphy_no_config_intr,
146 + .ack_interrupt = genphy_no_ack_interrupt,
147 + .suspend = genphy_suspend,
148 + .resume = genphy_resume,
149 + .read_page = mtk_gephy_read_page,
150 + .write_page = mtk_gephy_write_page,
151 + },
152 +};
153 +
154 +module_phy_driver(mtk_gephy_driver);
155 +
156 +static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
157 + { PHY_ID_MATCH_VENDOR(0x03a29400) },
158 + { }
159 +};