0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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
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);