1a2443fd1SAndrew Lunn // SPDX-License-Identifier: GPL-2.0+
2dbb7a95dSChaithrika U S /*
3dbb7a95dSChaithrika U S * drivers/net/phy/et1011c.c
4dbb7a95dSChaithrika U S *
5dbb7a95dSChaithrika U S * Driver for LSI ET1011C PHYs
6dbb7a95dSChaithrika U S *
7dbb7a95dSChaithrika U S * Author: Chaithrika U S
8dbb7a95dSChaithrika U S *
9dbb7a95dSChaithrika U S * Copyright (c) 2008 Texas Instruments
10dbb7a95dSChaithrika U S */
11dbb7a95dSChaithrika U S #include <linux/kernel.h>
12dbb7a95dSChaithrika U S #include <linux/string.h>
13dbb7a95dSChaithrika U S #include <linux/errno.h>
14dbb7a95dSChaithrika U S #include <linux/unistd.h>
15dbb7a95dSChaithrika U S #include <linux/interrupt.h>
16dbb7a95dSChaithrika U S #include <linux/init.h>
17dbb7a95dSChaithrika U S #include <linux/delay.h>
18dbb7a95dSChaithrika U S #include <linux/netdevice.h>
19dbb7a95dSChaithrika U S #include <linux/etherdevice.h>
20dbb7a95dSChaithrika U S #include <linux/skbuff.h>
21dbb7a95dSChaithrika U S #include <linux/spinlock.h>
22dbb7a95dSChaithrika U S #include <linux/mm.h>
23dbb7a95dSChaithrika U S #include <linux/module.h>
24dbb7a95dSChaithrika U S #include <linux/mii.h>
25dbb7a95dSChaithrika U S #include <linux/ethtool.h>
26dbb7a95dSChaithrika U S #include <linux/phy.h>
27dbb7a95dSChaithrika U S #include <linux/io.h>
28dbb7a95dSChaithrika U S #include <linux/uaccess.h>
29dbb7a95dSChaithrika U S #include <asm/irq.h>
30dbb7a95dSChaithrika U S
31dbb7a95dSChaithrika U S #define ET1011C_STATUS_REG (0x1A)
32dbb7a95dSChaithrika U S #define ET1011C_CONFIG_REG (0x16)
33dbb7a95dSChaithrika U S #define ET1011C_SPEED_MASK (0x0300)
34dbb7a95dSChaithrika U S #define ET1011C_GIGABIT_SPEED (0x0200)
35dbb7a95dSChaithrika U S #define ET1011C_TX_FIFO_MASK (0x3000)
36dbb7a95dSChaithrika U S #define ET1011C_TX_FIFO_DEPTH_8 (0x0000)
37dbb7a95dSChaithrika U S #define ET1011C_TX_FIFO_DEPTH_16 (0x1000)
38dbb7a95dSChaithrika U S #define ET1011C_INTERFACE_MASK (0x0007)
39dbb7a95dSChaithrika U S #define ET1011C_GMII_INTERFACE (0x0002)
40dbb7a95dSChaithrika U S #define ET1011C_SYS_CLK_EN (0x01 << 4)
41dbb7a95dSChaithrika U S
42dbb7a95dSChaithrika U S
43dbb7a95dSChaithrika U S MODULE_DESCRIPTION("LSI ET1011C PHY driver");
44dbb7a95dSChaithrika U S MODULE_AUTHOR("Chaithrika U S");
45dbb7a95dSChaithrika U S MODULE_LICENSE("GPL");
46dbb7a95dSChaithrika U S
et1011c_config_aneg(struct phy_device * phydev)47dbb7a95dSChaithrika U S static int et1011c_config_aneg(struct phy_device *phydev)
48dbb7a95dSChaithrika U S {
49775f2547SWenpeng Liang int ctl = phy_read(phydev, MII_BMCR);
50775f2547SWenpeng Liang
51dbb7a95dSChaithrika U S if (ctl < 0)
52dbb7a95dSChaithrika U S return ctl;
53dbb7a95dSChaithrika U S ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
54dbb7a95dSChaithrika U S BMCR_ANENABLE);
55dbb7a95dSChaithrika U S /* First clear the PHY */
56dbb7a95dSChaithrika U S phy_write(phydev, MII_BMCR, ctl | BMCR_RESET);
57dbb7a95dSChaithrika U S
58dbb7a95dSChaithrika U S return genphy_config_aneg(phydev);
59dbb7a95dSChaithrika U S }
60dbb7a95dSChaithrika U S
et1011c_read_status(struct phy_device * phydev)61dbb7a95dSChaithrika U S static int et1011c_read_status(struct phy_device *phydev)
62dbb7a95dSChaithrika U S {
63775f2547SWenpeng Liang static int speed;
64dbb7a95dSChaithrika U S int ret;
65dbb7a95dSChaithrika U S u32 val;
66775f2547SWenpeng Liang
67dbb7a95dSChaithrika U S ret = genphy_read_status(phydev);
68dbb7a95dSChaithrika U S
69dbb7a95dSChaithrika U S if (speed != phydev->speed) {
70dbb7a95dSChaithrika U S speed = phydev->speed;
71dbb7a95dSChaithrika U S val = phy_read(phydev, ET1011C_STATUS_REG);
72dbb7a95dSChaithrika U S if ((val & ET1011C_SPEED_MASK) ==
73dbb7a95dSChaithrika U S ET1011C_GIGABIT_SPEED) {
74dbb7a95dSChaithrika U S val = phy_read(phydev, ET1011C_CONFIG_REG);
75dbb7a95dSChaithrika U S val &= ~ET1011C_TX_FIFO_MASK;
76*33ab4632SWenpeng Liang phy_write(phydev, ET1011C_CONFIG_REG, val |
77*33ab4632SWenpeng Liang ET1011C_GMII_INTERFACE |
78*33ab4632SWenpeng Liang ET1011C_SYS_CLK_EN |
79*33ab4632SWenpeng Liang ET1011C_TX_FIFO_DEPTH_16);
80dbb7a95dSChaithrika U S
81dbb7a95dSChaithrika U S }
82dbb7a95dSChaithrika U S }
83dbb7a95dSChaithrika U S return ret;
84dbb7a95dSChaithrika U S }
85dbb7a95dSChaithrika U S
86116dffa0SJohan Hovold static struct phy_driver et1011c_driver[] = { {
87dbb7a95dSChaithrika U S .phy_id = 0x0282f014,
88dbb7a95dSChaithrika U S .name = "ET1011C",
89dbb7a95dSChaithrika U S .phy_id_mask = 0xfffffff0,
90dcdecdcfSHeiner Kallweit /* PHY_GBIT_FEATURES */
91dbb7a95dSChaithrika U S .config_aneg = et1011c_config_aneg,
92dbb7a95dSChaithrika U S .read_status = et1011c_read_status,
93116dffa0SJohan Hovold } };
94dbb7a95dSChaithrika U S
95116dffa0SJohan Hovold module_phy_driver(et1011c_driver);
964e4f10f6SDavid Woodhouse
97cf93c945SUwe Kleine-König static struct mdio_device_id __maybe_unused et1011c_tbl[] = {
984e4f10f6SDavid Woodhouse { 0x0282f014, 0xfffffff0 },
994e4f10f6SDavid Woodhouse { }
1004e4f10f6SDavid Woodhouse };
1014e4f10f6SDavid Woodhouse
1024e4f10f6SDavid Woodhouse MODULE_DEVICE_TABLE(mdio, et1011c_tbl);
103