1 --- a/drivers/net/phy/at803x.c
2 +++ b/drivers/net/phy/at803x.c
7 +#include <linux/mdio.h>
8 #include <linux/module.h>
9 #include <linux/string.h>
10 #include <linux/netdevice.h>
11 #include <linux/etherdevice.h>
12 +#include <linux/platform_data/phy-at803x.h>
14 #define AT803X_INTR_ENABLE 0x12
15 #define AT803X_INTR_STATUS 0x13
17 #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
18 #define AT803X_FUNC_DATA 0x4003
20 +#define AT803X_PCS_SMART_EEE_CTRL3 0x805D
22 +#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3
23 +#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12
24 +#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8)
26 +#define AT803X_DEBUG_PORT_ACCESS_OFFSET 0x1D
27 +#define AT803X_DEBUG_PORT_ACCESS_DATA 0x1E
29 +#define AT803X_DBG0_REG 0x00
30 +#define AT803X_DBG0_RGMII_RX_CLK_DELAY_EN BIT(8)
32 +#define AT803X_DBG5_REG 0x05
33 +#define AT803X_DBG5_RGMII_TX_CLK_DELAY_EN BIT(8)
35 MODULE_DESCRIPTION("Atheros 803x PHY driver");
36 MODULE_AUTHOR("Matus Ujhelyi");
37 MODULE_LICENSE("GPL");
40 +at803x_dbg_reg_rmw(struct phy_device *phydev, u16 reg, u16 clear, u16 set)
42 + struct mii_bus *bus = phydev->bus;
45 + mutex_lock(&bus->mdio_lock);
47 + bus->write(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_OFFSET, reg);
48 + val = bus->read(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_DATA);
56 + bus->write(bus, phydev->addr, AT803X_DEBUG_PORT_ACCESS_DATA, val);
59 + mutex_unlock(&bus->mdio_lock);
64 +at803x_dbg_reg_set(struct phy_device *phydev, u16 reg, u16 set)
66 + at803x_dbg_reg_rmw(phydev, reg, 0, set);
70 +at803x_dbg_reg_clr(struct phy_device *phydev, u16 reg, u16 clear)
72 + at803x_dbg_reg_rmw(phydev, reg, clear, 0);
75 static void at803x_set_wol_mac_addr(struct phy_device *phydev)
77 struct net_device *ndev = phydev->attached_dev;
78 @@ -62,8 +115,16 @@ static void at803x_set_wol_mac_addr(stru
82 +static void at803x_disable_smarteee(struct phy_device *phydev)
84 + phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3,
85 + 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT);
86 + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
89 static int at803x_config_init(struct phy_device *phydev)
91 + struct at803x_platform_data *pdata;
95 @@ -105,6 +166,26 @@ static int at803x_config_init(struct phy
96 status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE);
97 status = phy_read(phydev, AT803X_INTR_STATUS);
99 + pdata = dev_get_platdata(&phydev->dev);
101 + if (pdata->disable_smarteee)
102 + at803x_disable_smarteee(phydev);
104 + if (pdata->enable_rgmii_rx_delay)
105 + at803x_dbg_reg_set(phydev, AT803X_DBG0_REG,
106 + AT803X_DBG0_RGMII_RX_CLK_DELAY_EN);
108 + at803x_dbg_reg_clr(phydev, AT803X_DBG0_REG,
109 + AT803X_DBG0_RGMII_RX_CLK_DELAY_EN);
111 + if (pdata->enable_rgmii_tx_delay)
112 + at803x_dbg_reg_set(phydev, AT803X_DBG5_REG,
113 + AT803X_DBG5_RGMII_TX_CLK_DELAY_EN);
115 + at803x_dbg_reg_clr(phydev, AT803X_DBG5_REG,
116 + AT803X_DBG5_RGMII_TX_CLK_DELAY_EN);
123 +++ b/include/linux/platform_data/phy-at803x.h
125 +#ifndef _PHY_AT803X_PDATA_H
126 +#define _PHY_AT803X_PDATA_H
128 +struct at803x_platform_data {
129 + int disable_smarteee:1;
130 + int enable_rgmii_tx_delay:1;
131 + int enable_rgmii_rx_delay:1;
134 +#endif /* _PHY_AT803X_PDATA_H */