cf74d108953e73524344c777ce5a186917e6f326
[cascardo/linux.git] / drivers / net / phy / at803x.c
1 /*
2  * drivers/net/phy/at803x.c
3  *
4  * Driver for Atheros 803x PHY
5  *
6  * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  */
13
14 #include <linux/phy.h>
15 #include <linux/module.h>
16 #include <linux/string.h>
17 #include <linux/netdevice.h>
18 #include <linux/etherdevice.h>
19 #include <linux/of_gpio.h>
20 #include <linux/gpio/consumer.h>
21
22 #define AT803X_INTR_ENABLE                      0x12
23 #define AT803X_INTR_ENABLE_AUTONEG_ERR          BIT(15)
24 #define AT803X_INTR_ENABLE_SPEED_CHANGED        BIT(14)
25 #define AT803X_INTR_ENABLE_DUPLEX_CHANGED       BIT(13)
26 #define AT803X_INTR_ENABLE_PAGE_RECEIVED        BIT(12)
27 #define AT803X_INTR_ENABLE_LINK_FAIL            BIT(11)
28 #define AT803X_INTR_ENABLE_LINK_SUCCESS         BIT(10)
29 #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE  BIT(5)
30 #define AT803X_INTR_ENABLE_POLARITY_CHANGED     BIT(1)
31 #define AT803X_INTR_ENABLE_WOL                  BIT(0)
32
33 #define AT803X_INTR_STATUS                      0x13
34
35 #define AT803X_SMART_SPEED                      0x14
36 #define AT803X_LED_CONTROL                      0x18
37
38 #define AT803X_DEVICE_ADDR                      0x03
39 #define AT803X_LOC_MAC_ADDR_0_15_OFFSET         0x804C
40 #define AT803X_LOC_MAC_ADDR_16_31_OFFSET        0x804B
41 #define AT803X_LOC_MAC_ADDR_32_47_OFFSET        0x804A
42 #define AT803X_MMD_ACCESS_CONTROL               0x0D
43 #define AT803X_MMD_ACCESS_CONTROL_DATA          0x0E
44 #define AT803X_FUNC_DATA                        0x4003
45
46 #define AT803X_DEBUG_ADDR                       0x1D
47 #define AT803X_DEBUG_DATA                       0x1E
48
49 #define AT803X_DEBUG_REG_0                      0x00
50 #define AT803X_DEBUG_RX_CLK_DLY_EN              BIT(15)
51
52 #define AT803X_DEBUG_REG_5                      0x05
53 #define AT803X_DEBUG_TX_CLK_DLY_EN              BIT(8)
54
55 #define ATH8030_PHY_ID 0x004dd076
56 #define ATH8031_PHY_ID 0x004dd074
57 #define ATH8035_PHY_ID 0x004dd072
58
59 MODULE_DESCRIPTION("Atheros 803x PHY driver");
60 MODULE_AUTHOR("Matus Ujhelyi");
61 MODULE_LICENSE("GPL");
62
63 struct at803x_priv {
64         bool phy_reset:1;
65         struct gpio_desc *gpiod_reset;
66 };
67
68 struct at803x_context {
69         u16 bmcr;
70         u16 advertise;
71         u16 control1000;
72         u16 int_enable;
73         u16 smart_speed;
74         u16 led_control;
75 };
76
77 static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
78 {
79         int ret;
80
81         ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
82         if (ret < 0)
83                 return ret;
84
85         return phy_read(phydev, AT803X_DEBUG_DATA);
86 }
87
88 static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
89                                  u16 clear, u16 set)
90 {
91         u16 val;
92         int ret;
93
94         ret = at803x_debug_reg_read(phydev, reg);
95         if (ret < 0)
96                 return ret;
97
98         val = ret & 0xffff;
99         val &= ~clear;
100         val |= set;
101
102         return phy_write(phydev, AT803X_DEBUG_DATA, val);
103 }
104
105 static inline int at803x_enable_rx_delay(struct phy_device *phydev)
106 {
107         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
108                                         AT803X_DEBUG_RX_CLK_DLY_EN);
109 }
110
111 static inline int at803x_enable_tx_delay(struct phy_device *phydev)
112 {
113         return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
114                                         AT803X_DEBUG_TX_CLK_DLY_EN);
115 }
116
117 /* save relevant PHY registers to private copy */
118 static void at803x_context_save(struct phy_device *phydev,
119                                 struct at803x_context *context)
120 {
121         context->bmcr = phy_read(phydev, MII_BMCR);
122         context->advertise = phy_read(phydev, MII_ADVERTISE);
123         context->control1000 = phy_read(phydev, MII_CTRL1000);
124         context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
125         context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
126         context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
127 }
128
129 /* restore relevant PHY registers from private copy */
130 static void at803x_context_restore(struct phy_device *phydev,
131                                    const struct at803x_context *context)
132 {
133         phy_write(phydev, MII_BMCR, context->bmcr);
134         phy_write(phydev, MII_ADVERTISE, context->advertise);
135         phy_write(phydev, MII_CTRL1000, context->control1000);
136         phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
137         phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
138         phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
139 }
140
141 static int at803x_set_wol(struct phy_device *phydev,
142                           struct ethtool_wolinfo *wol)
143 {
144         struct net_device *ndev = phydev->attached_dev;
145         const u8 *mac;
146         int ret;
147         u32 value;
148         unsigned int i, offsets[] = {
149                 AT803X_LOC_MAC_ADDR_32_47_OFFSET,
150                 AT803X_LOC_MAC_ADDR_16_31_OFFSET,
151                 AT803X_LOC_MAC_ADDR_0_15_OFFSET,
152         };
153
154         if (!ndev)
155                 return -ENODEV;
156
157         if (wol->wolopts & WAKE_MAGIC) {
158                 mac = (const u8 *) ndev->dev_addr;
159
160                 if (!is_valid_ether_addr(mac))
161                         return -EFAULT;
162
163                 for (i = 0; i < 3; i++) {
164                         phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
165                                   AT803X_DEVICE_ADDR);
166                         phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
167                                   offsets[i]);
168                         phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
169                                   AT803X_FUNC_DATA);
170                         phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
171                                   mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
172                 }
173
174                 value = phy_read(phydev, AT803X_INTR_ENABLE);
175                 value |= AT803X_INTR_ENABLE_WOL;
176                 ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
177                 if (ret)
178                         return ret;
179                 value = phy_read(phydev, AT803X_INTR_STATUS);
180         } else {
181                 value = phy_read(phydev, AT803X_INTR_ENABLE);
182                 value &= (~AT803X_INTR_ENABLE_WOL);
183                 ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
184                 if (ret)
185                         return ret;
186                 value = phy_read(phydev, AT803X_INTR_STATUS);
187         }
188
189         return ret;
190 }
191
192 static void at803x_get_wol(struct phy_device *phydev,
193                            struct ethtool_wolinfo *wol)
194 {
195         u32 value;
196
197         wol->supported = WAKE_MAGIC;
198         wol->wolopts = 0;
199
200         value = phy_read(phydev, AT803X_INTR_ENABLE);
201         if (value & AT803X_INTR_ENABLE_WOL)
202                 wol->wolopts |= WAKE_MAGIC;
203 }
204
205 static int at803x_suspend(struct phy_device *phydev)
206 {
207         int value;
208         int wol_enabled;
209
210         mutex_lock(&phydev->lock);
211
212         value = phy_read(phydev, AT803X_INTR_ENABLE);
213         wol_enabled = value & AT803X_INTR_ENABLE_WOL;
214
215         value = phy_read(phydev, MII_BMCR);
216
217         if (wol_enabled)
218                 value |= BMCR_ISOLATE;
219         else
220                 value |= BMCR_PDOWN;
221
222         phy_write(phydev, MII_BMCR, value);
223
224         mutex_unlock(&phydev->lock);
225
226         return 0;
227 }
228
229 static int at803x_resume(struct phy_device *phydev)
230 {
231         int value;
232
233         mutex_lock(&phydev->lock);
234
235         value = phy_read(phydev, MII_BMCR);
236         value &= ~(BMCR_PDOWN | BMCR_ISOLATE);
237         phy_write(phydev, MII_BMCR, value);
238
239         mutex_unlock(&phydev->lock);
240
241         return 0;
242 }
243
244 static int at803x_probe(struct phy_device *phydev)
245 {
246         struct device *dev = &phydev->mdio.dev;
247         struct at803x_priv *priv;
248         struct gpio_desc *gpiod_reset;
249
250         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
251         if (!priv)
252                 return -ENOMEM;
253
254         if (phydev->drv->phy_id != ATH8030_PHY_ID)
255                 goto does_not_require_reset_workaround;
256
257         gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
258         if (IS_ERR(gpiod_reset))
259                 return PTR_ERR(gpiod_reset);
260
261         priv->gpiod_reset = gpiod_reset;
262
263 does_not_require_reset_workaround:
264         phydev->priv = priv;
265
266         return 0;
267 }
268
269 static int at803x_config_init(struct phy_device *phydev)
270 {
271         int ret;
272
273         ret = genphy_config_init(phydev);
274         if (ret < 0)
275                 return ret;
276
277         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
278                         phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
279                 ret = at803x_enable_rx_delay(phydev);
280                 if (ret < 0)
281                         return ret;
282         }
283
284         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
285                         phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
286                 ret = at803x_enable_tx_delay(phydev);
287                 if (ret < 0)
288                         return ret;
289         }
290
291         return 0;
292 }
293
294 static int at803x_ack_interrupt(struct phy_device *phydev)
295 {
296         int err;
297
298         err = phy_read(phydev, AT803X_INTR_STATUS);
299
300         return (err < 0) ? err : 0;
301 }
302
303 static int at803x_config_intr(struct phy_device *phydev)
304 {
305         int err;
306         int value;
307
308         value = phy_read(phydev, AT803X_INTR_ENABLE);
309
310         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
311                 value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
312                 value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
313                 value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
314                 value |= AT803X_INTR_ENABLE_LINK_FAIL;
315                 value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
316
317                 err = phy_write(phydev, AT803X_INTR_ENABLE, value);
318         }
319         else
320                 err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
321
322         return err;
323 }
324
325 static void at803x_link_change_notify(struct phy_device *phydev)
326 {
327         struct at803x_priv *priv = phydev->priv;
328
329         /*
330          * Conduct a hardware reset for AT8030 every time a link loss is
331          * signalled. This is necessary to circumvent a hardware bug that
332          * occurs when the cable is unplugged while TX packets are pending
333          * in the FIFO. In such cases, the FIFO enters an error mode it
334          * cannot recover from by software.
335          */
336         if (phydev->state == PHY_NOLINK) {
337                 if (priv->gpiod_reset && !priv->phy_reset) {
338                         struct at803x_context context;
339
340                         at803x_context_save(phydev, &context);
341
342                         gpiod_set_value(priv->gpiod_reset, 1);
343                         msleep(1);
344                         gpiod_set_value(priv->gpiod_reset, 0);
345                         msleep(1);
346
347                         at803x_context_restore(phydev, &context);
348
349                         phydev_dbg(phydev, "%s(): phy was reset\n",
350                                    __func__);
351                         priv->phy_reset = true;
352                 }
353         } else {
354                 priv->phy_reset = false;
355         }
356 }
357
358 static struct phy_driver at803x_driver[] = {
359 {
360         /* ATHEROS 8035 */
361         .phy_id                 = ATH8035_PHY_ID,
362         .name                   = "Atheros 8035 ethernet",
363         .phy_id_mask            = 0xffffffef,
364         .probe                  = at803x_probe,
365         .config_init            = at803x_config_init,
366         .set_wol                = at803x_set_wol,
367         .get_wol                = at803x_get_wol,
368         .suspend                = at803x_suspend,
369         .resume                 = at803x_resume,
370         .features               = PHY_GBIT_FEATURES,
371         .flags                  = PHY_HAS_INTERRUPT,
372         .config_aneg            = genphy_config_aneg,
373         .read_status            = genphy_read_status,
374         .ack_interrupt          = at803x_ack_interrupt,
375         .config_intr            = at803x_config_intr,
376 }, {
377         /* ATHEROS 8030 */
378         .phy_id                 = ATH8030_PHY_ID,
379         .name                   = "Atheros 8030 ethernet",
380         .phy_id_mask            = 0xffffffef,
381         .probe                  = at803x_probe,
382         .config_init            = at803x_config_init,
383         .link_change_notify     = at803x_link_change_notify,
384         .set_wol                = at803x_set_wol,
385         .get_wol                = at803x_get_wol,
386         .suspend                = at803x_suspend,
387         .resume                 = at803x_resume,
388         .features               = PHY_BASIC_FEATURES,
389         .flags                  = PHY_HAS_INTERRUPT,
390         .config_aneg            = genphy_config_aneg,
391         .read_status            = genphy_read_status,
392         .ack_interrupt          = at803x_ack_interrupt,
393         .config_intr            = at803x_config_intr,
394 }, {
395         /* ATHEROS 8031 */
396         .phy_id                 = ATH8031_PHY_ID,
397         .name                   = "Atheros 8031 ethernet",
398         .phy_id_mask            = 0xffffffef,
399         .probe                  = at803x_probe,
400         .config_init            = at803x_config_init,
401         .set_wol                = at803x_set_wol,
402         .get_wol                = at803x_get_wol,
403         .suspend                = at803x_suspend,
404         .resume                 = at803x_resume,
405         .features               = PHY_GBIT_FEATURES,
406         .flags                  = PHY_HAS_INTERRUPT,
407         .config_aneg            = genphy_config_aneg,
408         .read_status            = genphy_read_status,
409         .ack_interrupt          = &at803x_ack_interrupt,
410         .config_intr            = &at803x_config_intr,
411 } };
412
413 module_phy_driver(at803x_driver);
414
415 static struct mdio_device_id __maybe_unused atheros_tbl[] = {
416         { ATH8030_PHY_ID, 0xffffffef },
417         { ATH8031_PHY_ID, 0xffffffef },
418         { ATH8035_PHY_ID, 0xffffffef },
419         { }
420 };
421
422 MODULE_DEVICE_TABLE(mdio, atheros_tbl);