linux/drivers/net/phy/realtek.c
<<
>>
Prefs
   1// 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>
  15
  16#define RTL821x_PHYSR                           0x11
  17#define RTL821x_PHYSR_DUPLEX                    BIT(13)
  18#define RTL821x_PHYSR_SPEED                     GENMASK(15, 14)
  19
  20#define RTL821x_INER                            0x12
  21#define RTL8211B_INER_INIT                      0x6400
  22#define RTL8211E_INER_LINK_STATUS               BIT(10)
  23#define RTL8211F_INER_LINK_STATUS               BIT(4)
  24
  25#define RTL821x_INSR                            0x13
  26
  27#define RTL821x_EXT_PAGE_SELECT                 0x1e
  28#define RTL821x_PAGE_SELECT                     0x1f
  29
  30#define RTL8211F_INSR                           0x1d
  31
  32#define RTL8211F_TX_DELAY                       BIT(8)
  33#define RTL8211F_RX_DELAY                       BIT(3)
  34
  35#define RTL8211E_TX_DELAY                       BIT(1)
  36#define RTL8211E_RX_DELAY                       BIT(2)
  37#define RTL8211E_MODE_MII_GMII                  BIT(3)
  38
  39#define RTL8201F_ISR                            0x1e
  40#define RTL8201F_IER                            0x13
  41
  42#define RTL8366RB_POWER_SAVE                    0x15
  43#define RTL8366RB_POWER_SAVE_ON                 BIT(12)
  44
  45#define RTL_SUPPORTS_5000FULL                   BIT(14)
  46#define RTL_SUPPORTS_2500FULL                   BIT(13)
  47#define RTL_SUPPORTS_10000FULL                  BIT(0)
  48#define RTL_ADV_2500FULL                        BIT(7)
  49#define RTL_LPADV_10000FULL                     BIT(11)
  50#define RTL_LPADV_5000FULL                      BIT(6)
  51#define RTL_LPADV_2500FULL                      BIT(5)
  52
  53#define RTLGEN_SPEED_MASK                       0x0630
  54
  55#define RTL_GENERIC_PHYID                       0x001cc800
  56
  57MODULE_DESCRIPTION("Realtek PHY driver");
  58MODULE_AUTHOR("Johnson Leung");
  59MODULE_LICENSE("GPL");
  60
  61static int rtl821x_read_page(struct phy_device *phydev)
  62{
  63        return __phy_read(phydev, RTL821x_PAGE_SELECT);
  64}
  65
  66static int rtl821x_write_page(struct phy_device *phydev, int page)
  67{
  68        return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
  69}
  70
  71static int rtl8201_ack_interrupt(struct phy_device *phydev)
  72{
  73        int err;
  74
  75        err = phy_read(phydev, RTL8201F_ISR);
  76
  77        return (err < 0) ? err : 0;
  78}
  79
  80static int rtl821x_ack_interrupt(struct phy_device *phydev)
  81{
  82        int err;
  83
  84        err = phy_read(phydev, RTL821x_INSR);
  85
  86        return (err < 0) ? err : 0;
  87}
  88
  89static int rtl8211f_ack_interrupt(struct phy_device *phydev)
  90{
  91        int err;
  92
  93        err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
  94
  95        return (err < 0) ? err : 0;
  96}
  97
  98static int rtl8201_config_intr(struct phy_device *phydev)
  99{
 100        u16 val;
 101
 102        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 103                val = BIT(13) | BIT(12) | BIT(11);
 104        else
 105                val = 0;
 106
 107        return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
 108}
 109
 110static int rtl8211b_config_intr(struct phy_device *phydev)
 111{
 112        int err;
 113
 114        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 115                err = phy_write(phydev, RTL821x_INER,
 116                                RTL8211B_INER_INIT);
 117        else
 118                err = phy_write(phydev, RTL821x_INER, 0);
 119
 120        return err;
 121}
 122
 123static int rtl8211e_config_intr(struct phy_device *phydev)
 124{
 125        int err;
 126
 127        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 128                err = phy_write(phydev, RTL821x_INER,
 129                                RTL8211E_INER_LINK_STATUS);
 130        else
 131                err = phy_write(phydev, RTL821x_INER, 0);
 132
 133        return err;
 134}
 135
 136static int rtl8211f_config_intr(struct phy_device *phydev)
 137{
 138        u16 val;
 139
 140        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 141                val = RTL8211F_INER_LINK_STATUS;
 142        else
 143                val = 0;
 144
 145        return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
 146}
 147
 148static int rtl8211_config_aneg(struct phy_device *phydev)
 149{
 150        int ret;
 151
 152        ret = genphy_config_aneg(phydev);
 153        if (ret < 0)
 154                return ret;
 155
 156        /* Quirk was copied from vendor driver. Unfortunately it includes no
 157         * description of the magic numbers.
 158         */
 159        if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
 160                phy_write(phydev, 0x17, 0x2138);
 161                phy_write(phydev, 0x0e, 0x0260);
 162        } else {
 163                phy_write(phydev, 0x17, 0x2108);
 164                phy_write(phydev, 0x0e, 0x0000);
 165        }
 166
 167        return 0;
 168}
 169
 170static int rtl8211c_config_init(struct phy_device *phydev)
 171{
 172        /* RTL8211C has an issue when operating in Gigabit slave mode */
 173        return phy_set_bits(phydev, MII_CTRL1000,
 174                            CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
 175}
 176
 177static int rtl8211f_config_init(struct phy_device *phydev)
 178{
 179        struct device *dev = &phydev->mdio.dev;
 180        u16 val_txdly, val_rxdly;
 181        int ret;
 182
 183        switch (phydev->interface) {
 184        case PHY_INTERFACE_MODE_RGMII:
 185                val_txdly = 0;
 186                val_rxdly = 0;
 187                break;
 188
 189        case PHY_INTERFACE_MODE_RGMII_RXID:
 190                val_txdly = 0;
 191                val_rxdly = RTL8211F_RX_DELAY;
 192                break;
 193
 194        case PHY_INTERFACE_MODE_RGMII_TXID:
 195                val_txdly = RTL8211F_TX_DELAY;
 196                val_rxdly = 0;
 197                break;
 198
 199        case PHY_INTERFACE_MODE_RGMII_ID:
 200                val_txdly = RTL8211F_TX_DELAY;
 201                val_rxdly = RTL8211F_RX_DELAY;
 202                break;
 203
 204        default: /* the rest of the modes imply leaving delay as is. */
 205                return 0;
 206        }
 207
 208        ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
 209                                       val_txdly);
 210        if (ret < 0) {
 211                dev_err(dev, "Failed to update the TX delay register\n");
 212                return ret;
 213        } else if (ret) {
 214                dev_dbg(dev,
 215                        "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
 216                        val_txdly ? "Enabling" : "Disabling");
 217        } else {
 218                dev_dbg(dev,
 219                        "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
 220                        val_txdly ? "enabled" : "disabled");
 221        }
 222
 223        ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
 224                                       val_rxdly);
 225        if (ret < 0) {
 226                dev_err(dev, "Failed to update the RX delay register\n");
 227                return ret;
 228        } else if (ret) {
 229                dev_dbg(dev,
 230                        "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
 231                        val_rxdly ? "Enabling" : "Disabling");
 232        } else {
 233                dev_dbg(dev,
 234                        "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
 235                        val_rxdly ? "enabled" : "disabled");
 236        }
 237
 238        return 0;
 239}
 240
 241static int rtl8211e_config_init(struct phy_device *phydev)
 242{
 243        int ret = 0, oldpage;
 244        u16 val;
 245
 246        /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
 247        switch (phydev->interface) {
 248        case PHY_INTERFACE_MODE_RGMII:
 249                val = 0;
 250                break;
 251        case PHY_INTERFACE_MODE_RGMII_ID:
 252                val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
 253                break;
 254        case PHY_INTERFACE_MODE_RGMII_RXID:
 255                val = RTL8211E_RX_DELAY;
 256                break;
 257        case PHY_INTERFACE_MODE_RGMII_TXID:
 258                val = RTL8211E_TX_DELAY;
 259                break;
 260        default: /* the rest of the modes imply leaving delays as is. */
 261                return 0;
 262        }
 263
 264        /* According to a sample driver there is a 0x1c config register on the
 265         * 0xa4 extension page (0x7) layout. It can be used to disable/enable
 266         * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
 267         * also be used to customize the whole configuration register:
 268         * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
 269         * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
 270         * for details).
 271         */
 272        oldpage = phy_select_page(phydev, 0x7);
 273        if (oldpage < 0)
 274                goto err_restore_page;
 275
 276        ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
 277        if (ret)
 278                goto err_restore_page;
 279
 280        ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
 281                           val);
 282
 283err_restore_page:
 284        return phy_restore_page(phydev, oldpage, ret);
 285}
 286
 287static int rtl8211b_suspend(struct phy_device *phydev)
 288{
 289        phy_write(phydev, MII_MMD_DATA, BIT(9));
 290
 291        return genphy_suspend(phydev);
 292}
 293
 294static int rtl8211b_resume(struct phy_device *phydev)
 295{
 296        phy_write(phydev, MII_MMD_DATA, 0);
 297
 298        return genphy_resume(phydev);
 299}
 300
 301static int rtl8366rb_config_init(struct phy_device *phydev)
 302{
 303        int ret;
 304
 305        ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
 306                           RTL8366RB_POWER_SAVE_ON);
 307        if (ret) {
 308                dev_err(&phydev->mdio.dev,
 309                        "error enabling power management\n");
 310        }
 311
 312        return ret;
 313}
 314
 315/* get actual speed to cover the downshift case */
 316static int rtlgen_get_speed(struct phy_device *phydev)
 317{
 318        int val;
 319
 320        if (!phydev->link)
 321                return 0;
 322
 323        val = phy_read_paged(phydev, 0xa43, 0x12);
 324        if (val < 0)
 325                return val;
 326
 327        switch (val & RTLGEN_SPEED_MASK) {
 328        case 0x0000:
 329                phydev->speed = SPEED_10;
 330                break;
 331        case 0x0010:
 332                phydev->speed = SPEED_100;
 333                break;
 334        case 0x0020:
 335                phydev->speed = SPEED_1000;
 336                break;
 337        case 0x0200:
 338                phydev->speed = SPEED_10000;
 339                break;
 340        case 0x0210:
 341                phydev->speed = SPEED_2500;
 342                break;
 343        case 0x0220:
 344                phydev->speed = SPEED_5000;
 345                break;
 346        default:
 347                break;
 348        }
 349
 350        return 0;
 351}
 352
 353static int rtlgen_read_status(struct phy_device *phydev)
 354{
 355        int ret;
 356
 357        ret = genphy_read_status(phydev);
 358        if (ret < 0)
 359                return ret;
 360
 361        return rtlgen_get_speed(phydev);
 362}
 363
 364static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
 365{
 366        int ret;
 367
 368        if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
 369                rtl821x_write_page(phydev, 0xa5c);
 370                ret = __phy_read(phydev, 0x12);
 371                rtl821x_write_page(phydev, 0);
 372        } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
 373                rtl821x_write_page(phydev, 0xa5d);
 374                ret = __phy_read(phydev, 0x10);
 375                rtl821x_write_page(phydev, 0);
 376        } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
 377                rtl821x_write_page(phydev, 0xa5d);
 378                ret = __phy_read(phydev, 0x11);
 379                rtl821x_write_page(phydev, 0);
 380        } else {
 381                ret = -EOPNOTSUPP;
 382        }
 383
 384        return ret;
 385}
 386
 387static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
 388                            u16 val)
 389{
 390        int ret;
 391
 392        if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
 393                rtl821x_write_page(phydev, 0xa5d);
 394                ret = __phy_write(phydev, 0x10, val);
 395                rtl821x_write_page(phydev, 0);
 396        } else {
 397                ret = -EOPNOTSUPP;
 398        }
 399
 400        return ret;
 401}
 402
 403static int rtl8125_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
 404{
 405        int ret = rtlgen_read_mmd(phydev, devnum, regnum);
 406
 407        if (ret != -EOPNOTSUPP)
 408                return ret;
 409
 410        if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
 411                rtl821x_write_page(phydev, 0xa6e);
 412                ret = __phy_read(phydev, 0x16);
 413                rtl821x_write_page(phydev, 0);
 414        } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
 415                rtl821x_write_page(phydev, 0xa6d);
 416                ret = __phy_read(phydev, 0x12);
 417                rtl821x_write_page(phydev, 0);
 418        } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
 419                rtl821x_write_page(phydev, 0xa6d);
 420                ret = __phy_read(phydev, 0x10);
 421                rtl821x_write_page(phydev, 0);
 422        }
 423
 424        return ret;
 425}
 426
 427static int rtl8125_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
 428                             u16 val)
 429{
 430        int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
 431
 432        if (ret != -EOPNOTSUPP)
 433                return ret;
 434
 435        if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
 436                rtl821x_write_page(phydev, 0xa6d);
 437                ret = __phy_write(phydev, 0x12, val);
 438                rtl821x_write_page(phydev, 0);
 439        }
 440
 441        return ret;
 442}
 443
 444static int rtl8125_get_features(struct phy_device *phydev)
 445{
 446        int val;
 447
 448        val = phy_read_paged(phydev, 0xa61, 0x13);
 449        if (val < 0)
 450                return val;
 451
 452        linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 453                         phydev->supported, val & RTL_SUPPORTS_2500FULL);
 454        linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 455                         phydev->supported, val & RTL_SUPPORTS_5000FULL);
 456        linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
 457                         phydev->supported, val & RTL_SUPPORTS_10000FULL);
 458
 459        return genphy_read_abilities(phydev);
 460}
 461
 462static int rtl8125_config_aneg(struct phy_device *phydev)
 463{
 464        int ret = 0;
 465
 466        if (phydev->autoneg == AUTONEG_ENABLE) {
 467                u16 adv2500 = 0;
 468
 469                if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 470                                      phydev->advertising))
 471                        adv2500 = RTL_ADV_2500FULL;
 472
 473                ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
 474                                               RTL_ADV_2500FULL, adv2500);
 475                if (ret < 0)
 476                        return ret;
 477        }
 478
 479        return __genphy_config_aneg(phydev, ret);
 480}
 481
 482static int rtl8125_read_status(struct phy_device *phydev)
 483{
 484        int ret;
 485
 486        if (phydev->autoneg == AUTONEG_ENABLE) {
 487                int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
 488
 489                if (lpadv < 0)
 490                        return lpadv;
 491
 492                linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
 493                        phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
 494                linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 495                        phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
 496                linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 497                        phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
 498        }
 499
 500        ret = genphy_read_status(phydev);
 501        if (ret < 0)
 502                return ret;
 503
 504        return rtlgen_get_speed(phydev);
 505}
 506
 507static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
 508{
 509        int val;
 510
 511        phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
 512        val = phy_read(phydev, 0x13);
 513        phy_write(phydev, RTL821x_PAGE_SELECT, 0);
 514
 515        return val >= 0 && val & RTL_SUPPORTS_2500FULL;
 516}
 517
 518static int rtlgen_match_phy_device(struct phy_device *phydev)
 519{
 520        return phydev->phy_id == RTL_GENERIC_PHYID &&
 521               !rtlgen_supports_2_5gbps(phydev);
 522}
 523
 524static int rtl8125_match_phy_device(struct phy_device *phydev)
 525{
 526        return phydev->phy_id == RTL_GENERIC_PHYID &&
 527               rtlgen_supports_2_5gbps(phydev);
 528}
 529
 530static int rtlgen_resume(struct phy_device *phydev)
 531{
 532        int ret = genphy_resume(phydev);
 533
 534        /* Internal PHY's from RTL8168h up may not be instantly ready */
 535        msleep(20);
 536
 537        return ret;
 538}
 539
 540static struct phy_driver realtek_drvs[] = {
 541        {
 542                PHY_ID_MATCH_EXACT(0x00008201),
 543                .name           = "RTL8201CP Ethernet",
 544        }, {
 545                PHY_ID_MATCH_EXACT(0x001cc816),
 546                .name           = "RTL8201F Fast Ethernet",
 547                .ack_interrupt  = &rtl8201_ack_interrupt,
 548                .config_intr    = &rtl8201_config_intr,
 549                .suspend        = genphy_suspend,
 550                .resume         = genphy_resume,
 551                .read_page      = rtl821x_read_page,
 552                .write_page     = rtl821x_write_page,
 553        }, {
 554                PHY_ID_MATCH_MODEL(0x001cc880),
 555                .name           = "RTL8208 Fast Ethernet",
 556                .read_mmd       = genphy_read_mmd_unsupported,
 557                .write_mmd      = genphy_write_mmd_unsupported,
 558                .suspend        = genphy_suspend,
 559                .resume         = genphy_resume,
 560                .read_page      = rtl821x_read_page,
 561                .write_page     = rtl821x_write_page,
 562        }, {
 563                PHY_ID_MATCH_EXACT(0x001cc910),
 564                .name           = "RTL8211 Gigabit Ethernet",
 565                .config_aneg    = rtl8211_config_aneg,
 566                .read_mmd       = &genphy_read_mmd_unsupported,
 567                .write_mmd      = &genphy_write_mmd_unsupported,
 568                .read_page      = rtl821x_read_page,
 569                .write_page     = rtl821x_write_page,
 570        }, {
 571                PHY_ID_MATCH_EXACT(0x001cc912),
 572                .name           = "RTL8211B Gigabit Ethernet",
 573                .ack_interrupt  = &rtl821x_ack_interrupt,
 574                .config_intr    = &rtl8211b_config_intr,
 575                .read_mmd       = &genphy_read_mmd_unsupported,
 576                .write_mmd      = &genphy_write_mmd_unsupported,
 577                .suspend        = rtl8211b_suspend,
 578                .resume         = rtl8211b_resume,
 579                .read_page      = rtl821x_read_page,
 580                .write_page     = rtl821x_write_page,
 581        }, {
 582                PHY_ID_MATCH_EXACT(0x001cc913),
 583                .name           = "RTL8211C Gigabit Ethernet",
 584                .config_init    = rtl8211c_config_init,
 585                .read_mmd       = &genphy_read_mmd_unsupported,
 586                .write_mmd      = &genphy_write_mmd_unsupported,
 587                .read_page      = rtl821x_read_page,
 588                .write_page     = rtl821x_write_page,
 589        }, {
 590                PHY_ID_MATCH_EXACT(0x001cc914),
 591                .name           = "RTL8211DN Gigabit Ethernet",
 592                .ack_interrupt  = rtl821x_ack_interrupt,
 593                .config_intr    = rtl8211e_config_intr,
 594                .suspend        = genphy_suspend,
 595                .resume         = genphy_resume,
 596                .read_page      = rtl821x_read_page,
 597                .write_page     = rtl821x_write_page,
 598        }, {
 599                PHY_ID_MATCH_EXACT(0x001cc915),
 600                .name           = "RTL8211E Gigabit Ethernet",
 601                .config_init    = &rtl8211e_config_init,
 602                .ack_interrupt  = &rtl821x_ack_interrupt,
 603                .config_intr    = &rtl8211e_config_intr,
 604                .suspend        = genphy_suspend,
 605                .resume         = genphy_resume,
 606                .read_page      = rtl821x_read_page,
 607                .write_page     = rtl821x_write_page,
 608        }, {
 609                PHY_ID_MATCH_EXACT(0x001cc916),
 610                .name           = "RTL8211F Gigabit Ethernet",
 611                .config_init    = &rtl8211f_config_init,
 612                .ack_interrupt  = &rtl8211f_ack_interrupt,
 613                .config_intr    = &rtl8211f_config_intr,
 614                .suspend        = genphy_suspend,
 615                .resume         = genphy_resume,
 616                .read_page      = rtl821x_read_page,
 617                .write_page     = rtl821x_write_page,
 618        }, {
 619                .name           = "Generic FE-GE Realtek PHY",
 620                .match_phy_device = rtlgen_match_phy_device,
 621                .read_status    = rtlgen_read_status,
 622                .suspend        = genphy_suspend,
 623                .resume         = rtlgen_resume,
 624                .read_page      = rtl821x_read_page,
 625                .write_page     = rtl821x_write_page,
 626                .read_mmd       = rtlgen_read_mmd,
 627                .write_mmd      = rtlgen_write_mmd,
 628        }, {
 629                .name           = "RTL8125 2.5Gbps internal",
 630                .match_phy_device = rtl8125_match_phy_device,
 631                .get_features   = rtl8125_get_features,
 632                .config_aneg    = rtl8125_config_aneg,
 633                .read_status    = rtl8125_read_status,
 634                .suspend        = genphy_suspend,
 635                .resume         = rtlgen_resume,
 636                .read_page      = rtl821x_read_page,
 637                .write_page     = rtl821x_write_page,
 638                .read_mmd       = rtl8125_read_mmd,
 639                .write_mmd      = rtl8125_write_mmd,
 640        }, {
 641                PHY_ID_MATCH_EXACT(0x001cc961),
 642                .name           = "RTL8366RB Gigabit Ethernet",
 643                .config_init    = &rtl8366rb_config_init,
 644                /* These interrupts are handled by the irq controller
 645                 * embedded inside the RTL8366RB, they get unmasked when the
 646                 * irq is requested and ACKed by reading the status register,
 647                 * which is done by the irqchip code.
 648                 */
 649                .ack_interrupt  = genphy_no_ack_interrupt,
 650                .config_intr    = genphy_no_config_intr,
 651                .suspend        = genphy_suspend,
 652                .resume         = genphy_resume,
 653        },
 654};
 655
 656module_phy_driver(realtek_drvs);
 657
 658static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
 659        { PHY_ID_MATCH_VENDOR(0x001cc800) },
 660        { }
 661};
 662
 663MODULE_DEVICE_TABLE(mdio, realtek_tbl);
 664