linux/drivers/net/phy/realtek.c
<<
>>
Prefs
   1/*
   2 * drivers/net/phy/realtek.c
   3 *
   4 * Driver for Realtek PHYs
   5 *
   6 * Author: Johnson Leung <r58129@freescale.com>
   7 *
   8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 *
  15 */
  16#include <linux/phy.h>
  17#include <linux/module.h>
  18
  19#define RTL821x_PHYSR           0x11
  20#define RTL821x_PHYSR_DUPLEX    0x2000
  21#define RTL821x_PHYSR_SPEED     0xc000
  22#define RTL821x_INER            0x12
  23#define RTL821x_INER_INIT       0x6400
  24#define RTL821x_INSR            0x13
  25
  26#define RTL8211E_INER_LINK_STATUS       0x400
  27
  28MODULE_DESCRIPTION("Realtek PHY driver");
  29MODULE_AUTHOR("Johnson Leung");
  30MODULE_LICENSE("GPL");
  31
  32static int rtl821x_ack_interrupt(struct phy_device *phydev)
  33{
  34        int err;
  35
  36        err = phy_read(phydev, RTL821x_INSR);
  37
  38        return (err < 0) ? err : 0;
  39}
  40
  41static int rtl8211b_config_intr(struct phy_device *phydev)
  42{
  43        int err;
  44
  45        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  46                err = phy_write(phydev, RTL821x_INER,
  47                                RTL821x_INER_INIT);
  48        else
  49                err = phy_write(phydev, RTL821x_INER, 0);
  50
  51        return err;
  52}
  53
  54static int rtl8211e_config_intr(struct phy_device *phydev)
  55{
  56        int err;
  57
  58        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  59                err = phy_write(phydev, RTL821x_INER,
  60                                RTL8211E_INER_LINK_STATUS);
  61        else
  62                err = phy_write(phydev, RTL821x_INER, 0);
  63
  64        return err;
  65}
  66
  67/* RTL8201CP */
  68static struct phy_driver rtl8201cp_driver = {
  69        .phy_id         = 0x00008201,
  70        .name           = "RTL8201CP Ethernet",
  71        .phy_id_mask    = 0x0000ffff,
  72        .features       = PHY_BASIC_FEATURES,
  73        .flags          = PHY_HAS_INTERRUPT,
  74        .config_aneg    = &genphy_config_aneg,
  75        .read_status    = &genphy_read_status,
  76        .driver         = { .owner = THIS_MODULE,},
  77};
  78
  79/* RTL8211B */
  80static struct phy_driver rtl8211b_driver = {
  81        .phy_id         = 0x001cc912,
  82        .name           = "RTL8211B Gigabit Ethernet",
  83        .phy_id_mask    = 0x001fffff,
  84        .features       = PHY_GBIT_FEATURES,
  85        .flags          = PHY_HAS_INTERRUPT,
  86        .config_aneg    = &genphy_config_aneg,
  87        .read_status    = &genphy_read_status,
  88        .ack_interrupt  = &rtl821x_ack_interrupt,
  89        .config_intr    = &rtl8211b_config_intr,
  90        .driver         = { .owner = THIS_MODULE,},
  91};
  92
  93/* RTL8211E */
  94static struct phy_driver rtl8211e_driver = {
  95        .phy_id         = 0x001cc915,
  96        .name           = "RTL8211E Gigabit Ethernet",
  97        .phy_id_mask    = 0x001fffff,
  98        .features       = PHY_GBIT_FEATURES,
  99        .flags          = PHY_HAS_INTERRUPT,
 100        .config_aneg    = &genphy_config_aneg,
 101        .read_status    = &genphy_read_status,
 102        .ack_interrupt  = &rtl821x_ack_interrupt,
 103        .config_intr    = &rtl8211e_config_intr,
 104        .suspend        = genphy_suspend,
 105        .resume         = genphy_resume,
 106        .driver         = { .owner = THIS_MODULE,},
 107};
 108
 109static int __init realtek_init(void)
 110{
 111        int ret;
 112
 113        ret = phy_driver_register(&rtl8201cp_driver);
 114        if (ret < 0)
 115                return -ENODEV;
 116        ret = phy_driver_register(&rtl8211b_driver);
 117        if (ret < 0)
 118                return -ENODEV;
 119        return phy_driver_register(&rtl8211e_driver);
 120}
 121
 122static void __exit realtek_exit(void)
 123{
 124        phy_driver_unregister(&rtl8211b_driver);
 125        phy_driver_unregister(&rtl8211e_driver);
 126}
 127
 128module_init(realtek_init);
 129module_exit(realtek_exit);
 130
 131static struct mdio_device_id __maybe_unused realtek_tbl[] = {
 132        { 0x001cc912, 0x001fffff },
 133        { 0x001cc915, 0x001fffff },
 134        { }
 135};
 136
 137MODULE_DEVICE_TABLE(mdio, realtek_tbl);
 138