blob: 096b2c10cc21177eec2483f9d72f00743cdf12c5 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * drivers/net/phy/realtek.c
4 *
5 * Driver for Realtek PHYs
6 *
7 * Author: Johnson Leung <r58129@freescale.com>
8 *
9 * Copyright (c) 2004 Freescale Semiconductor, Inc.
10 */
11#include <linux/bitops.h>
12#include <linux/phy.h>
13#include <linux/module.h>
14#include <linux/delay.h>
hj.shaof72d6ff2025-06-10 04:34:26 -070015#include <linux/miscdevice.h>
16#include <linux/uaccess.h>
17#include <linux/gpio/consumer.h>
18#include <linux/of_gpio.h>
19//#LYNQ_MODFIY modify for task-1618 2025/6/10 start
20
21#define DEVICE_NAME "mdio_misc"
22
23struct rtl9000bf_mdio_dev {
24 struct phy_device *phydev;
25 struct mutex lock;
26 int rst_gpio;
hj.shaofb3ba9b2025-06-19 02:53:56 -070027 //#LYNQ_MODFIY modify for task-1618 2025/6/19 start
28 int power_gpio;
29 //#LYNQ_MODFIY modify for task-1618 2025/6/19 end
hj.shaof72d6ff2025-06-10 04:34:26 -070030};
31struct mdio_reg_op {
32 uint32_t reg;
33 uint32_t val;
34};
35static struct rtl9000bf_mdio_dev *s_rtl9000bf_mdio_dev;
36static u16 param_check[27] = {0, 0x8017, 0xFB03, 0, 0x8092, 0x6000, 0, 0x80AF, 0x6000, \
37 0, 0x807D, 0x4443, 0, 0x809A, 0x4443, \
38 0, 0x81A3, 0x0F00, 0x0A81, 0x12, 0x0004, 0, \
39 0x83C8, 0x0005, 0x0A5C, 0x12, 0x0003};
40
41static u16 param_check2[5] = {0x401C, 0xA610, 0x8520, 0xA510, 0x21F4};
42static u16 param_check3[3] = {0, 0xA000, 0x11EF};
43
44#define RTL9000BF_INIT_TIMES_OUT 10
45#define RTL9000BF_ACCESS_TIMES_OUT 10
46//#LYNQ_MODFIY modify for task-1618 2025/6/10 end
b.liue9582032025-04-17 19:18:16 +080047
48#define RTL821x_PHYSR 0x11
49#define RTL821x_PHYSR_DUPLEX BIT(13)
50#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
51
52#define RTL821x_INER 0x12
53#define RTL8211B_INER_INIT 0x6400
54#define RTL8211E_INER_LINK_STATUS BIT(10)
55#define RTL8211F_INER_LINK_STATUS BIT(4)
56
57#define RTL821x_INSR 0x13
58
59#define RTL821x_EXT_PAGE_SELECT 0x1e
60#define RTL821x_PAGE_SELECT 0x1f
61
62#define RTL8211F_INSR 0x1d
63
64#define RTL8211F_TX_DELAY BIT(8)
65#define RTL8211E_TX_DELAY BIT(1)
66#define RTL8211E_RX_DELAY BIT(2)
67#define RTL8211E_MODE_MII_GMII BIT(3)
68
69#define RTL8201F_ISR 0x1e
70#define RTL8201F_IER 0x13
71
72#define RTL8366RB_POWER_SAVE 0x15
73#define RTL8366RB_POWER_SAVE_ON BIT(12)
74
75#define RTL_SUPPORTS_5000FULL BIT(14)
76#define RTL_SUPPORTS_2500FULL BIT(13)
77#define RTL_SUPPORTS_10000FULL BIT(0)
78#define RTL_ADV_2500FULL BIT(7)
79#define RTL_LPADV_10000FULL BIT(11)
80#define RTL_LPADV_5000FULL BIT(6)
81#define RTL_LPADV_2500FULL BIT(5)
82
83#define RTLGEN_SPEED_MASK 0x0630
84
85#define RTL_GENERIC_PHYID 0x001cc800
86
87MODULE_DESCRIPTION("Realtek PHY driver");
88MODULE_AUTHOR("Johnson Leung");
89MODULE_LICENSE("GPL");
90
91static int rtl821x_read_page(struct phy_device *phydev)
92{
93 return __phy_read(phydev, RTL821x_PAGE_SELECT);
94}
95
96static int rtl821x_write_page(struct phy_device *phydev, int page)
97{
98 return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
99}
100
101static int rtl8201_ack_interrupt(struct phy_device *phydev)
102{
103 int err;
104
105 err = phy_read(phydev, RTL8201F_ISR);
106
107 return (err < 0) ? err : 0;
108}
109
110static int rtl821x_ack_interrupt(struct phy_device *phydev)
111{
112 int err;
113
114 err = phy_read(phydev, RTL821x_INSR);
115
116 return (err < 0) ? err : 0;
117}
118
119static int rtl8211f_ack_interrupt(struct phy_device *phydev)
120{
121 int err;
122
123 err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
124
125 return (err < 0) ? err : 0;
126}
127
128static int rtl8201_config_intr(struct phy_device *phydev)
129{
130 u16 val;
131
132 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
133 val = BIT(13) | BIT(12) | BIT(11);
134 else
135 val = 0;
136
137 return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
138}
139
140static int rtl8211b_config_intr(struct phy_device *phydev)
141{
142 int err;
143
144 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
145 err = phy_write(phydev, RTL821x_INER,
146 RTL8211B_INER_INIT);
147 else
148 err = phy_write(phydev, RTL821x_INER, 0);
149
150 return err;
151}
152
153static int rtl8211e_config_intr(struct phy_device *phydev)
154{
155 int err;
156
157 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
158 err = phy_write(phydev, RTL821x_INER,
159 RTL8211E_INER_LINK_STATUS);
160 else
161 err = phy_write(phydev, RTL821x_INER, 0);
162
163 return err;
164}
165
166static int rtl8211f_config_intr(struct phy_device *phydev)
167{
168 u16 val;
169
170 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
171 val = RTL8211F_INER_LINK_STATUS;
172 else
173 val = 0;
174
175 return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
176}
177
178static int rtl8211_config_aneg(struct phy_device *phydev)
179{
180 int ret;
181
182 ret = genphy_config_aneg(phydev);
183 if (ret < 0)
184 return ret;
185
186 /* Quirk was copied from vendor driver. Unfortunately it includes no
187 * description of the magic numbers.
188 */
189 if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
190 phy_write(phydev, 0x17, 0x2138);
191 phy_write(phydev, 0x0e, 0x0260);
192 } else {
193 phy_write(phydev, 0x17, 0x2108);
194 phy_write(phydev, 0x0e, 0x0000);
195 }
196
197 return 0;
198}
199
200static int rtl8211c_config_init(struct phy_device *phydev)
201{
202 /* RTL8211C has an issue when operating in Gigabit slave mode */
203 return phy_set_bits(phydev, MII_CTRL1000,
204 CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
205}
206
207static int rtl8211f_config_init(struct phy_device *phydev)
208{
209 struct device *dev = &phydev->mdio.dev;
210 u16 val;
211 int ret;
212
213 /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
214 * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
215 */
216 switch (phydev->interface) {
217 case PHY_INTERFACE_MODE_RGMII:
218 case PHY_INTERFACE_MODE_RGMII_RXID:
219 val = 0;
220 break;
221 case PHY_INTERFACE_MODE_RGMII_ID:
222 case PHY_INTERFACE_MODE_RGMII_TXID:
223 val = RTL8211F_TX_DELAY;
224 break;
225 default: /* the rest of the modes imply leaving delay as is. */
226 return 0;
227 }
228
229 ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
230 val);
231 if (ret < 0) {
232 dev_err(dev, "Failed to update the TX delay register\n");
233 return ret;
234 } else if (ret) {
235 dev_dbg(dev,
236 "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
237 val ? "Enabling" : "Disabling");
238 } else {
239 dev_dbg(dev,
240 "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
241 val ? "enabled" : "disabled");
242 }
243
244 return 0;
245}
246
247static int rtl8211e_config_init(struct phy_device *phydev)
248{
249 int ret = 0, oldpage;
250 u16 val;
251
252 /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
253 switch (phydev->interface) {
254 case PHY_INTERFACE_MODE_RGMII:
255 val = 0;
256 break;
257 case PHY_INTERFACE_MODE_RGMII_ID:
258 val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
259 break;
260 case PHY_INTERFACE_MODE_RGMII_RXID:
261 val = RTL8211E_RX_DELAY;
262 break;
263 case PHY_INTERFACE_MODE_RGMII_TXID:
264 val = RTL8211E_TX_DELAY;
265 break;
266 default: /* the rest of the modes imply leaving delays as is. */
267 return 0;
268 }
269
270 /* According to a sample driver there is a 0x1c config register on the
271 * 0xa4 extension page (0x7) layout. It can be used to disable/enable
272 * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
273 * also be used to customize the whole configuration register:
274 * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
275 * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
276 * for details).
277 */
278 oldpage = phy_select_page(phydev, 0x7);
279 if (oldpage < 0)
280 goto err_restore_page;
281
282 ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
283 if (ret)
284 goto err_restore_page;
285
286 ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
287 val);
288
289err_restore_page:
290 return phy_restore_page(phydev, oldpage, ret);
291}
292
293static int rtl8211b_suspend(struct phy_device *phydev)
294{
295 phy_write(phydev, MII_MMD_DATA, BIT(9));
296
297 return genphy_suspend(phydev);
298}
299
300static int rtl8211b_resume(struct phy_device *phydev)
301{
302 phy_write(phydev, MII_MMD_DATA, 0);
303
304 return genphy_resume(phydev);
305}
306
307static int rtl8366rb_config_init(struct phy_device *phydev)
308{
309 int ret;
310
311 ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
312 RTL8366RB_POWER_SAVE_ON);
313 if (ret) {
314 dev_err(&phydev->mdio.dev,
315 "error enabling power management\n");
316 }
317
318 return ret;
319}
320
321/* get actual speed to cover the downshift case */
322static int rtlgen_get_speed(struct phy_device *phydev)
323{
324 int val;
325
326 if (!phydev->link)
327 return 0;
328
329 val = phy_read_paged(phydev, 0xa43, 0x12);
330 if (val < 0)
331 return val;
332
333 switch (val & RTLGEN_SPEED_MASK) {
334 case 0x0000:
335 phydev->speed = SPEED_10;
336 break;
337 case 0x0010:
338 phydev->speed = SPEED_100;
339 break;
340 case 0x0020:
341 phydev->speed = SPEED_1000;
342 break;
343 case 0x0200:
344 phydev->speed = SPEED_10000;
345 break;
346 case 0x0210:
347 phydev->speed = SPEED_2500;
348 break;
349 case 0x0220:
350 phydev->speed = SPEED_5000;
351 break;
352 default:
353 break;
354 }
355
356 return 0;
357}
358
359static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
360{
361 int ret;
362
363 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
364 rtl821x_write_page(phydev, 0xa5c);
365 ret = __phy_read(phydev, 0x12);
366 rtl821x_write_page(phydev, 0);
367 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
368 rtl821x_write_page(phydev, 0xa5d);
369 ret = __phy_read(phydev, 0x10);
370 rtl821x_write_page(phydev, 0);
371 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
372 rtl821x_write_page(phydev, 0xa5d);
373 ret = __phy_read(phydev, 0x11);
374 rtl821x_write_page(phydev, 0);
375 } else {
376 ret = -EOPNOTSUPP;
377 }
378
379 return ret;
380}
381
382static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
383 u16 val)
384{
385 int ret;
386
387 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
388 rtl821x_write_page(phydev, 0xa5d);
389 ret = __phy_write(phydev, 0x10, val);
390 rtl821x_write_page(phydev, 0);
391 } else {
392 ret = -EOPNOTSUPP;
393 }
394
395 return ret;
396}
397
398static int rtl8125_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
399{
400 int ret = rtlgen_read_mmd(phydev, devnum, regnum);
401
402 if (ret != -EOPNOTSUPP)
403 return ret;
404
405 if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
406 rtl821x_write_page(phydev, 0xa6e);
407 ret = __phy_read(phydev, 0x16);
408 rtl821x_write_page(phydev, 0);
409 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
410 rtl821x_write_page(phydev, 0xa6d);
411 ret = __phy_read(phydev, 0x12);
412 rtl821x_write_page(phydev, 0);
413 } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
414 rtl821x_write_page(phydev, 0xa6d);
415 ret = __phy_read(phydev, 0x10);
416 rtl821x_write_page(phydev, 0);
417 }
418
419 return ret;
420}
421
422static int rtl8125_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
423 u16 val)
424{
425 int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
426
427 if (ret != -EOPNOTSUPP)
428 return ret;
429
430 if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
431 rtl821x_write_page(phydev, 0xa6d);
432 ret = __phy_write(phydev, 0x12, val);
433 rtl821x_write_page(phydev, 0);
434 }
435
436 return ret;
437}
438
439static int rtl8125_get_features(struct phy_device *phydev)
440{
441 int val;
442
443 val = phy_read_paged(phydev, 0xa61, 0x13);
444 if (val < 0)
445 return val;
446
447 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
448 phydev->supported, val & RTL_SUPPORTS_2500FULL);
449 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
450 phydev->supported, val & RTL_SUPPORTS_5000FULL);
451 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
452 phydev->supported, val & RTL_SUPPORTS_10000FULL);
453
454 return genphy_read_abilities(phydev);
455}
456
457static int rtl8125_config_aneg(struct phy_device *phydev)
458{
459 int ret = 0;
460
461 if (phydev->autoneg == AUTONEG_ENABLE) {
462 u16 adv2500 = 0;
463
464 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
465 phydev->advertising))
466 adv2500 = RTL_ADV_2500FULL;
467
468 ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
469 RTL_ADV_2500FULL, adv2500);
470 if (ret < 0)
471 return ret;
472 }
473
474 return __genphy_config_aneg(phydev, ret);
475}
476
477static int rtl8125_read_status(struct phy_device *phydev)
478{
479 if (phydev->autoneg == AUTONEG_ENABLE) {
480 int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
481
482 if (lpadv < 0)
483 return lpadv;
484
485 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
486 phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
487 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
488 phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
489 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
490 phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
491 }
492
493 return genphy_read_status(phydev);
494}
495
496static int rtl822x_config_init(struct phy_device *phydev)
497{
498 struct device *dev = &phydev->mdio.dev;
499 int ret;
500 int reg;
501
502 switch (phydev->interface) {
503 case PHY_INTERFACE_MODE_SGMII:
504 case PHY_INTERFACE_MODE_2500BASEX:
505 break;
506 default:
507 return 0;
508 }
509
510 /* set serdes mode */
511 reg = phy_read_mmd(phydev, 30, 0x697a);
512 dev_info(dev, "MMD30:0x697a = 0x%x\n", reg);
513
514 /* change to 2500Base-X + SGMII mode*/
515 phy_modify_mmd_changed(phydev, 30, 0x75F3, 0x1, 0);
516 ret = phy_modify_mmd_changed(phydev, 30, 0x697a, 0x1f, 0x0);
517 if (ret < 0) {
518 dev_err(dev, "Failed to update serdes option mode\n");
519 return ret;
520 } else if (ret) {
521 dev_info(dev, "serdes option mode set\n");
522
523 /* make changes take effect */
524 phy_modify_mmd_changed(phydev, 31, 0xA400, 0x1 << 14, 0x1 << 14);
525 do {
526 reg = phy_read_mmd(phydev, 31, 0xA434);
527 if (reg & (0x1 << 2))
528 break;
529 } while(1);
530 phy_modify_mmd_changed(phydev, 31, 0xA400, 0x1 << 14, 0);
531
532 } else {
533 dev_info(dev, "serdes option mode already set\n");
534 }
535
536 /* disabled hisgmii auto-negotiation */
537 phy_write_mmd(phydev, 30, 0x7588, 0x2);
538 phy_write_mmd(phydev, 30, 0x7589, 0x71d0);
539 phy_write_mmd(phydev, 30, 0x7587, 0x3);
540
541 dev_info(dev, "start to wait disable hisgmii AN finish\n");
542 do {
543 reg = phy_read_mmd(phydev, 30, 0x7587);
544 if ((reg & 0x1) == 0)
545 break;
546 } while(1);
547
548 return 0;
549}
550
551static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
552{
553 int ret;
554
555 if (devnum == MDIO_MMD_VEND2) {
556 int page, regad;
557
558 page = regnum >> 4;
559 regad = 16 + (regnum % 16) / 2;
560
561 rtl821x_write_page(phydev, page);
562 ret = __phy_read(phydev, regad);
563 rtl821x_write_page(phydev, 0);
564 } else {
565 /* Write the desired MMD Devad */
566 __phy_write(phydev, MII_MMD_CTRL, devnum);
567 /* Write the desired MMD register address */
568 __phy_write(phydev, MII_MMD_DATA, regnum);
569 /* Select the Function : DATA with no post increment */
570 __phy_write(phydev, MII_MMD_CTRL, devnum | MII_MMD_CTRL_NOINCR);
571 /* Read the content of the MMD's selected register */
572 ret = __phy_read(phydev, MII_MMD_DATA);
573 }
574
575 return ret;
576}
577
578static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
579 u16 val)
580{
581 int ret;
582
583 if (devnum == MDIO_MMD_VEND2) {
584 int page, regad;
585
586 page = regnum >> 4;
587 regad = 16 + (regnum % 16) / 2;
588
589 rtl821x_write_page(phydev, page);
590 ret = __phy_write(phydev, regad, val);
591 rtl821x_write_page(phydev, 0);
592 } else {
593 /* Write the desired MMD Devad */
594 __phy_write(phydev, MII_MMD_CTRL, devnum);
595 /* Write the desired MMD register address */
596 __phy_write(phydev, MII_MMD_DATA, regnum);
597 /* Select the Function : DATA with no post increment */
598 __phy_write(phydev, MII_MMD_CTRL, devnum | MII_MMD_CTRL_NOINCR);
599 /* Write the data into MMD's selected register */
600 ret = __phy_write(phydev, MII_MMD_DATA, val);
601 }
602
603 return ret;
604}
605
606static int rtl822x_get_features(struct phy_device *phydev)
607{
608 int val;
609
610 val = phy_read_paged(phydev, 0xa61, 0x13);
611 if (val < 0)
612 return val;
613
614 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
615 phydev->supported, val & RTL_SUPPORTS_2500FULL);
616 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
617 phydev->supported, val & RTL_SUPPORTS_5000FULL);
618 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
619 phydev->supported, val & RTL_SUPPORTS_10000FULL);
620
621 return genphy_read_abilities(phydev);
622}
623
624static int rtl822x_config_aneg(struct phy_device *phydev)
625{
626 int ret = 0;
627
628 if (phydev->autoneg == AUTONEG_ENABLE) {
629 u16 adv2500 = 0;
630
631 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
632 phydev->advertising))
633 adv2500 = RTL_ADV_2500FULL;
634
635 ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
636 RTL_ADV_2500FULL, adv2500);
637 if (ret < 0)
638 return ret;
639 }
640
641 return __genphy_config_aneg(phydev, ret);
642}
643
644static int rtlgen_get_serdes_mode(struct phy_device *phydev)
645{
646 struct device *dev = &phydev->mdio.dev;
647 int ret;
648
649 ret = phy_read_mmd(phydev, 30, 0x7580);
650 if (ret < 0)
651 return ret;
652
653 switch (ret & 0x1f) {
654 case 0x2:
655 phydev->interface = PHY_INTERFACE_MODE_SGMII;
656 dev_dbg(dev, "==> Serdes mode: SGMII\n");
657 break;
658 case 0x12:
659 phydev->interface = PHY_INTERFACE_MODE_NA;
660 dev_dbg(dev, "==> Serdes mode: HiSGMII\n");
661 break;
662 case 0x16:
663 phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
664 dev_dbg(dev, "==> Serdes mode: 2500BASE-X\n");
665 break;
666 case 0x1f:
667 dev_dbg(dev, "==> Serdes mode: off\n");
668 break;
669 default:
670 break;
671 }
672
673 return 0;
674}
675
676static int rtl822x_read_status(struct phy_device *phydev)
677{
678 int ret;
679
680 if (phydev->autoneg == AUTONEG_ENABLE) {
681 int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
682
683 if (lpadv < 0)
684 return lpadv;
685
686 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
687 phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
688 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
689 phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
690 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
691 phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
692 }
693
694 ret = genphy_read_status(phydev);
695 if (ret < 0)
696 return ret;
697
698 ret = rtlgen_get_serdes_mode(phydev);
699 if (ret < 0)
700 return ret;
701
702 return rtlgen_get_speed(phydev);
703}
704
705static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
706{
707 int val;
708
709 phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
710 val = phy_read(phydev, 0x13);
711 phy_write(phydev, RTL821x_PAGE_SELECT, 0);
712
713 return val >= 0 && val & RTL_SUPPORTS_2500FULL;
714}
715
716static int rtlgen_match_phy_device(struct phy_device *phydev)
717{
718 return phydev->phy_id == RTL_GENERIC_PHYID &&
719 !rtlgen_supports_2_5gbps(phydev);
720}
721
722static int rtl8125_match_phy_device(struct phy_device *phydev)
723{
724 return phydev->phy_id == RTL_GENERIC_PHYID &&
725 rtlgen_supports_2_5gbps(phydev);
726}
727
728static int rtlgen_resume(struct phy_device *phydev)
729{
730 int ret = genphy_resume(phydev);
731
732 /* Internal PHY's from RTL8168h up may not be instantly ready */
733 msleep(20);
734
735 return ret;
736}
hj.shaof72d6ff2025-06-10 04:34:26 -0700737//#LYNQ_MODFIY modify for task-1618 2025/6/10 start
738
739static int mdio_misc_open(struct inode *inode, struct file *file)
740{
741 return 0;
742}
743
744static ssize_t mdio_misc_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
745{
746 struct rtl9000bf_mdio_dev *dev = s_rtl9000bf_mdio_dev;
747 struct mdio_reg_op reg_op;
748
749 if (count < sizeof(struct mdio_reg_op))
750 return -EINVAL;
751
752 if (copy_from_user(&reg_op, buf, sizeof(struct mdio_reg_op)))
753 return -EFAULT;
754
755
756 mutex_lock(&dev->lock);
757 reg_op.val = __phy_read(dev->phydev, reg_op.reg);
758 mutex_unlock(&dev->lock);
759
760 if (copy_to_user(buf, &reg_op, sizeof(struct mdio_reg_op)))
761 return -EFAULT;
762
763 return sizeof(reg_op);
764}
765
766static ssize_t mdio_misc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
767{
768 struct rtl9000bf_mdio_dev *dev = s_rtl9000bf_mdio_dev;
769 struct mdio_reg_op reg_op;
770 int ret;
771
772 if (count < sizeof(struct mdio_reg_op))
773 return -EINVAL;
774
775 if (copy_from_user(&reg_op, buf, sizeof(struct mdio_reg_op)))
776 return -EFAULT;
777
778
779 mutex_lock(&dev->lock);
780 ret = __phy_write(dev->phydev, reg_op.reg, reg_op.val);
781 mutex_unlock(&dev->lock);
782
783 *f_pos += count;
784 return ret ? ret : count;
785
786}
787
788static const struct file_operations mdio_misc_fops = {
789 .owner = THIS_MODULE,
790 .open = mdio_misc_open,
791 .read = mdio_misc_read,
792 .write = mdio_misc_write,
793};
794
795static struct miscdevice mdio_misc_device = {
796 .minor = MISC_DYNAMIC_MINOR,
797 .name = DEVICE_NAME,
798 .fops = &mdio_misc_fops,
799};
800
801static int mdio_misc_init(struct phy_device *phydev)
802{
803 s_rtl9000bf_mdio_dev->phydev = phydev;
804 mutex_init(&s_rtl9000bf_mdio_dev->lock);
805 return misc_register(&mdio_misc_device);
806}
807
808static s16 RTL9000Bx_Initial_Configuration(struct phy_device *phydev)
809{
810 u16 reg_data = 0;
811 u32 timer = 2000; // set a 2ms timer
812
813 //power down
814 __phy_write(phydev, 0, 0x800);
815 mdelay(10);
816
817 __phy_write(phydev, 27, 0x8017);
818 __phy_write(phydev, 28, 0xFB03);
819 __phy_write(phydev, 27, 0x8092);
820 __phy_write(phydev, 28, 0x6000);
821 __phy_write(phydev, 27, 0x80AF);
822 __phy_write(phydev, 28, 0x6000);
823 __phy_write(phydev, 27, 0x807D);
824 __phy_write(phydev, 28, 0x4443);
825 __phy_write(phydev, 27, 0x809A);
826 __phy_write(phydev, 28, 0x4443);
827 __phy_write(phydev, 27, 0x81A3);
828 __phy_write(phydev, 28, 0x0F00);
829 __phy_write(phydev, 31, 0x0a81);
830 __phy_write(phydev, 18, 0x0004);
831 __phy_write(phydev, 27, 0x83c8);
832 __phy_write(phydev, 28, 0x0005);
833 __phy_write(phydev, 31, 0x0a5c);
834 __phy_write(phydev, 18, 0x0003);
835 __phy_write(phydev, 27, 0xB820);
836 __phy_write(phydev, 28, 0x0010);
837 __phy_write(phydev, 27, 0xB830);
838 __phy_write(phydev, 28, 0x8000);
839
840 __phy_write(phydev, 27, 0xB800);
841 do {
842 reg_data = ((u16)__phy_read(phydev, 28) & 0x0040);
843 timer--;
844 if (timer == 0)
845 {
846 return -1;
847 }
848 } while (reg_data != 0x0040);
849
850 __phy_write(phydev, 27, 0x8020);
851 __phy_write(phydev, 28, 0x3300);
852 __phy_write(phydev, 27, 0xb82e);
853 __phy_write(phydev, 28, 0x0001);
854 __phy_write(phydev, 27, 0xb820);
855 __phy_write(phydev, 28, 0x0290);
856 __phy_write(phydev, 27, 0xa012);
857 __phy_write(phydev, 28, 0x0000);
858 __phy_write(phydev, 27, 0xa014);
859 __phy_write(phydev, 28, 0x401c);
860 __phy_write(phydev, 28, 0xa610);
861 __phy_write(phydev, 28, 0x8520);
862 __phy_write(phydev, 28, 0xa510);
863 __phy_write(phydev, 28, 0x21f4);
864 __phy_write(phydev, 27, 0xa01a);
865 __phy_write(phydev, 28, 0x0000);
866 __phy_write(phydev, 27, 0xa000);
867 __phy_write(phydev, 28, 0x11ef);
868 __phy_write(phydev, 27, 0xb820);
869 __phy_write(phydev, 28, 0x0210);
870 __phy_write(phydev, 27, 0xb82e);
871 __phy_write(phydev, 28, 0x0000);
872 __phy_write(phydev, 27, 0x8020);
873 __phy_write(phydev, 28, 0x0000);
874 __phy_write(phydev, 27, 0xb820);
875 __phy_write(phydev, 28, 0x0000);
876
877 __phy_write(phydev, 27, 0xb800);
878 timer = 2000; // set a 2ms timer
879 do {
880 reg_data = ((u16)__phy_read(phydev, 28) & 0x0040);
881 timer--;
882 if (timer == 0) {
883 return -1;
884 }
885 } while (reg_data != 0x0000);
886
887 __phy_write(phydev, 0, 0x2100); //power on
hj.shaofb3ba9b2025-06-19 02:53:56 -0700888 __phy_write(phydev, 9, 0x0); //set slave mode
hj.shaof72d6ff2025-06-10 04:34:26 -0700889 return 0;
890}
891
892static s16 RTL9000Bx_Initial_Configuration_Check(struct phy_device *phydev)
893{
894 u16 reg_data = 0, reg_data_temp;
895 u16 reg_data_chk = 0;
896 u32 timer = 2000; // set a 2ms timer
897
898 u16 page;
899 u16 reg, i, param_address;
900
901 for (i = 0; i < 27; i = i + 3) {
902 page = param_check[i];
903 reg = param_check[i + 1];
904 reg_data_chk = param_check[i + 2];
905
906 if (page == 0) {
907 __phy_write(phydev, 27, reg);
908 reg_data = __phy_read(phydev, 28);
909 }
910 else {
911 __phy_write(phydev, 31, page);
912 reg_data = __phy_read(phydev, reg);
913 }
914 if (reg_data_chk != reg_data) {
915 printk(KERN_ERR "%dth param error page=0x%04X reg=0x%04X data=0x%04X\r\n", i / 3, page, reg, reg_data);
916 return -1;
917 }
918 }
919
920 __phy_write(phydev, 27, 0xB820);
921 __phy_write(phydev, 28, 0x0010);
922 __phy_write(phydev, 27, 0xB830);
923 __phy_write(phydev, 28, 0x8000);
924
925 __phy_write(phydev, 27, 0xB800);
926 do {
927 reg_data = ((u16)__phy_read(phydev, 28) & 0x0040);
928 timer--;
929 if (timer == 0){
930 return -1;
931 }
932 } while (reg_data != 0x0040);
933
934 __phy_write(phydev, 27, 0x8020);
935 __phy_write(phydev, 28, 0x3300);
936 __phy_write(phydev, 27, 0xB82E);
937 __phy_write(phydev, 28, 0x0001);
938
939 param_address = 0;
940 for (i = 0; i < 5; i++) {
941 __phy_write(phydev, 31, 0xA01);
942 reg_data_temp = __phy_read(phydev, 17);
943 reg_data_temp &= ~(0x1ff);
944 param_address &= 0x1FF;
945 __phy_write(phydev, 17, (reg_data_temp | param_address));
946 __phy_write(phydev, 31, 0xA01);
947 reg_data = __phy_read(phydev, 18);
948 reg_data_chk = param_check2[i];
949 if (reg_data_chk != reg_data){
950 printk(KERN_ERR "%dth param error data=0x%04X expected_data=0x%04X\r\n", i, reg_data, reg_data_chk);
951 return -1;
952 }
953 param_address++;
954 }
955 for (i = 0; i < 3; i = i + 3) {
956 page = param_check3[i];
957 reg = param_check3[i + 1];
958 reg_data_chk = param_check3[i + 2];
959
960 if (page == 0) {
961 __phy_write(phydev, 27, reg);
962 reg_data = __phy_read(phydev, 28);
963 }
964 else {
965 __phy_write(phydev, 31, page);
966 reg_data = __phy_read(phydev, reg);
967 }
968 if (reg_data_chk != reg_data) {
969 printk(KERN_ERR "%dth param error page=0x%04X reg=0x%04X data=0x%04X\r\n", i / 3, page, reg, reg_data);
970 return -1;
971 }
972 }
973 __phy_write(phydev, 27, 0xB82E);
974 __phy_write(phydev, 28, 0x0000);
975 __phy_write(phydev, 27, 0x8020);
976 __phy_write(phydev, 28, 0x0000);
977 __phy_write(phydev, 27, 0xB820);
978 __phy_write(phydev, 28, 0x0000);
979
980 __phy_write(phydev, 27, 0xB800);
981 timer = 2000; // set a 2ms timer
982 do {
983 reg_data = ((u16)__phy_read(phydev, 28) & 0x0040);
984 timer--;
985 if (timer == 0){
986 return -1;
987 }
988 } while (reg_data != 0x0000);
989
990 return 0;
991}
b.liue9582032025-04-17 19:18:16 +0800992
hj.shaofb3ba9b2025-06-19 02:53:56 -0700993//#LYNQ_MODFIY modify for task-1618 2025/6/19 satrt
994static int rtl9000Bf_power_set(int gpio, int power_en)
995{
996 int ret;
997 ret = gpio_direction_output(gpio, power_en);
998 mdelay(30);
999 return ret;
1000}
1001
1002static void rtl9000Bf_reset(int gpio)
1003{
1004 gpio_direction_output(gpio, 0);
1005 mdelay(30);
1006 gpio_set_value(gpio, 1);
1007 mdelay(20);
1008}
1009
hj.shaofe1632a2025-06-05 00:19:33 -07001010static int rtl9000Bf_config_init(struct phy_device *phydev)
1011{
hj.shaofe1632a2025-06-05 00:19:33 -07001012 u32 mdio_data = 0;
hj.shaof72d6ff2025-06-10 04:34:26 -07001013 u32 ret;
1014 int times= 1;
1015 struct device_node *np;
1016
1017 np = phydev->mdio.dev.of_node;
1018 if (!np) {
1019 dev_err(&phydev->mdio.dev, "No device tree node found\n");
1020 return -ENODEV;
1021 }
1022
1023 if (!s_rtl9000bf_mdio_dev) {
1024 s_rtl9000bf_mdio_dev = kzalloc(sizeof(*s_rtl9000bf_mdio_dev), GFP_KERNEL);
1025 if (!s_rtl9000bf_mdio_dev)
1026 return -ENOMEM;
hj.shaofe1632a2025-06-05 00:19:33 -07001027
hj.shaof72d6ff2025-06-10 04:34:26 -07001028 s_rtl9000bf_mdio_dev->rst_gpio = of_get_named_gpio(np, "rst-gpio", 0);
1029 if (s_rtl9000bf_mdio_dev->rst_gpio < 0) {
1030 dev_err(&phydev->mdio.dev, "Failed to get reset gpio: %d\n", s_rtl9000bf_mdio_dev->rst_gpio);
1031 kfree(s_rtl9000bf_mdio_dev);
1032 s_rtl9000bf_mdio_dev = NULL;
1033 return s_rtl9000bf_mdio_dev->rst_gpio;
hj.shaofe1632a2025-06-05 00:19:33 -07001034 }
hj.shaofb3ba9b2025-06-19 02:53:56 -07001035 gpio_request(s_rtl9000bf_mdio_dev->rst_gpio, "phy-reset");
1036
1037 s_rtl9000bf_mdio_dev->power_gpio = of_get_named_gpio(np, "power-en-gpio", 0);
1038 if (s_rtl9000bf_mdio_dev->power_gpio < 0) {
1039 dev_err(&phydev->mdio.dev, "Failed to get power gpio: %d\n", s_rtl9000bf_mdio_dev->power_gpio);
1040 kfree(s_rtl9000bf_mdio_dev);
1041 s_rtl9000bf_mdio_dev = NULL;
1042 return s_rtl9000bf_mdio_dev->power_gpio;
1043 }
hj.shaof72d6ff2025-06-10 04:34:26 -07001044 ret = mdio_misc_init(phydev);
1045 if(ret){
1046 goto err;
hj.shaofe1632a2025-06-05 00:19:33 -07001047 }
hj.shaofb3ba9b2025-06-19 02:53:56 -07001048 gpio_request(s_rtl9000bf_mdio_dev->power_gpio, "phy-power");
hj.shaof72d6ff2025-06-10 04:34:26 -07001049 }
1050
hj.shaofb3ba9b2025-06-19 02:53:56 -07001051 rtl9000Bf_power_set(s_rtl9000bf_mdio_dev->power_gpio, 1);
1052 rtl9000Bf_reset(s_rtl9000bf_mdio_dev->rst_gpio);
hj.shaofe1632a2025-06-05 00:19:33 -07001053
hj.shaof72d6ff2025-06-10 04:34:26 -07001054 //check PHY accessible
1055 while(times <= RTL9000BF_ACCESS_TIMES_OUT) {
1056 mdio_data = phy_read(phydev, 0x10);
1057 mdio_data = mdio_data & 0x0007;
1058 if(mdio_data == 0x0003) {
1059 printk(KERN_INFO "phy_info: phy is accessible \n");
1060 break;
1061 } else {
1062 printk(KERN_INFO "phy_info: phy is not accessible times:%d \n", times);
hj.shaofb3ba9b2025-06-19 02:53:56 -07001063 rtl9000Bf_reset(s_rtl9000bf_mdio_dev->rst_gpio);
hj.shaof72d6ff2025-06-10 04:34:26 -07001064 }
1065 times++;
1066 mdelay(1000);
1067 }
1068
1069 if(times >= RTL9000BF_ACCESS_TIMES_OUT) {
1070 printk(KERN_ERR "phy_info: phy init error times:%d \n", times);
1071 ret = -1;
1072 goto err;
1073 }
1074
1075 times = 1;
1076
1077 //init phy init and check phy init
1078 while(times <= RTL9000BF_INIT_TIMES_OUT) {
1079 ret = RTL9000Bx_Initial_Configuration(phydev);
1080 if(0 == ret) {
1081 printk(KERN_INFO "phy_info: phy init success times:%d \n", times);
1082 ret = RTL9000Bx_Initial_Configuration_Check(phydev);
1083 if(0 == ret) {
1084 printk(KERN_INFO "phy_info: phy init_check success times:%d \n", times);
1085 break;
1086 } else {
1087 printk(KERN_INFO "phy_info: phy init_check error times:%d \n", times);
1088 }
1089 } else {
1090 printk(KERN_INFO "phy_info: phy init error times:%d \n", times);
1091 //phy hard reset
hj.shaofb3ba9b2025-06-19 02:53:56 -07001092 rtl9000Bf_reset(s_rtl9000bf_mdio_dev->rst_gpio);
1093
hj.shaof72d6ff2025-06-10 04:34:26 -07001094 }
1095 times++;
1096 }
1097
1098 if(times >= RTL9000BF_INIT_TIMES_OUT) {
1099 printk(KERN_ERR "phy_info: phy init error times:%d \n", times);
1100 ret = -1;
1101 goto err;
1102 }
1103
hj.shaofe1632a2025-06-05 00:19:33 -07001104 /* I/O Power Sllection */
hj.shaof72d6ff2025-06-10 04:34:26 -07001105 //change page to default value
1106 __phy_write(phydev, 0x1F, 0x0A4C);
hj.shaofe1632a2025-06-05 00:19:33 -07001107 mdio_data = __phy_read(phydev, 0x12);
1108 mdio_data &= 0xC7FF;
1109 mdio_data |= 4 << 11;
1110 __phy_write(phydev, 0x12, mdio_data);
hj.shaof72d6ff2025-06-10 04:34:26 -07001111 printk(KERN_INFO "phy_info: set rgmii driving strengths is 1.8v \n");
hj.shaofe1632a2025-06-05 00:19:33 -07001112
1113 phydev->autoneg = AUTONEG_DISABLE;
1114 phydev->duplex = DUPLEX_FULL;
1115
hj.shaofe1632a2025-06-05 00:19:33 -07001116 return 0;
hj.shaof72d6ff2025-06-10 04:34:26 -07001117
1118err:
1119 gpio_free(s_rtl9000bf_mdio_dev->rst_gpio);
hj.shaofb3ba9b2025-06-19 02:53:56 -07001120 gpio_free(s_rtl9000bf_mdio_dev->power_gpio);
1121 kfree(s_rtl9000bf_mdio_dev);
hj.shaof72d6ff2025-06-10 04:34:26 -07001122 s_rtl9000bf_mdio_dev = NULL;
1123 return ret;
1124}
hj.shaofb3ba9b2025-06-19 02:53:56 -07001125//#LYNQ_MODFIY modify for task-1618 2025/6/19 end
hj.shaof72d6ff2025-06-10 04:34:26 -07001126
1127static void rtl9000Bf_remove(struct phy_device *phydev)
1128{
1129 if (s_rtl9000bf_mdio_dev && s_rtl9000bf_mdio_dev->phydev == phydev) {
1130 misc_deregister(&mdio_misc_device);
1131 gpio_free(s_rtl9000bf_mdio_dev->rst_gpio);
hj.shaofb3ba9b2025-06-19 02:53:56 -07001132 //#LYNQ_MODFIY modify for task-1618 2025/6/19 start
1133 gpio_free(s_rtl9000bf_mdio_dev->power_gpio);
1134 //#LYNQ_MODFIY modify for task-1618 2025/6/19 end
hj.shaof72d6ff2025-06-10 04:34:26 -07001135 kfree(s_rtl9000bf_mdio_dev);
1136 s_rtl9000bf_mdio_dev = NULL;
1137 }
1138
hj.shaofe1632a2025-06-05 00:19:33 -07001139}
1140
1141static int rtl9000Bf_read_status(struct phy_device *phydev)
1142{
hj.shaofe1632a2025-06-05 00:19:33 -07001143 phydev->duplex = DUPLEX_FULL;
1144 phydev->speed = SPEED_100;
1145 phydev->pause = 0;
1146 phydev->asym_pause = 0;
1147 phydev->link = 1;
1148
1149 return 0;
1150}
hj.shaof72d6ff2025-06-10 04:34:26 -07001151static int rtl9000Bf_soft_reset(struct phy_device *phydev)
1152{
1153 return 0;
1154}
1155
1156//#LYNQ_MODFIY modify for task-1618 2025/6/10 end
hj.shaofe1632a2025-06-05 00:19:33 -07001157
hj.shaofb3ba9b2025-06-19 02:53:56 -07001158//#LYNQ_MODFIY modify for task-1618 2025/6/19 start
1159static int rtl9000Bf_suspend(struct phy_device *phydev)
1160{
1161 return gpio_direction_output(s_rtl9000bf_mdio_dev->power_gpio, 0);
1162}
1163static int rtl9000Bf_resume(struct phy_device *phydev)
1164{
1165 rtl9000Bf_power_set(s_rtl9000bf_mdio_dev->power_gpio, 1);
1166 return rtl9000Bf_config_init(phydev);
1167}
1168//#LYNQ_MODFIY modify for task-1618 2025/6/19 end
1169
1170
b.liue9582032025-04-17 19:18:16 +08001171static struct phy_driver realtek_drvs[] = {
1172 {
1173 PHY_ID_MATCH_EXACT(0x00008201),
1174 .name = "RTL8201CP Ethernet",
1175 }, {
1176 PHY_ID_MATCH_EXACT(0x001cc816),
1177 .name = "RTL8201F Fast Ethernet",
1178 .ack_interrupt = &rtl8201_ack_interrupt,
1179 .config_intr = &rtl8201_config_intr,
1180 .suspend = genphy_suspend,
1181 .resume = genphy_resume,
1182 .read_page = rtl821x_read_page,
1183 .write_page = rtl821x_write_page,
1184 }, {
1185 PHY_ID_MATCH_MODEL(0x001cc880),
1186 .name = "RTL8208 Fast Ethernet",
1187 .read_mmd = genphy_read_mmd_unsupported,
1188 .write_mmd = genphy_write_mmd_unsupported,
1189 .suspend = genphy_suspend,
1190 .resume = genphy_resume,
1191 .read_page = rtl821x_read_page,
1192 .write_page = rtl821x_write_page,
1193 }, {
1194 PHY_ID_MATCH_EXACT(0x001cc910),
1195 .name = "RTL8211 Gigabit Ethernet",
1196 .config_aneg = rtl8211_config_aneg,
1197 .read_mmd = &genphy_read_mmd_unsupported,
1198 .write_mmd = &genphy_write_mmd_unsupported,
1199 .read_page = rtl821x_read_page,
1200 .write_page = rtl821x_write_page,
1201 }, {
1202 PHY_ID_MATCH_EXACT(0x001cc912),
1203 .name = "RTL8211B Gigabit Ethernet",
1204 .ack_interrupt = &rtl821x_ack_interrupt,
1205 .config_intr = &rtl8211b_config_intr,
1206 .read_mmd = &genphy_read_mmd_unsupported,
1207 .write_mmd = &genphy_write_mmd_unsupported,
1208 .suspend = rtl8211b_suspend,
1209 .resume = rtl8211b_resume,
1210 .read_page = rtl821x_read_page,
1211 .write_page = rtl821x_write_page,
1212 }, {
1213 PHY_ID_MATCH_EXACT(0x001cc913),
1214 .name = "RTL8211C Gigabit Ethernet",
1215 .config_init = rtl8211c_config_init,
1216 .read_mmd = &genphy_read_mmd_unsupported,
1217 .write_mmd = &genphy_write_mmd_unsupported,
1218 .read_page = rtl821x_read_page,
1219 .write_page = rtl821x_write_page,
1220 }, {
1221 PHY_ID_MATCH_EXACT(0x001cc914),
1222 .name = "RTL8211DN Gigabit Ethernet",
1223 .ack_interrupt = rtl821x_ack_interrupt,
1224 .config_intr = rtl8211e_config_intr,
1225 .suspend = genphy_suspend,
1226 .resume = genphy_resume,
1227 .read_page = rtl821x_read_page,
1228 .write_page = rtl821x_write_page,
1229 }, {
1230 PHY_ID_MATCH_EXACT(0x001cc915),
1231 .name = "RTL8211E Gigabit Ethernet",
1232 .config_init = &rtl8211e_config_init,
1233 .ack_interrupt = &rtl821x_ack_interrupt,
1234 .config_intr = &rtl8211e_config_intr,
1235 .suspend = genphy_suspend,
1236 .resume = genphy_resume,
1237 .read_page = rtl821x_read_page,
1238 .write_page = rtl821x_write_page,
1239 }, {
1240 PHY_ID_MATCH_EXACT(0x001cc916),
1241 .name = "RTL8211F Gigabit Ethernet",
1242 .config_init = &rtl8211f_config_init,
1243 .ack_interrupt = &rtl8211f_ack_interrupt,
1244 .config_intr = &rtl8211f_config_intr,
1245 .suspend = genphy_suspend,
1246 .resume = genphy_resume,
1247 .read_page = rtl821x_read_page,
1248 .write_page = rtl821x_write_page,
1249 }, {
1250 .name = "Generic FE-GE Realtek PHY",
1251 .match_phy_device = rtlgen_match_phy_device,
1252 .suspend = genphy_suspend,
1253 .resume = genphy_resume,
1254 .read_page = rtl821x_read_page,
1255 .write_page = rtl821x_write_page,
1256 .read_mmd = rtlgen_read_mmd,
1257 .write_mmd = rtlgen_write_mmd,
1258 }, {
1259 .name = "RTL8125 2.5Gbps internal",
1260 .match_phy_device = rtl8125_match_phy_device,
1261 .get_features = rtl8125_get_features,
1262 .config_aneg = rtl8125_config_aneg,
1263 .read_status = rtl8125_read_status,
1264 .suspend = genphy_suspend,
1265 .resume = genphy_resume,
1266 .read_page = rtl821x_read_page,
1267 .write_page = rtl821x_write_page,
1268 .read_mmd = rtl8125_read_mmd,
1269 .write_mmd = rtl8125_write_mmd,
1270 }, {
1271 PHY_ID_MATCH_EXACT(0x001cc961),
1272 .name = "RTL8366RB Gigabit Ethernet",
1273 .config_init = &rtl8366rb_config_init,
1274 /* These interrupts are handled by the irq controller
1275 * embedded inside the RTL8366RB, they get unmasked when the
1276 * irq is requested and ACKed by reading the status register,
1277 * which is done by the irqchip code.
1278 */
1279 .ack_interrupt = genphy_no_ack_interrupt,
1280 .config_intr = genphy_no_config_intr,
1281 .suspend = genphy_suspend,
1282 .resume = genphy_resume,
1283 }, {
1284 PHY_ID_MATCH_EXACT(0x001cc849),
1285 .name = "RTL8221B-VB-CG 2.5Gbps PHY",
1286 .config_init = &rtl822x_config_init,
1287 .get_features = rtl822x_get_features,
1288 .config_aneg = rtl822x_config_aneg,
1289 .read_status = rtl822x_read_status,
1290 .suspend = genphy_suspend,
1291 .resume = rtlgen_resume,
1292 .read_page = rtl821x_read_page,
1293 .write_page = rtl821x_write_page,
1294 .read_mmd = rtl822x_read_mmd,
1295 .write_mmd = rtl822x_write_mmd,
1296 }, {
1297 PHY_ID_MATCH_EXACT(0x001cc84a),
1298 .name = "RTL8221B-VM-CG 2.5Gbps PHY",
1299 .config_init = &rtl822x_config_init,
1300 .get_features = rtl822x_get_features,
1301 .config_aneg = rtl822x_config_aneg,
1302 .read_status = rtl822x_read_status,
1303 .suspend = genphy_suspend,
1304 .resume = rtlgen_resume,
1305 .read_page = rtl821x_read_page,
1306 .write_page = rtl821x_write_page,
1307 .read_mmd = rtl822x_read_mmd,
1308 .write_mmd = rtl822x_write_mmd,
hj.shaof72d6ff2025-06-10 04:34:26 -07001309 },
1310//#LYNQ_MODFIY modify for task-1618 2025/6/10 start
1311 {
hj.shaofe1632a2025-06-05 00:19:33 -07001312 PHY_ID_MATCH_EXACT(0x001ccb00),
1313 .name = "RTL90000Bf PHY",
1314 .config_init = &rtl9000Bf_config_init,
hj.shaof72d6ff2025-06-10 04:34:26 -07001315 .remove = &rtl9000Bf_remove,
hj.shaofe1632a2025-06-05 00:19:33 -07001316 .read_status = rtl9000Bf_read_status,
hj.shaofb3ba9b2025-06-19 02:53:56 -07001317 //#LYNQ_MODFIY modify for task-1618 2025/6/19 start
1318 .suspend = rtl9000Bf_suspend,
1319 .resume = rtl9000Bf_resume,
1320 //#LYNQ_MODFIY modify for task-1618 2025/6/19 end
hj.shaof72d6ff2025-06-10 04:34:26 -07001321 .soft_reset = rtl9000Bf_soft_reset,
hj.shaofe1632a2025-06-05 00:19:33 -07001322 },
hj.shaof72d6ff2025-06-10 04:34:26 -07001323//#LYNQ_MODFIY modify for task-1618 2025/6/10 end
hj.shaofe1632a2025-06-05 00:19:33 -07001324
b.liue9582032025-04-17 19:18:16 +08001325};
1326
hj.shaofe1632a2025-06-05 00:19:33 -07001327
1328
b.liue9582032025-04-17 19:18:16 +08001329module_phy_driver(realtek_drvs);
1330
1331static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
1332 { PHY_ID_MATCH_VENDOR(0x001cc800) },
hj.shaof72d6ff2025-06-10 04:34:26 -07001333//#LYNQ_MODFIY modify for task-1618 2025/6/10 start
1334
hj.shaofe1632a2025-06-05 00:19:33 -07001335 { 0x001ccb00, 0x001fffff },
hj.shaof72d6ff2025-06-10 04:34:26 -07001336
1337//#LYNQ_MODFIY modify for task-1618 2025/6/10 end
b.liue9582032025-04-17 19:18:16 +08001338 { }
1339};
1340
1341MODULE_DEVICE_TABLE(mdio, realtek_tbl);
hj.shaof72d6ff2025-06-10 04:34:26 -07001342