blob: 38d6d4c6e1888e83c5adaf50509a5623000fc97e [file] [log] [blame]
developer8a021832022-08-02 23:47:49 +08001Index: drivers/net/phy/en8801sc.c
2===================================================================
3--- /dev/null
4+++ b/drivers/net/phy/en8801sc.c
5@@ -0,0 +1,449 @@
6+// SPDX-License-Identifier: GPL-2.0
7+/* FILE NAME: en8801sc.c
8+ * PURPOSE:
9+ * EN8801S phy driver for Linux
10+ * NOTES:
11+ *
12+ */
13+
14+/* INCLUDE FILE DECLARATIONS
15+ */
16+
17+#include <linux/kernel.h>
18+#include <linux/string.h>
19+#include <linux/errno.h>
20+#include <linux/unistd.h>
21+#include <linux/interrupt.h>
22+#include <linux/init.h>
23+#include <linux/delay.h>
24+#include <linux/netdevice.h>
25+#include <linux/etherdevice.h>
26+#include <linux/skbuff.h>
27+#include <linux/spinlock.h>
28+#include <linux/mm.h>
29+#include <linux/module.h>
30+#include <linux/mii.h>
31+#include <linux/ethtool.h>
32+#include <linux/phy.h>
33+#include <linux/delay.h>
34+
35+#include <linux/uaccess.h>
36+#include <linux/version.h>
37+
38+#include "en8801sc.h"
39+
40+MODULE_DESCRIPTION("Airoha EN8801S PHY drivers for MT7981 SoC");
41+MODULE_AUTHOR("Airoha");
42+MODULE_LICENSE("GPL");
43+
44+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
45+#define phydev_mdio_bus(dev) ((dev)->bus)
46+#else
47+#define phydev_mdio_bus(dev) ((dev)->mdio.bus)
48+#endif
49+
50+enum {
51+ PHY_STATE_DONE = 0,
52+ PHY_STATE_INIT = 1,
53+ PHY_STATE_PROCESS = 2,
54+};
55+
56+static int preSpeed = 0;
57+/************************************************************************
58+* F U N C T I O N S
59+************************************************************************/
60+unsigned int airoha_cl45_write(struct mii_bus *bus, u32 port, u32 devad, u32 reg, u16 val)
61+{
62+ mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, devad);
63+ mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg);
64+ mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
65+ mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, val);
66+ return 0;
67+}
68+
69+unsigned int airoha_cl45_read(struct mii_bus *bus, u32 port, u32 devad, u32 reg, u32 *read_data)
70+{
71+ mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, devad);
72+ mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg);
73+ mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
74+ *read_data = mdiobus_read(bus, port, MII_MMD_ADDR_DATA_REG);
75+ return 0;
76+}
77+
78+unsigned int airoha_cl22_read(struct mii_bus *ebus, unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data)
79+{
80+ *read_data = mdiobus_read(ebus, phy_addr, phy_register);
81+ return 0;
82+}
83+
84+unsigned int airoha_cl22_write(struct mii_bus *ebus, unsigned int phy_addr, unsigned int phy_register,unsigned int write_data)
85+{
86+ mdiobus_write(ebus, phy_addr, phy_register, write_data);
87+ return 0;
88+}
89+
90+void airoha_pbus_write(struct mii_bus *ebus, unsigned long pbus_id, unsigned long pbus_address, unsigned long pbus_data)
91+{
92+ airoha_cl22_write(ebus, pbus_id, 0x1F, (unsigned int)(pbus_address >> 6));
93+ airoha_cl22_write(ebus, pbus_id, (unsigned int)((pbus_address >> 2) & 0xf), (unsigned int)(pbus_data & 0xFFFF));
94+ airoha_cl22_write(ebus, pbus_id, 0x10, (unsigned int)(pbus_data >> 16));
95+ return;
96+}
97+
98+unsigned long airoha_pbus_read(struct mii_bus *ebus, unsigned long pbus_id, unsigned long pbus_address)
99+{
100+ unsigned long pbus_data;
101+ unsigned int pbus_data_low, pbus_data_high;
102+
103+ airoha_cl22_write(ebus, pbus_id, 0x1F, (unsigned int)(pbus_address >> 6));
104+ airoha_cl22_read(ebus, pbus_id, (unsigned int)((pbus_address >> 2) & 0xf), &pbus_data_low);
105+ airoha_cl22_read(ebus, pbus_id, 0x10, &pbus_data_high);
106+ pbus_data = (pbus_data_high << 16) + pbus_data_low;
107+ return pbus_data;
108+}
109+
110+/* Airoha Token Ring Write function */
111+void airoha_tr_reg_write(struct mii_bus *ebus, unsigned long tr_address, unsigned long tr_data)
112+{
113+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x52b5); /* page select */
114+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x11, (unsigned int)(tr_data & 0xffff));
115+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x12, (unsigned int)(tr_data >> 16));
116+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x10, (unsigned int)(tr_address | TrReg_WR));
117+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x0); /* page resetore */
118+ return;
119+}
120+
121+/* Airoha Token Ring Read function */
122+unsigned long airoha_tr_reg_read(struct mii_bus *ebus, unsigned long tr_address)
123+{
124+ unsigned long tr_data;
125+ unsigned int tr_data_low, tr_data_high;
126+
127+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x52b5); /* page select */
128+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x10, (unsigned int)(tr_address | TrReg_RD));
129+ airoha_cl22_read(ebus, EN8801S_MDIO_PHY_ID, 0x11, &tr_data_low);
130+ airoha_cl22_read(ebus, EN8801S_MDIO_PHY_ID, 0x12, &tr_data_high);
131+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x0); /* page resetore */
132+ tr_data = (tr_data_high << 16) + tr_data_low;
133+ return tr_data;
134+}
135+
136+void en8801s_led_init(struct mii_bus *mbus)
137+{
138+ u32 reg_value;
139+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x186c, 0x3);
140+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0X1870, 0x100);
141+ reg_value = (airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1880) & ~(0x3));
142+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1880, reg_value);
143+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x21, 0x8008);
144+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x22, 0x600);
145+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x23, 0xc00);
146+ /* LED0: 10M/100M */
147+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x24, 0x8006);
148+ /* LED0: blink 10M/100M Tx/Rx */
149+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x25, 0x3c);
150+ /* LED1: 1000M */
151+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x26, 0x8001);
152+ /* LED1: blink 1000M Tx/Rx */
153+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, 0x27, 0x3);
154+}
155+
156+static int en8801s_phy_process(struct phy_device *phydev)
157+{
158+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
159+ u32 reg_value = 0;
160+
161+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x19e0);
162+ reg_value |= (1 << 0);
163+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x19e0, reg_value);
164+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x19e0);
165+ reg_value &= ~(1 << 0);
166+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x19e0, reg_value);
167+ return 0;
168+}
169+
170+static int en8801s_phase1_init(struct phy_device *phydev)
171+{
172+ unsigned long pbus_data;
173+ unsigned int pbusAddress;
174+ u32 reg_value;
175+ int retry;
176+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
177+
178+ msleep(1500);
179+
180+ pbusAddress = EN8801S_PBUS_DEFAULT_ID;
181+ retry = MAX_OUI_CHECK;
182+ while(1)
183+ {
184+ pbus_data = airoha_pbus_read(mbus, pbusAddress, EN8801S_RG_ETHER_PHY_OUI); /* PHY OUI */
185+ if(EN8801S_PBUS_OUI == pbus_data)
186+ {
187+ pbus_data = airoha_pbus_read(mbus, pbusAddress, EN8801S_RG_SMI_ADDR); /* SMI ADDR */
188+ pbus_data = (pbus_data & 0xffff0000) | (unsigned long)(EN8801S_PBUS_PHY_ID << 8) | (unsigned long)(EN8801S_MDIO_PHY_ID );
189+ printk("[Airoha] EN8801S SMI_ADDR=%lx (renew)\n", pbus_data);
190+ airoha_pbus_write(mbus, pbusAddress, EN8801S_RG_SMI_ADDR, pbus_data);
191+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_BUCK_CTL, 0x03);
192+ mdelay(10);
193+ break;
194+ }
195+ else
196+ {
197+ pbusAddress = EN8801S_PBUS_PHY_ID;
198+ }
199+ retry --;
200+ if (0 == retry)
201+ {
202+ printk("[Airoha] EN8801S probe fail !\n");
203+ return 0;
204+ }
205+ }
206+
207+ reg_value = (airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL) & 0xfffffffc) | 0x10 | (EN8801S_RX_POLARITY << 1) | EN8801S_TX_POLARITY;
208+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, reg_value);
209+ mdelay(10);
210+ reg_value &= 0xffffffef;
211+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, reg_value);
212+
213+ retry = MAX_RETRY;
214+ while (1)
215+ {
216+ mdelay(10);
217+ reg_value = phy_read(phydev, MII_PHYSID2);
218+ if (reg_value == EN8801S_PHY_ID2)
219+ {
220+ break; /* wait GPHY ready */
221+ }
222+ retry--;
223+ if (0 == retry)
224+ {
225+ printk("[Airoha] EN8801S initialize fail !\n");
226+ return 0;
227+ }
228+ }
229+ /* Software Reset PHY */
230+ reg_value = phy_read(phydev, MII_BMCR);
231+ reg_value |= BMCR_RESET;
232+ phy_write(phydev, MII_BMCR, reg_value);
233+ retry = MAX_RETRY;
234+ do
235+ {
236+ mdelay(10);
237+ reg_value = phy_read(phydev, MII_BMCR);
238+ retry--;
239+ if (0 == retry)
240+ {
241+ printk("[Airoha] EN8801S reset fail !\n");
242+ return 0;
243+ }
244+ } while (reg_value & BMCR_RESET);
245+
246+ printk("[Airoha] EN8801S Phase1 initialize OK ! (%s)\n", EN8801S_DRIVER_VERSION);
247+ return 0;
248+}
249+
250+static int en8801s_phase2_init(struct phy_device *phydev)
251+{
252+ gephy_all_REG_LpiReg1Ch GPHY_RG_LPI_1C;
253+ gephy_all_REG_dev1Eh_reg324h GPHY_RG_1E_324;
254+ gephy_all_REG_dev1Eh_reg012h GPHY_RG_1E_012;
255+ gephy_all_REG_dev1Eh_reg017h GPHY_RG_1E_017;
256+ unsigned long pbus_data;
257+ u32 reg_value;
258+ int retry;
259+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
260+
261+ reg_value = (airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL) & 0xfffffffc) | 0x10 | (EN8801S_RX_POLARITY << 1) | EN8801S_TX_POLARITY;
262+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, reg_value);
263+ mdelay(10);
264+ reg_value &= 0xffffffef;
265+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, reg_value);
266+
267+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1690);
268+ pbus_data |= (1 << 31);
269+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1690, pbus_data);
270+
271+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
272+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD801);
273+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
274+
275+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0003);
276+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
277+ /* Set FCM control */
278+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x004b);
279+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
280+
281+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x142c, 0x05050505);
282+ /* Set GPHY Perfomance*/
283+ /* Token Ring */
284+ airoha_tr_reg_write(mbus, RgAddr_PMA_01h, 0x6FB90A);
285+ airoha_tr_reg_write(mbus, RgAddr_PMA_18h, 0x0E2F00);
286+ airoha_tr_reg_write(mbus, RgAddr_DSPF_06h, 0x2EBAEF);
287+ airoha_tr_reg_write(mbus, RgAddr_DSPF_11h, 0x040001);
288+ airoha_tr_reg_write(mbus, RgAddr_DSPF_03h, 0x000004);
289+ airoha_tr_reg_write(mbus, RgAddr_DSPF_1Ch, 0x003210);
290+ airoha_tr_reg_write(mbus, RgAddr_DSPF_14h, 0x00024A);
291+ airoha_tr_reg_write(mbus, RgAddr_DSPF_0Ch, 0x00704D);
292+ airoha_tr_reg_write(mbus, RgAddr_DSPF_0Dh, 0x02314F);
293+ airoha_tr_reg_write(mbus, RgAddr_DSPF_10h, 0x005010);
294+ airoha_tr_reg_write(mbus, RgAddr_DSPF_0Fh, 0x003028);
295+ airoha_tr_reg_write(mbus, RgAddr_TR_26h, 0x444444);
296+ airoha_tr_reg_write(mbus, RgAddr_R1000DEC_15h,0x0055A0);
297+ /* CL22 & CL45 */
298+ phy_write(phydev, 0x1f, 0x03);
299+ GPHY_RG_LPI_1C.DATA = phy_read(phydev, RgAddr_LpiReg1Ch);
300+ GPHY_RG_LPI_1C.DataBitField.smi_deton_th = 0x0C;
301+ phy_write(phydev, RgAddr_LpiReg1Ch, GPHY_RG_LPI_1C.DATA);
302+ phy_write(phydev, 0x1f, 0x0);
303+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x122, 0xffff);
304+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x234, 0x0180);
305+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x238, 0x0120);
306+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x120, 0x9014);
307+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x239, 0x0117);
308+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x14A, 0xEE20);
309+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x19B, 0x0111);
310+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1F, 0x268, 0x07F4);
311+
312+ airoha_cl45_read(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, &reg_value);
313+ GPHY_RG_1E_324.DATA=(u16)reg_value;
314+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = 0;
315+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, (u32)GPHY_RG_1E_324.DATA);
316+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x19E, 0xC2);
317+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x013, 0x0);
318+
319+ /* EFUSE */
320+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1C08, 0x40000040);
321+ retry = MAX_RETRY;
322+ while (0 != retry)
323+ {
324+ mdelay(1);
325+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C08);
326+ if ((reg_value & (1 << 30)) == 0)
327+ {
328+ break;
329+ }
330+ retry--;
331+ }
332+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C38); /* RAW#2 */
333+ GPHY_RG_1E_012.DataBitField.da_tx_i2mpb_a_tbt = reg_value & 0x03f;
334+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x12, (u32)GPHY_RG_1E_012.DATA);
335+ GPHY_RG_1E_017.DataBitField.da_tx_i2mpb_b_tbt=(reg_value >> 8) & 0x03f;
336+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x12, (u32)GPHY_RG_1E_017.DATA);
337+
338+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1C08, 0x40400040);
339+ retry = MAX_RETRY;
340+ while (0 != retry)
341+ {
342+ mdelay(1);
343+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C08);
344+ if ((reg_value & (1 << 30)) == 0)
345+ {
346+ break;
347+ }
348+ retry--;
349+ }
350+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C30); /* RAW#16 */
351+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = (reg_value >> 12) & 0x01;
352+ airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, (u32)GPHY_RG_1E_324.DATA);
353+
354+ en8801s_led_init(mbus);
355+
356+ printk("[Airoha] EN8801S Phase2 initialize OK !\n");
357+ return 0;
358+}
359+
360+static int en8801s_read_status(struct phy_device *phydev)
361+{
362+ int ret;
363+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
364+ u32 reg_value;
365+ static int phystate = PHY_STATE_INIT;
366+
367+ ret = genphy_read_status(phydev);
368+ if (LINK_DOWN == phydev->link) preSpeed =0;
369+
370+ if (phystate == PHY_STATE_PROCESS) {
371+ en8801s_phy_process(phydev);
372+ phystate = PHY_STATE_DONE;
373+ }
374+
375+ if ((preSpeed != phydev->speed) && (LINK_UP == phydev->link))
376+ {
377+ preSpeed = phydev->speed;
378+
379+ if (phystate == PHY_STATE_INIT) {
380+ en8801s_phase2_init(phydev);
381+ phystate = PHY_STATE_PROCESS;
382+ }
383+
384+ if (preSpeed == SPEED_10) {
385+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1694);
386+ reg_value |= (1 << 31);
387+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1694, reg_value);
388+ phystate = PHY_STATE_PROCESS;
389+ } else {
390+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1694);
391+ reg_value &= ~(1 << 31);
392+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1694, reg_value);
393+ phystate = PHY_STATE_PROCESS;
394+ }
395+
396+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
397+ if (SPEED_1000 == preSpeed)
398+ {
399+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD801);
400+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
401+
402+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0003);
403+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
404+ mdelay(2); /* delay 2 ms */
405+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x004b);
406+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
407+ }
408+ else if (SPEED_100 == preSpeed)
409+ {
410+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD401);
411+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
412+
413+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0007);
414+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c11);
415+ mdelay(2); /* delay 2 ms */
416+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x0027);
417+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
418+ }
419+ else if (SPEED_10 == preSpeed)
420+ {
421+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD001);
422+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
423+
424+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x000b);
425+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c11);
426+ mdelay(2); /* delay 2 ms */
427+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x0027);
428+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
429+ }
430+ }
431+ return ret;
432+}
433+
434+static struct phy_driver Airoha_driver[] = {
435+{
436+ .phy_id = EN8801S_PHY_ID,
437+ .name = "Airoha EN8801S",
438+ .phy_id_mask = 0x0ffffff0,
439+ .features = PHY_GBIT_FEATURES,
440+ .config_init = en8801s_phase1_init,
441+ .config_aneg = genphy_config_aneg,
442+ .read_status = en8801s_read_status,
443+ .suspend = genphy_suspend,
444+ .resume = genphy_resume,
445+} };
446+
447+module_phy_driver(Airoha_driver);
448+
449+static struct mdio_device_id __maybe_unused Airoha_tbl[] = {
450+ { EN8801S_PHY_ID, 0x0ffffff0 },
451+ { }
452+};
453+
454+MODULE_DEVICE_TABLE(mdio, Airoha_tbl);
455Index: drivers/net/phy/en8801sc.h
456===================================================================
457--- /dev/null
458+++ b/drivers/net/phy/en8801sc.h
459@@ -0,0 +1,158 @@
460+// SPDX-License-Identifier: GPL-2.0
461+/* FILE NAME: en8801sc.h
462+ * PURPOSE:
463+ * Define EN8801S driver function
464+ *
465+ * NOTES:
466+ *
467+ */
468+
469+#ifndef __AIROHA_H
470+#define __AIROHA_H
471+
472+/* NAMING DECLARATIONS
473+ */
474+#define EN8801S_DRIVER_VERSION "1.0.0"
475+
476+#define PHY_ADDRESS_RANGE 0x18
477+#define EN8801S_PBUS_DEFAULT_ID 0x1e
478+#define EN8801S_MDIO_PHY_ID 0x18 /* Range PHY_ADDRESS_RANGE .. 0x1e */
479+#define EN8801S_PBUS_PHY_ID (EN8801S_MDIO_PHY_ID + 1)
480+
481+#define EN8801S_RG_ETHER_PHY_OUI 0x19a4
482+#define EN8801S_RG_SMI_ADDR 0x19a8
483+#define EN8801S_RG_BUCK_CTL 0x1a20
484+#define EN8801S_RG_LTR_CTL 0x0cf8
485+
486+#define EN8801S_PBUS_OUI 0x17a5
487+#define EN8801S_PHY_ID1 0x03a2
488+#define EN8801S_PHY_ID2 0x9471
489+#define EN8801S_PHY_ID (unsigned long)((EN8801S_PHY_ID1 << 16) | EN8801S_PHY_ID2)
490+
491+#define DEV1E_REG013_VALUE 0
492+#define DEV1E_REG19E_VALUE 0xC2
493+#define DEV1E_REG324_VALUE 0x200
494+
495+#define TRUE 1
496+#define FALSE 0
497+#define LINK_UP 1
498+#define LINK_DOWN 0
499+
500+//#define TEST_BOARD
501+#if defined(TEST_BOARD)
502+/* SFP sample for verification */
503+#define EN8801S_TX_POLARITY 1
504+#define EN8801S_RX_POLARITY 0
505+#else
506+/* chip on board */
507+#define EN8801S_TX_POLARITY 0
508+#define EN8801S_RX_POLARITY 1 /* The pin default assignment is set to 1 */
509+#endif
510+
511+#define MAX_RETRY 5
512+#define MAX_OUI_CHECK 2
513+/* CL45 MDIO control */
514+#define MII_MMD_ACC_CTL_REG 0x0d
515+#define MII_MMD_ADDR_DATA_REG 0x0e
516+#define MMD_OP_MODE_DATA BIT(14)
517+
518+#define MAX_TRG_COUNTER 5
519+
520+/* CL22 Reg Support Page Select */
521+#define RgAddr_Reg1Fh 0x1f
522+#define CL22_Page_Reg 0x0000
523+#define CL22_Page_ExtReg 0x0001
524+#define CL22_Page_MiscReg 0x0002
525+#define CL22_Page_LpiReg 0x0003
526+#define CL22_Page_tReg 0x02A3
527+#define CL22_Page_TrReg 0x52B5
528+
529+/* CL45 Reg Support DEVID */
530+#define DEVID_03 0x03
531+#define DEVID_07 0x07
532+#define DEVID_1E 0x1E
533+#define DEVID_1F 0x1F
534+
535+/* TokenRing Reg Access */
536+#define TrReg_PKT_XMT_STA 0x8000
537+#define TrReg_WR 0x8000
538+#define TrReg_RD 0xA000
539+
540+#define RgAddr_LpiReg1Ch 0x1c
541+#define RgAddr_PMA_01h 0x0f82
542+#define RgAddr_PMA_18h 0x0fb0
543+#define RgAddr_DSPF_03h 0x1686
544+#define RgAddr_DSPF_06h 0x168c
545+#define RgAddr_DSPF_0Ch 0x1698
546+#define RgAddr_DSPF_0Dh 0x169a
547+#define RgAddr_DSPF_0Fh 0x169e
548+#define RgAddr_DSPF_10h 0x16a0
549+#define RgAddr_DSPF_11h 0x16a2
550+#define RgAddr_DSPF_14h 0x16a8
551+#define RgAddr_DSPF_1Ch 0x16b8
552+#define RgAddr_TR_26h 0x0ecc
553+#define RgAddr_R1000DEC_15h 0x03aa
554+
555+/* DATA TYPE DECLARATIONS
556+ */
557+typedef struct
558+{
559+ u16 DATA_Lo;
560+ u16 DATA_Hi;
561+}TR_DATA_T;
562+
563+typedef union
564+{
565+ struct
566+ {
567+ /* b[15:00] */
568+ u16 smi_deton_wt : 3;
569+ u16 smi_det_mdi_inv : 1;
570+ u16 smi_detoff_wt : 3;
571+ u16 smi_sigdet_debouncing_en : 1;
572+ u16 smi_deton_th : 6;
573+ u16 rsv_14 : 2;
574+ } DataBitField;
575+ u16 DATA;
576+} gephy_all_REG_LpiReg1Ch, *Pgephy_all_REG_LpiReg1Ch;
577+
578+typedef union
579+{
580+ struct
581+ {
582+ /* b[15:00] */
583+ u16 rg_smi_detcnt_max : 6;
584+ u16 rsv_6 : 2;
585+ u16 rg_smi_det_max_en : 1;
586+ u16 smi_det_deglitch_off : 1;
587+ u16 rsv_10 : 6;
588+ } DataBitField;
589+ u16 DATA;
590+} gephy_all_REG_dev1Eh_reg324h, *Pgephy_all_REG_dev1Eh_reg324h;
591+
592+typedef union
593+{
594+ struct
595+ {
596+ /* b[15:00] */
597+ u16 da_tx_i2mpb_a_tbt : 6;
598+ u16 rsv_6 : 4;
599+ u16 da_tx_i2mpb_a_gbe : 6;
600+ } DataBitField;
601+ u16 DATA;
602+} gephy_all_REG_dev1Eh_reg012h, *Pgephy_all_REG_dev1Eh_reg012h;
603+
604+typedef union
605+{
606+ struct
607+ {
608+ /* b[15:00] */
609+ u16 da_tx_i2mpb_b_tbt : 6;
610+ u16 rsv_6 : 2;
611+ u16 da_tx_i2mpb_b_gbe : 6;
612+ u16 rsv_14 : 2;
613+ } DataBitField;
614+ u16 DATA;
615+} gephy_all_REG_dev1Eh_reg017h, *Pgephy_all_REG_dev1Eh_reg017h;
616+
617+#endif /* End of __AIROHA_H */
618Index: drivers/net/phy/Kconfig
619===================================================================
620--- a/drivers/net/phy/Kconfig
621+++ b/drivers/net/phy/Kconfig
622@@ -350,6 +350,11 @@ config AIROHA_EN8801S_PHY
623 ---help---
624 Currently supports the Airoha EN8801S PHY.
625
626+config AIROHA_EN8801SC_PHY
627+ tristate "Drivers for Airoha EN8801S Gigabit PHYs for MT7981 SoC."
628+ ---help---
629+ Currently supports the Airoha EN8801S PHY for MT7981 SoC.
630+
631 config ADIN_PHY
632 tristate "Analog Devices Industrial Ethernet PHYs"
633 help
634Index: drivers/net/phy/Makefile
635===================================================================
636--- a/drivers/net/phy/Makefile
637+++ b/drivers/net/phy/Makefile
638@@ -68,6 +68,7 @@ ifdef CONFIG_HWMON
639 aquantia-objs += aquantia_hwmon.o
640 endif
641 obj-$(CONFIG_AIROHA_EN8801S_PHY) += en8801s.o
642+obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
643 obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
644 obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
645 obj-$(CONFIG_AT803X_PHY) += at803x.o