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/interrupt.h>
  21#include <linux/init.h>
  22#include <linux/delay.h>
  23#include <linux/netdevice.h>
  24#include <linux/etherdevice.h>
  25#include <linux/skbuff.h>
  26#include <linux/spinlock.h>
  27#include <linux/mm.h>
  28#include <linux/module.h>
  29#include <linux/mii.h>
  30#include <linux/ethtool.h>
  31#include <linux/phy.h>
  32#include <linux/io.h>
  33#include <linux/uaccess.h>
  34#include <asm/irq.h>
  35
  36#define ET1011C_STATUS_REG      (0x1A)
  37#define ET1011C_CONFIG_REG      (0x16)
  38#define ET1011C_SPEED_MASK              (0x0300)
  39#define ET1011C_GIGABIT_SPEED           (0x0200)
  40#define ET1011C_TX_FIFO_MASK            (0x3000)
  41#define ET1011C_TX_FIFO_DEPTH_8         (0x0000)
  42#define ET1011C_TX_FIFO_DEPTH_16        (0x1000)
  43#define ET1011C_INTERFACE_MASK          (0x0007)
  44#define ET1011C_GMII_INTERFACE          (0x0002)
  45#define ET1011C_SYS_CLK_EN              (0x01 << 4)
  46
  47
  48MODULE_DESCRIPTION("LSI ET1011C PHY driver");
  49MODULE_AUTHOR("Chaithrika U S");
  50MODULE_LICENSE("GPL");
  51
  52static int et1011c_config_aneg(struct phy_device *phydev)
  53{
  54        int ctl = 0;
  55        ctl = phy_read(phydev, MII_BMCR);
  56        if (ctl < 0)
  57                return ctl;
  58        ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
  59                 BMCR_ANENABLE);
  60        /* First clear the PHY */
  61        phy_write(phydev, MII_BMCR, ctl | BMCR_RESET);
  62
  63        return genphy_config_aneg(phydev);
  64}
  65
  66static int et1011c_read_status(struct phy_device *phydev)
  67{
  68        int ret;
  69        u32 val;
  70        static int speed;
  71        ret = genphy_read_status(phydev);
  72
  73        if (speed != phydev->speed) {
  74                speed = phydev->speed;
  75                val = phy_read(phydev, ET1011C_STATUS_REG);
  76                if ((val & ET1011C_SPEED_MASK) ==
  77                                        ET1011C_GIGABIT_SPEED) {
  78                        val = phy_read(phydev, ET1011C_CONFIG_REG);
  79                        val &= ~ET1011C_TX_FIFO_MASK;
  80                        phy_write(phydev, ET1011C_CONFIG_REG, val\
  81                                        | ET1011C_GMII_INTERFACE\
  82                                        | ET1011C_SYS_CLK_EN\
  83                                        | ET1011C_TX_FIFO_DEPTH_16);
  84
  85                }
  86        }
  87        return ret;
  88}
  89
  90static struct phy_driver et1011c_driver[] = { {
  91        .phy_id         = 0x0282f014,
  92        .name           = "ET1011C",
  93        .phy_id_mask    = 0xfffffff0,
  94        .features       = (PHY_BASIC_FEATURES | SUPPORTED_1000baseT_Full),
  95        .flags          = PHY_POLL,
  96        .config_aneg    = et1011c_config_aneg,
  97        .read_status    = et1011c_read_status,
  98        .driver         = { .owner = THIS_MODULE,},
  99} };
 100
 101module_phy_driver(et1011c_driver);
 102
 103static struct mdio_device_id __maybe_unused et1011c_tbl[] = {
 104        { 0x0282f014, 0xfffffff0 },
 105        { }
 106};
 107
 108MODULE_DEVICE_TABLE(mdio, et1011c_tbl);
 109