Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * drivers/net/phy/et1011c.c
0004  *
0005  * Driver for LSI ET1011C PHYs
0006  *
0007  * Author: Chaithrika U S
0008  *
0009  * Copyright (c) 2008 Texas Instruments
0010  */
0011 #include <linux/kernel.h>
0012 #include <linux/string.h>
0013 #include <linux/errno.h>
0014 #include <linux/unistd.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/init.h>
0017 #include <linux/delay.h>
0018 #include <linux/netdevice.h>
0019 #include <linux/etherdevice.h>
0020 #include <linux/skbuff.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/mm.h>
0023 #include <linux/module.h>
0024 #include <linux/mii.h>
0025 #include <linux/ethtool.h>
0026 #include <linux/phy.h>
0027 #include <linux/io.h>
0028 #include <linux/uaccess.h>
0029 #include <asm/irq.h>
0030 
0031 #define ET1011C_STATUS_REG  (0x1A)
0032 #define ET1011C_CONFIG_REG  (0x16)
0033 #define ET1011C_SPEED_MASK      (0x0300)
0034 #define ET1011C_GIGABIT_SPEED       (0x0200)
0035 #define ET1011C_TX_FIFO_MASK        (0x3000)
0036 #define ET1011C_TX_FIFO_DEPTH_8     (0x0000)
0037 #define ET1011C_TX_FIFO_DEPTH_16    (0x1000)
0038 #define ET1011C_INTERFACE_MASK      (0x0007)
0039 #define ET1011C_GMII_INTERFACE      (0x0002)
0040 #define ET1011C_SYS_CLK_EN      (0x01 << 4)
0041 
0042 
0043 MODULE_DESCRIPTION("LSI ET1011C PHY driver");
0044 MODULE_AUTHOR("Chaithrika U S");
0045 MODULE_LICENSE("GPL");
0046 
0047 static int et1011c_config_aneg(struct phy_device *phydev)
0048 {
0049     int ctl = phy_read(phydev, MII_BMCR);
0050 
0051     if (ctl < 0)
0052         return ctl;
0053     ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
0054          BMCR_ANENABLE);
0055     /* First clear the PHY */
0056     phy_write(phydev, MII_BMCR, ctl | BMCR_RESET);
0057 
0058     return genphy_config_aneg(phydev);
0059 }
0060 
0061 static int et1011c_read_status(struct phy_device *phydev)
0062 {
0063     static int speed;
0064     int ret;
0065     u32 val;
0066 
0067     ret = genphy_read_status(phydev);
0068 
0069     if (speed != phydev->speed) {
0070         speed = phydev->speed;
0071         val = phy_read(phydev, ET1011C_STATUS_REG);
0072         if ((val & ET1011C_SPEED_MASK) ==
0073                     ET1011C_GIGABIT_SPEED) {
0074             val = phy_read(phydev, ET1011C_CONFIG_REG);
0075             val &= ~ET1011C_TX_FIFO_MASK;
0076             phy_write(phydev, ET1011C_CONFIG_REG, val |
0077                       ET1011C_GMII_INTERFACE |
0078                       ET1011C_SYS_CLK_EN |
0079                       ET1011C_TX_FIFO_DEPTH_16);
0080 
0081         }
0082     }
0083     return ret;
0084 }
0085 
0086 static struct phy_driver et1011c_driver[] = { {
0087     .phy_id     = 0x0282f014,
0088     .name       = "ET1011C",
0089     .phy_id_mask    = 0xfffffff0,
0090     /* PHY_GBIT_FEATURES */
0091     .config_aneg    = et1011c_config_aneg,
0092     .read_status    = et1011c_read_status,
0093 } };
0094 
0095 module_phy_driver(et1011c_driver);
0096 
0097 static struct mdio_device_id __maybe_unused et1011c_tbl[] = {
0098     { 0x0282f014, 0xfffffff0 },
0099     { }
0100 };
0101 
0102 MODULE_DEVICE_TABLE(mdio, et1011c_tbl);