1 /*
2  * Broadcom GENET MDIO routines
3  *
4  * Copyright (c) 2014 Broadcom Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 
11 
12 #include <linux/types.h>
13 #include <linux/delay.h>
14 #include <linux/wait.h>
15 #include <linux/mii.h>
16 #include <linux/ethtool.h>
17 #include <linux/bitops.h>
18 #include <linux/netdevice.h>
19 #include <linux/platform_device.h>
20 #include <linux/phy.h>
21 #include <linux/phy_fixed.h>
22 #include <linux/brcmphy.h>
23 #include <linux/of.h>
24 #include <linux/of_net.h>
25 #include <linux/of_mdio.h>
26 
27 #include "bcmgenet.h"
28 
29 /* read a value from the MII */
30 static int bcmgenet_mii_read(struct mii_bus *bus, int phy_id, int location)
31 {
32 	int ret;
33 	struct net_device *dev = bus->priv;
34 	struct bcmgenet_priv *priv = netdev_priv(dev);
35 	u32 reg;
36 
37 	bcmgenet_umac_writel(priv, (MDIO_RD | (phy_id << MDIO_PMD_SHIFT) |
38 			     (location << MDIO_REG_SHIFT)), UMAC_MDIO_CMD);
39 	/* Start MDIO transaction*/
40 	reg = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
41 	reg |= MDIO_START_BUSY;
42 	bcmgenet_umac_writel(priv, reg, UMAC_MDIO_CMD);
43 	wait_event_timeout(priv->wq,
44 			   !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD)
45 			   & MDIO_START_BUSY),
46 			   HZ / 100);
47 	ret = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
48 
49 	if (ret & MDIO_READ_FAIL)
50 		return -EIO;
51 
52 	return ret & 0xffff;
53 }
54 
55 /* write a value to the MII */
56 static int bcmgenet_mii_write(struct mii_bus *bus, int phy_id,
57 			      int location, u16 val)
58 {
59 	struct net_device *dev = bus->priv;
60 	struct bcmgenet_priv *priv = netdev_priv(dev);
61 	u32 reg;
62 
63 	bcmgenet_umac_writel(priv, (MDIO_WR | (phy_id << MDIO_PMD_SHIFT) |
64 			     (location << MDIO_REG_SHIFT) | (0xffff & val)),
65 			     UMAC_MDIO_CMD);
66 	reg = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
67 	reg |= MDIO_START_BUSY;
68 	bcmgenet_umac_writel(priv, reg, UMAC_MDIO_CMD);
69 	wait_event_timeout(priv->wq,
70 			   !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD) &
71 			   MDIO_START_BUSY),
72 			   HZ / 100);
73 
74 	return 0;
75 }
76 
77 /* setup netdev link state when PHY link status change and
78  * update UMAC and RGMII block when link up
79  */
80 static void bcmgenet_mii_setup(struct net_device *dev)
81 {
82 	struct bcmgenet_priv *priv = netdev_priv(dev);
83 	struct phy_device *phydev = priv->phydev;
84 	u32 reg, cmd_bits = 0;
85 	unsigned int status_changed = 0;
86 
87 	if (priv->old_link != phydev->link) {
88 		status_changed = 1;
89 		priv->old_link = phydev->link;
90 	}
91 
92 	if (phydev->link) {
93 		/* program UMAC and RGMII block based on established link
94 		 * speed, pause, and duplex.
95 		 * the speed set in umac->cmd tell RGMII block which clock
96 		 * 25MHz(100Mbps)/125MHz(1Gbps) to use for transmit.
97 		 * receive clock is provided by PHY.
98 		 */
99 		reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
100 		reg &= ~OOB_DISABLE;
101 		reg |= RGMII_LINK;
102 		bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
103 
104 		/* speed */
105 		if (phydev->speed == SPEED_1000)
106 			cmd_bits = UMAC_SPEED_1000;
107 		else if (phydev->speed == SPEED_100)
108 			cmd_bits = UMAC_SPEED_100;
109 		else
110 			cmd_bits = UMAC_SPEED_10;
111 		cmd_bits <<= CMD_SPEED_SHIFT;
112 
113 		if (priv->old_duplex != phydev->duplex) {
114 			status_changed = 1;
115 			priv->old_duplex = phydev->duplex;
116 		}
117 
118 		/* duplex */
119 		if (phydev->duplex != DUPLEX_FULL)
120 			cmd_bits |= CMD_HD_EN;
121 
122 		if (priv->old_pause != phydev->pause) {
123 			status_changed = 1;
124 			priv->old_pause = phydev->pause;
125 		}
126 
127 		/* pause capability */
128 		if (!phydev->pause)
129 			cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
130 	}
131 
132 	if (!status_changed)
133 		return;
134 
135 	if (phydev->link) {
136 		reg = bcmgenet_umac_readl(priv, UMAC_CMD);
137 		reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
138 			       CMD_HD_EN |
139 			       CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
140 		reg |= cmd_bits;
141 		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
142 
143 	}
144 
145 	phy_print_status(phydev);
146 }
147 
148 void bcmgenet_mii_reset(struct net_device *dev)
149 {
150 	struct bcmgenet_priv *priv = netdev_priv(dev);
151 
152 	if (priv->phydev) {
153 		phy_init_hw(priv->phydev);
154 		phy_start_aneg(priv->phydev);
155 	}
156 }
157 
158 static void bcmgenet_ephy_power_up(struct net_device *dev)
159 {
160 	struct bcmgenet_priv *priv = netdev_priv(dev);
161 	u32 reg = 0;
162 
163 	/* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
164 	if (!GENET_IS_V4(priv))
165 		return;
166 
167 	reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
168 	reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN);
169 	reg |= EXT_GPHY_RESET;
170 	bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
171 	mdelay(2);
172 
173 	reg &= ~EXT_GPHY_RESET;
174 	bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
175 	udelay(20);
176 }
177 
178 static void bcmgenet_internal_phy_setup(struct net_device *dev)
179 {
180 	struct bcmgenet_priv *priv = netdev_priv(dev);
181 	u32 reg;
182 
183 	/* Power up EPHY */
184 	bcmgenet_ephy_power_up(dev);
185 	/* enable APD */
186 	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
187 	reg |= EXT_PWR_DN_EN_LD;
188 	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
189 	bcmgenet_mii_reset(dev);
190 }
191 
192 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
193 {
194 	u32 reg;
195 
196 	/* Speed settings are set in bcmgenet_mii_setup() */
197 	reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
198 	reg |= LED_ACT_SOURCE_MAC;
199 	bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
200 }
201 
202 int bcmgenet_mii_config(struct net_device *dev)
203 {
204 	struct bcmgenet_priv *priv = netdev_priv(dev);
205 	struct phy_device *phydev = priv->phydev;
206 	struct device *kdev = &priv->pdev->dev;
207 	const char *phy_name = NULL;
208 	u32 id_mode_dis = 0;
209 	u32 port_ctrl;
210 	u32 reg;
211 
212 	priv->ext_phy = !phy_is_internal(priv->phydev) &&
213 			(priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
214 
215 	if (phy_is_internal(priv->phydev))
216 		priv->phy_interface = PHY_INTERFACE_MODE_NA;
217 
218 	switch (priv->phy_interface) {
219 	case PHY_INTERFACE_MODE_NA:
220 	case PHY_INTERFACE_MODE_MOCA:
221 		/* Irrespective of the actually configured PHY speed (100 or
222 		 * 1000) GENETv4 only has an internal GPHY so we will just end
223 		 * up masking the Gigabit features from what we support, not
224 		 * switching to the EPHY
225 		 */
226 		if (GENET_IS_V4(priv))
227 			port_ctrl = PORT_MODE_INT_GPHY;
228 		else
229 			port_ctrl = PORT_MODE_INT_EPHY;
230 
231 		bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
232 
233 		if (phy_is_internal(priv->phydev)) {
234 			phy_name = "internal PHY";
235 			bcmgenet_internal_phy_setup(dev);
236 		} else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
237 			phy_name = "MoCA";
238 			bcmgenet_moca_phy_setup(priv);
239 		}
240 		break;
241 
242 	case PHY_INTERFACE_MODE_MII:
243 		phy_name = "external MII";
244 		phydev->supported &= PHY_BASIC_FEATURES;
245 		bcmgenet_sys_writel(priv,
246 				    PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
247 		break;
248 
249 	case PHY_INTERFACE_MODE_REVMII:
250 		phy_name = "external RvMII";
251 		/* of_mdiobus_register took care of reading the 'max-speed'
252 		 * PHY property for us, effectively limiting the PHY supported
253 		 * capabilities, use that knowledge to also configure the
254 		 * Reverse MII interface correctly.
255 		 */
256 		if ((priv->phydev->supported & PHY_BASIC_FEATURES) ==
257 				PHY_BASIC_FEATURES)
258 			port_ctrl = PORT_MODE_EXT_RVMII_25;
259 		else
260 			port_ctrl = PORT_MODE_EXT_RVMII_50;
261 		bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
262 		break;
263 
264 	case PHY_INTERFACE_MODE_RGMII:
265 		/* RGMII_NO_ID: TXC transitions at the same time as TXD
266 		 *		(requires PCB or receiver-side delay)
267 		 * RGMII:	Add 2ns delay on TXC (90 degree shift)
268 		 *
269 		 * ID is implicitly disabled for 100Mbps (RG)MII operation.
270 		 */
271 		id_mode_dis = BIT(16);
272 		/* fall through */
273 	case PHY_INTERFACE_MODE_RGMII_TXID:
274 		if (id_mode_dis)
275 			phy_name = "external RGMII (no delay)";
276 		else
277 			phy_name = "external RGMII (TX delay)";
278 		reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
279 		reg |= RGMII_MODE_EN | id_mode_dis;
280 		bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
281 		bcmgenet_sys_writel(priv,
282 				    PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
283 		break;
284 	default:
285 		dev_err(kdev, "unknown phy mode: %d\n", priv->phy_interface);
286 		return -EINVAL;
287 	}
288 
289 	dev_info(kdev, "configuring instance for %s\n", phy_name);
290 
291 	return 0;
292 }
293 
294 static int bcmgenet_mii_probe(struct net_device *dev)
295 {
296 	struct bcmgenet_priv *priv = netdev_priv(dev);
297 	struct device_node *dn = priv->pdev->dev.of_node;
298 	struct phy_device *phydev;
299 	unsigned int phy_flags;
300 	int ret;
301 
302 	if (priv->phydev) {
303 		pr_info("PHY already attached\n");
304 		return 0;
305 	}
306 
307 	/* In the case of a fixed PHY, the DT node associated
308 	 * to the PHY is the Ethernet MAC DT node.
309 	 */
310 	if (!priv->phy_dn && of_phy_is_fixed_link(dn)) {
311 		ret = of_phy_register_fixed_link(dn);
312 		if (ret)
313 			return ret;
314 
315 		priv->phy_dn = of_node_get(dn);
316 	}
317 
318 	phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, 0,
319 				priv->phy_interface);
320 	if (!phydev) {
321 		pr_err("could not attach to PHY\n");
322 		return -ENODEV;
323 	}
324 
325 	priv->old_link = -1;
326 	priv->old_duplex = -1;
327 	priv->old_pause = -1;
328 	priv->phydev = phydev;
329 
330 	/* Configure port multiplexer based on what the probed PHY device since
331 	 * reading the 'max-speed' property determines the maximum supported
332 	 * PHY speed which is needed for bcmgenet_mii_config() to configure
333 	 * things appropriately.
334 	 */
335 	ret = bcmgenet_mii_config(dev);
336 	if (ret) {
337 		phy_disconnect(priv->phydev);
338 		return ret;
339 	}
340 
341 	phy_flags = PHY_BRCM_100MBPS_WAR;
342 
343 	/* workarounds are only needed for 100Mpbs PHYs, and
344 	 * never on GENET V1 hardware
345 	 */
346 	if ((phydev->supported & PHY_GBIT_FEATURES) || GENET_IS_V1(priv))
347 		phy_flags = 0;
348 
349 	phydev->dev_flags |= phy_flags;
350 	phydev->advertising = phydev->supported;
351 
352 	/* The internal PHY has its link interrupts routed to the
353 	 * Ethernet MAC ISRs
354 	 */
355 	if (phy_is_internal(priv->phydev))
356 		priv->mii_bus->irq[phydev->addr] = PHY_IGNORE_INTERRUPT;
357 	else
358 		priv->mii_bus->irq[phydev->addr] = PHY_POLL;
359 
360 	pr_info("attached PHY at address %d [%s]\n",
361 		phydev->addr, phydev->drv->name);
362 
363 	return 0;
364 }
365 
366 static int bcmgenet_mii_alloc(struct bcmgenet_priv *priv)
367 {
368 	struct mii_bus *bus;
369 
370 	if (priv->mii_bus)
371 		return 0;
372 
373 	priv->mii_bus = mdiobus_alloc();
374 	if (!priv->mii_bus) {
375 		pr_err("failed to allocate\n");
376 		return -ENOMEM;
377 	}
378 
379 	bus = priv->mii_bus;
380 	bus->priv = priv->dev;
381 	bus->name = "bcmgenet MII bus";
382 	bus->parent = &priv->pdev->dev;
383 	bus->read = bcmgenet_mii_read;
384 	bus->write = bcmgenet_mii_write;
385 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d",
386 		 priv->pdev->name, priv->pdev->id);
387 
388 	bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
389 	if (!bus->irq) {
390 		mdiobus_free(priv->mii_bus);
391 		return -ENOMEM;
392 	}
393 
394 	return 0;
395 }
396 
397 static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
398 {
399 	struct device_node *dn = priv->pdev->dev.of_node;
400 	struct device *kdev = &priv->pdev->dev;
401 	struct device_node *mdio_dn;
402 	char *compat;
403 	int ret;
404 
405 	compat = kasprintf(GFP_KERNEL, "brcm,genet-mdio-v%d", priv->version);
406 	if (!compat)
407 		return -ENOMEM;
408 
409 	mdio_dn = of_find_compatible_node(dn, NULL, compat);
410 	kfree(compat);
411 	if (!mdio_dn) {
412 		dev_err(kdev, "unable to find MDIO bus node\n");
413 		return -ENODEV;
414 	}
415 
416 	ret = of_mdiobus_register(priv->mii_bus, mdio_dn);
417 	if (ret) {
418 		dev_err(kdev, "failed to register MDIO bus\n");
419 		return ret;
420 	}
421 
422 	/* Fetch the PHY phandle */
423 	priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0);
424 
425 	/* Get the link mode */
426 	priv->phy_interface = of_get_phy_mode(dn);
427 
428 	return 0;
429 }
430 
431 int bcmgenet_mii_init(struct net_device *dev)
432 {
433 	struct bcmgenet_priv *priv = netdev_priv(dev);
434 	int ret;
435 
436 	ret = bcmgenet_mii_alloc(priv);
437 	if (ret)
438 		return ret;
439 
440 	ret = bcmgenet_mii_of_init(priv);
441 	if (ret)
442 		goto out_free;
443 
444 	ret = bcmgenet_mii_probe(dev);
445 	if (ret)
446 		goto out;
447 
448 	return 0;
449 
450 out:
451 	of_node_put(priv->phy_dn);
452 	mdiobus_unregister(priv->mii_bus);
453 out_free:
454 	kfree(priv->mii_bus->irq);
455 	mdiobus_free(priv->mii_bus);
456 	return ret;
457 }
458 
459 void bcmgenet_mii_exit(struct net_device *dev)
460 {
461 	struct bcmgenet_priv *priv = netdev_priv(dev);
462 
463 	of_node_put(priv->phy_dn);
464 	mdiobus_unregister(priv->mii_bus);
465 	kfree(priv->mii_bus->irq);
466 	mdiobus_free(priv->mii_bus);
467 }
468