xref: /openbmc/linux/drivers/net/phy/at803x.c (revision 3e26a691)
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 AT803X_REG_CHIP_CONFIG			0x1f
56 #define AT803X_BT_BX_REG_SEL			0x8000
57 
58 #define ATH8030_PHY_ID 0x004dd076
59 #define ATH8031_PHY_ID 0x004dd074
60 #define ATH8035_PHY_ID 0x004dd072
61 
62 MODULE_DESCRIPTION("Atheros 803x PHY driver");
63 MODULE_AUTHOR("Matus Ujhelyi");
64 MODULE_LICENSE("GPL");
65 
66 struct at803x_priv {
67 	bool phy_reset:1;
68 	struct gpio_desc *gpiod_reset;
69 };
70 
71 struct at803x_context {
72 	u16 bmcr;
73 	u16 advertise;
74 	u16 control1000;
75 	u16 int_enable;
76 	u16 smart_speed;
77 	u16 led_control;
78 };
79 
80 static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
81 {
82 	int ret;
83 
84 	ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
85 	if (ret < 0)
86 		return ret;
87 
88 	return phy_read(phydev, AT803X_DEBUG_DATA);
89 }
90 
91 static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
92 				 u16 clear, u16 set)
93 {
94 	u16 val;
95 	int ret;
96 
97 	ret = at803x_debug_reg_read(phydev, reg);
98 	if (ret < 0)
99 		return ret;
100 
101 	val = ret & 0xffff;
102 	val &= ~clear;
103 	val |= set;
104 
105 	return phy_write(phydev, AT803X_DEBUG_DATA, val);
106 }
107 
108 static inline int at803x_enable_rx_delay(struct phy_device *phydev)
109 {
110 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
111 					AT803X_DEBUG_RX_CLK_DLY_EN);
112 }
113 
114 static inline int at803x_enable_tx_delay(struct phy_device *phydev)
115 {
116 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
117 					AT803X_DEBUG_TX_CLK_DLY_EN);
118 }
119 
120 /* save relevant PHY registers to private copy */
121 static void at803x_context_save(struct phy_device *phydev,
122 				struct at803x_context *context)
123 {
124 	context->bmcr = phy_read(phydev, MII_BMCR);
125 	context->advertise = phy_read(phydev, MII_ADVERTISE);
126 	context->control1000 = phy_read(phydev, MII_CTRL1000);
127 	context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
128 	context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
129 	context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
130 }
131 
132 /* restore relevant PHY registers from private copy */
133 static void at803x_context_restore(struct phy_device *phydev,
134 				   const struct at803x_context *context)
135 {
136 	phy_write(phydev, MII_BMCR, context->bmcr);
137 	phy_write(phydev, MII_ADVERTISE, context->advertise);
138 	phy_write(phydev, MII_CTRL1000, context->control1000);
139 	phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
140 	phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
141 	phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
142 }
143 
144 static int at803x_set_wol(struct phy_device *phydev,
145 			  struct ethtool_wolinfo *wol)
146 {
147 	struct net_device *ndev = phydev->attached_dev;
148 	const u8 *mac;
149 	int ret;
150 	u32 value;
151 	unsigned int i, offsets[] = {
152 		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
153 		AT803X_LOC_MAC_ADDR_16_31_OFFSET,
154 		AT803X_LOC_MAC_ADDR_0_15_OFFSET,
155 	};
156 
157 	if (!ndev)
158 		return -ENODEV;
159 
160 	if (wol->wolopts & WAKE_MAGIC) {
161 		mac = (const u8 *) ndev->dev_addr;
162 
163 		if (!is_valid_ether_addr(mac))
164 			return -EFAULT;
165 
166 		for (i = 0; i < 3; i++) {
167 			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
168 				  AT803X_DEVICE_ADDR);
169 			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
170 				  offsets[i]);
171 			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
172 				  AT803X_FUNC_DATA);
173 			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
174 				  mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
175 		}
176 
177 		value = phy_read(phydev, AT803X_INTR_ENABLE);
178 		value |= AT803X_INTR_ENABLE_WOL;
179 		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
180 		if (ret)
181 			return ret;
182 		value = phy_read(phydev, AT803X_INTR_STATUS);
183 	} else {
184 		value = phy_read(phydev, AT803X_INTR_ENABLE);
185 		value &= (~AT803X_INTR_ENABLE_WOL);
186 		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
187 		if (ret)
188 			return ret;
189 		value = phy_read(phydev, AT803X_INTR_STATUS);
190 	}
191 
192 	return ret;
193 }
194 
195 static void at803x_get_wol(struct phy_device *phydev,
196 			   struct ethtool_wolinfo *wol)
197 {
198 	u32 value;
199 
200 	wol->supported = WAKE_MAGIC;
201 	wol->wolopts = 0;
202 
203 	value = phy_read(phydev, AT803X_INTR_ENABLE);
204 	if (value & AT803X_INTR_ENABLE_WOL)
205 		wol->wolopts |= WAKE_MAGIC;
206 }
207 
208 static int at803x_suspend(struct phy_device *phydev)
209 {
210 	int value;
211 	int wol_enabled;
212 	int ccr;
213 
214 	mutex_lock(&phydev->lock);
215 
216 	value = phy_read(phydev, AT803X_INTR_ENABLE);
217 	wol_enabled = value & AT803X_INTR_ENABLE_WOL;
218 
219 	value = phy_read(phydev, MII_BMCR);
220 
221 	if (wol_enabled)
222 		value |= BMCR_ISOLATE;
223 	else
224 		value |= BMCR_PDOWN;
225 
226 	phy_write(phydev, MII_BMCR, value);
227 
228 	if (phydev->interface != PHY_INTERFACE_MODE_SGMII)
229 		goto done;
230 
231 	/* also power-down SGMII interface */
232 	ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
233 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
234 	phy_write(phydev, MII_BMCR, phy_read(phydev, MII_BMCR) | BMCR_PDOWN);
235 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
236 
237 done:
238 	mutex_unlock(&phydev->lock);
239 
240 	return 0;
241 }
242 
243 static int at803x_resume(struct phy_device *phydev)
244 {
245 	int value;
246 	int ccr;
247 
248 	mutex_lock(&phydev->lock);
249 
250 	value = phy_read(phydev, MII_BMCR);
251 	value &= ~(BMCR_PDOWN | BMCR_ISOLATE);
252 	phy_write(phydev, MII_BMCR, value);
253 
254 	if (phydev->interface != PHY_INTERFACE_MODE_SGMII)
255 		goto done;
256 
257 	/* also power-up SGMII interface */
258 	ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
259 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
260 	value = phy_read(phydev, MII_BMCR) & ~(BMCR_PDOWN | BMCR_ISOLATE);
261 	phy_write(phydev, MII_BMCR, value);
262 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
263 
264 done:
265 	mutex_unlock(&phydev->lock);
266 
267 	return 0;
268 }
269 
270 static int at803x_probe(struct phy_device *phydev)
271 {
272 	struct device *dev = &phydev->mdio.dev;
273 	struct at803x_priv *priv;
274 	struct gpio_desc *gpiod_reset;
275 
276 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
277 	if (!priv)
278 		return -ENOMEM;
279 
280 	if (phydev->drv->phy_id != ATH8030_PHY_ID)
281 		goto does_not_require_reset_workaround;
282 
283 	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
284 	if (IS_ERR(gpiod_reset))
285 		return PTR_ERR(gpiod_reset);
286 
287 	priv->gpiod_reset = gpiod_reset;
288 
289 does_not_require_reset_workaround:
290 	phydev->priv = priv;
291 
292 	return 0;
293 }
294 
295 static int at803x_config_init(struct phy_device *phydev)
296 {
297 	int ret;
298 
299 	ret = genphy_config_init(phydev);
300 	if (ret < 0)
301 		return ret;
302 
303 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
304 			phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
305 		ret = at803x_enable_rx_delay(phydev);
306 		if (ret < 0)
307 			return ret;
308 	}
309 
310 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
311 			phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
312 		ret = at803x_enable_tx_delay(phydev);
313 		if (ret < 0)
314 			return ret;
315 	}
316 
317 	return 0;
318 }
319 
320 static int at803x_ack_interrupt(struct phy_device *phydev)
321 {
322 	int err;
323 
324 	err = phy_read(phydev, AT803X_INTR_STATUS);
325 
326 	return (err < 0) ? err : 0;
327 }
328 
329 static int at803x_config_intr(struct phy_device *phydev)
330 {
331 	int err;
332 	int value;
333 
334 	value = phy_read(phydev, AT803X_INTR_ENABLE);
335 
336 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
337 		value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
338 		value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
339 		value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
340 		value |= AT803X_INTR_ENABLE_LINK_FAIL;
341 		value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
342 
343 		err = phy_write(phydev, AT803X_INTR_ENABLE, value);
344 	}
345 	else
346 		err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
347 
348 	return err;
349 }
350 
351 static void at803x_link_change_notify(struct phy_device *phydev)
352 {
353 	struct at803x_priv *priv = phydev->priv;
354 
355 	/*
356 	 * Conduct a hardware reset for AT8030 every time a link loss is
357 	 * signalled. This is necessary to circumvent a hardware bug that
358 	 * occurs when the cable is unplugged while TX packets are pending
359 	 * in the FIFO. In such cases, the FIFO enters an error mode it
360 	 * cannot recover from by software.
361 	 */
362 	if (phydev->drv->phy_id == ATH8030_PHY_ID) {
363 		if (phydev->state == PHY_NOLINK) {
364 			if (priv->gpiod_reset && !priv->phy_reset) {
365 				struct at803x_context context;
366 
367 				at803x_context_save(phydev, &context);
368 
369 				gpiod_set_value(priv->gpiod_reset, 1);
370 				msleep(1);
371 				gpiod_set_value(priv->gpiod_reset, 0);
372 				msleep(1);
373 
374 				at803x_context_restore(phydev, &context);
375 
376 				phydev_dbg(phydev, "%s(): phy was reset\n",
377 					   __func__);
378 				priv->phy_reset = true;
379 			}
380 		} else {
381 			priv->phy_reset = false;
382 		}
383 	}
384 }
385 
386 static struct phy_driver at803x_driver[] = {
387 {
388 	/* ATHEROS 8035 */
389 	.phy_id			= ATH8035_PHY_ID,
390 	.name			= "Atheros 8035 ethernet",
391 	.phy_id_mask		= 0xffffffef,
392 	.probe			= at803x_probe,
393 	.config_init		= at803x_config_init,
394 	.link_change_notify	= at803x_link_change_notify,
395 	.set_wol		= at803x_set_wol,
396 	.get_wol		= at803x_get_wol,
397 	.suspend		= at803x_suspend,
398 	.resume			= at803x_resume,
399 	.features		= PHY_GBIT_FEATURES,
400 	.flags			= PHY_HAS_INTERRUPT,
401 	.config_aneg		= genphy_config_aneg,
402 	.read_status		= genphy_read_status,
403 	.ack_interrupt		= at803x_ack_interrupt,
404 	.config_intr		= at803x_config_intr,
405 }, {
406 	/* ATHEROS 8030 */
407 	.phy_id			= ATH8030_PHY_ID,
408 	.name			= "Atheros 8030 ethernet",
409 	.phy_id_mask		= 0xffffffef,
410 	.probe			= at803x_probe,
411 	.config_init		= at803x_config_init,
412 	.link_change_notify	= at803x_link_change_notify,
413 	.set_wol		= at803x_set_wol,
414 	.get_wol		= at803x_get_wol,
415 	.suspend		= at803x_suspend,
416 	.resume			= at803x_resume,
417 	.features		= PHY_BASIC_FEATURES,
418 	.flags			= PHY_HAS_INTERRUPT,
419 	.config_aneg		= genphy_config_aneg,
420 	.read_status		= genphy_read_status,
421 	.ack_interrupt		= at803x_ack_interrupt,
422 	.config_intr		= at803x_config_intr,
423 }, {
424 	/* ATHEROS 8031 */
425 	.phy_id			= ATH8031_PHY_ID,
426 	.name			= "Atheros 8031 ethernet",
427 	.phy_id_mask		= 0xffffffef,
428 	.probe			= at803x_probe,
429 	.config_init		= at803x_config_init,
430 	.link_change_notify	= at803x_link_change_notify,
431 	.set_wol		= at803x_set_wol,
432 	.get_wol		= at803x_get_wol,
433 	.suspend		= at803x_suspend,
434 	.resume			= at803x_resume,
435 	.features		= PHY_GBIT_FEATURES,
436 	.flags			= PHY_HAS_INTERRUPT,
437 	.config_aneg		= genphy_config_aneg,
438 	.read_status		= genphy_read_status,
439 	.ack_interrupt		= &at803x_ack_interrupt,
440 	.config_intr		= &at803x_config_intr,
441 } };
442 
443 module_phy_driver(at803x_driver);
444 
445 static struct mdio_device_id __maybe_unused atheros_tbl[] = {
446 	{ ATH8030_PHY_ID, 0xffffffef },
447 	{ ATH8031_PHY_ID, 0xffffffef },
448 	{ ATH8035_PHY_ID, 0xffffffef },
449 	{ }
450 };
451 
452 MODULE_DEVICE_TABLE(mdio, atheros_tbl);
453