linux/drivers/net/phy/et1011c.c
<<
>>
Prefs
   1/*
   2 * drivers/net/phy/et1011c.c
   3 *
   4 * Driver for LSI ET1011C PHYs
   5 *
   6 * Author: Chaithrika U S
   7 *
   8 * Copyright (c) 2008 Texas Instruments
   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/kernel.h>
  17#include <linux/string.h>
  18#include <linux/errno.h>
  19#include <linux/unistd.h>
  20#include <linux/slab.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/io.h>
  34#include <linux/uaccess.h>
  35#include <asm/irq.h>
  36
  37#define ET1011C_STATUS_REG      (0x1A)
  38#define ET1011C_CONFIG_REG      (0x16)
  39#define ET1011C_SPEED_MASK              (0x0300)
  40#define ET1011C_GIGABIT_SPEED           (0x0200)
  41#define ET1011C_TX_FIFO_MASK            (0x3000)
  42#define ET1011C_TX_FIFO_DEPTH_8         (0x0000)
  43#define ET1011C_TX_FIFO_DEPTH_16        (0x1000)
  44#define ET1011C_INTERFACE_MASK          (0x0007)
  45#define ET1011C_GMII_INTERFACE          (0x0002)
  46#define ET1011C_SYS_CLK_EN              (0x01 << 4)
  47
  48
  49MODULE_DESCRIPTION("LSI ET1011C PHY driver");
  50MODULE_AUTHOR("Chaithrika U S");
  51MODULE_LICENSE("GPL");
  52
  53static int et1011c_config_aneg(struct phy_device *phydev)
  54{
  55        int ctl = 0;
  56        ctl = phy_read(phydev, MII_BMCR);
  57        if (ctl < 0)
  58                return ctl;
  59        ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
  60                 BMCR_ANENABLE);
  61        /* First clear the PHY */
  62        phy_write(phydev, MII_BMCR, ctl | BMCR_RESET);
  63
  64        return genphy_config_aneg(phydev);
  65}
  66
  67static int et1011c_read_status(struct phy_device *phydev)
  68{
  69        int ret;
  70        u32 val;
  71        static int speed;
  72        ret = genphy_read_status(phydev);
  73
  74        if (speed != phydev->speed) {
  75                speed = phydev->speed;
  76                val = phy_read(phydev, ET1011C_STATUS_REG);
  77                if ((val & ET1011C_SPEED_MASK) ==
  78                                        ET1011C_GIGABIT_SPEED) {
  79                        val = phy_read(phydev, ET1011C_CONFIG_REG);
  80                        val &= ~ET1011C_TX_FIFO_MASK;
  81                        phy_write(phydev, ET1011C_CONFIG_REG, val\
  82                                        | ET1011C_GMII_INTERFACE\
  83                                        | ET1011C_SYS_CLK_EN\
  84                                        | ET1011C_TX_FIFO_DEPTH_16);
  85
  86                }
  87        }
  88        return ret;
  89}
  90
  91static struct phy_driver et1011c_driver = {
  92        .phy_id         = 0x0282f014,
  93        .name           = "ET1011C",
  94        .phy_id_mask    = 0xfffffff0,
  95        .features       = (PHY_BASIC_FEATURES | SUPPORTED_1000baseT_Full),
  96        .flags          = PHY_POLL,
  97        .config_aneg    = et1011c_config_aneg,
  98        .read_status    = et1011c_read_status,
  99        .driver         = { .owner = THIS_MODULE,},
 100};
 101
 102static int __init et1011c_init(void)
 103{
 104        return phy_driver_register(&et1011c_driver);
 105}
 106
 107static void __exit et1011c_exit(void)
 108{
 109        phy_driver_unregister(&et1011c_driver);
 110}
 111
 112module_init(et1011c_init);
 113module_exit(et1011c_exit);
 114