Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Broadcom GENET MDIO routines
  4 *
  5 * Copyright (c) 2014-2017 Broadcom
  6 */
  7
  8
  9#include <linux/types.h>
 10#include <linux/delay.h>
 11#include <linux/wait.h>
 12#include <linux/mii.h>
 13#include <linux/ethtool.h>
 14#include <linux/bitops.h>
 15#include <linux/netdevice.h>
 16#include <linux/platform_device.h>
 17#include <linux/phy.h>
 18#include <linux/phy_fixed.h>
 19#include <linux/brcmphy.h>
 20#include <linux/of.h>
 21#include <linux/of_net.h>
 22#include <linux/of_mdio.h>
 23#include <linux/platform_data/bcmgenet.h>
 24#include <linux/platform_data/mdio-bcm-unimac.h>
 25
 26#include "bcmgenet.h"
 27
 28/* setup netdev link state when PHY link status change and
 29 * update UMAC and RGMII block when link up
 30 */
 31void bcmgenet_mii_setup(struct net_device *dev)
 32{
 33	struct bcmgenet_priv *priv = netdev_priv(dev);
 34	struct phy_device *phydev = dev->phydev;
 35	u32 reg, cmd_bits = 0;
 36	bool status_changed = false;
 37
 38	if (priv->old_link != phydev->link) {
 39		status_changed = true;
 40		priv->old_link = phydev->link;
 41	}
 42
 43	if (phydev->link) {
 44		/* check speed/duplex/pause changes */
 45		if (priv->old_speed != phydev->speed) {
 46			status_changed = true;
 47			priv->old_speed = phydev->speed;
 48		}
 49
 50		if (priv->old_duplex != phydev->duplex) {
 51			status_changed = true;
 52			priv->old_duplex = phydev->duplex;
 53		}
 54
 55		if (priv->old_pause != phydev->pause) {
 56			status_changed = true;
 57			priv->old_pause = phydev->pause;
 58		}
 59
 60		/* done if nothing has changed */
 61		if (!status_changed)
 62			return;
 63
 64		/* speed */
 65		if (phydev->speed == SPEED_1000)
 66			cmd_bits = UMAC_SPEED_1000;
 67		else if (phydev->speed == SPEED_100)
 68			cmd_bits = UMAC_SPEED_100;
 69		else
 70			cmd_bits = UMAC_SPEED_10;
 71		cmd_bits <<= CMD_SPEED_SHIFT;
 72
 73		/* duplex */
 74		if (phydev->duplex != DUPLEX_FULL)
 75			cmd_bits |= CMD_HD_EN;
 76
 77		/* pause capability */
 78		if (!phydev->pause)
 79			cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
 80
 81		/*
 82		 * Program UMAC and RGMII block based on established
 83		 * link speed, duplex, and pause. The speed set in
 84		 * umac->cmd tell RGMII block which clock to use for
 85		 * transmit -- 25MHz(100Mbps) or 125MHz(1Gbps).
 86		 * Receive clock is provided by the PHY.
 87		 */
 88		reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
 89		reg &= ~OOB_DISABLE;
 90		reg |= RGMII_LINK;
 91		bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
 92
 93		reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 94		reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
 95			       CMD_HD_EN |
 96			       CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
 97		reg |= cmd_bits;
 98		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 99	} else {
100		/* done if nothing has changed */
101		if (!status_changed)
102			return;
103
104		/* needed for MoCA fixed PHY to reflect correct link status */
105		netif_carrier_off(dev);
106	}
107
108	phy_print_status(phydev);
109}
110
111
112static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
113					  struct fixed_phy_status *status)
114{
115	struct bcmgenet_priv *priv;
116	u32 reg;
117
118	if (dev && dev->phydev && status) {
119		priv = netdev_priv(dev);
120		reg = bcmgenet_umac_readl(priv, UMAC_MODE);
121		status->link = !!(reg & MODE_LINK_STATUS);
122	}
123
124	return 0;
125}
126
127void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
128{
129	struct bcmgenet_priv *priv = netdev_priv(dev);
130	u32 reg = 0;
131
132	/* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
133	if (GENET_IS_V4(priv)) {
134		reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
135		if (enable) {
136			reg &= ~EXT_CK25_DIS;
137			bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
138			mdelay(1);
139
140			reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN);
141			reg |= EXT_GPHY_RESET;
142			bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
143			mdelay(1);
144
145			reg &= ~EXT_GPHY_RESET;
146		} else {
147			reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN |
148			       EXT_GPHY_RESET;
149			bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
150			mdelay(1);
151			reg |= EXT_CK25_DIS;
152		}
153		bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
154		udelay(60);
155	} else {
156		mdelay(1);
157	}
158}
159
160static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
161{
162	u32 reg;
163
164	if (!GENET_IS_V5(priv)) {
165		/* Speed settings are set in bcmgenet_mii_setup() */
166		reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
167		reg |= LED_ACT_SOURCE_MAC;
168		bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
169	}
170
171	if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
172		fixed_phy_set_link_update(priv->dev->phydev,
173					  bcmgenet_fixed_phy_link_update);
174}
175
176int bcmgenet_mii_config(struct net_device *dev, bool init)
177{
178	struct bcmgenet_priv *priv = netdev_priv(dev);
179	struct phy_device *phydev = dev->phydev;
180	struct device *kdev = &priv->pdev->dev;
181	const char *phy_name = NULL;
182	u32 id_mode_dis = 0;
183	u32 port_ctrl;
184	int bmcr = -1;
185	int ret;
186	u32 reg;
187
188	/* MAC clocking workaround during reset of umac state machines */
189	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
190	if (reg & CMD_SW_RESET) {
191		/* An MII PHY must be isolated to prevent TXC contention */
192		if (priv->phy_interface == PHY_INTERFACE_MODE_MII) {
193			ret = phy_read(phydev, MII_BMCR);
194			if (ret >= 0) {
195				bmcr = ret;
196				ret = phy_write(phydev, MII_BMCR,
197						bmcr | BMCR_ISOLATE);
198			}
199			if (ret) {
200				netdev_err(dev, "failed to isolate PHY\n");
201				return ret;
202			}
203		}
204		/* Switch MAC clocking to RGMII generated clock */
205		bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
206		/* Ensure 5 clks with Rx disabled
207		 * followed by 5 clks with Reset asserted
208		 */
209		udelay(4);
210		reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN);
211		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
212		/* Ensure 5 more clocks before Rx is enabled */
213		udelay(2);
214	}
215
216	priv->ext_phy = !priv->internal_phy &&
217			(priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
218
219	switch (priv->phy_interface) {
220	case PHY_INTERFACE_MODE_INTERNAL:
221	case PHY_INTERFACE_MODE_MOCA:
222		/* Irrespective of the actually configured PHY speed (100 or
223		 * 1000) GENETv4 only has an internal GPHY so we will just end
224		 * up masking the Gigabit features from what we support, not
225		 * switching to the EPHY
226		 */
227		if (GENET_IS_V4(priv))
228			port_ctrl = PORT_MODE_INT_GPHY;
229		else
230			port_ctrl = PORT_MODE_INT_EPHY;
231
232		bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
233
234		if (priv->internal_phy) {
235			phy_name = "internal PHY";
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		phy_set_max_speed(phydev, SPEED_100);
245		bcmgenet_sys_writel(priv,
246				    PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
247		/* Restore the MII PHY after isolation */
248		if (bmcr >= 0)
249			phy_write(phydev, MII_BMCR, bmcr);
250		break;
251
252	case PHY_INTERFACE_MODE_REVMII:
253		phy_name = "external RvMII";
254		/* of_mdiobus_register took care of reading the 'max-speed'
255		 * PHY property for us, effectively limiting the PHY supported
256		 * capabilities, use that knowledge to also configure the
257		 * Reverse MII interface correctly.
258		 */
259		if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
260				      dev->phydev->supported))
261			port_ctrl = PORT_MODE_EXT_RVMII_50;
262		else
263			port_ctrl = PORT_MODE_EXT_RVMII_25;
264		bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
265		break;
266
267	case PHY_INTERFACE_MODE_RGMII:
268		/* RGMII_NO_ID: TXC transitions at the same time as TXD
269		 *		(requires PCB or receiver-side delay)
270		 * RGMII:	Add 2ns delay on TXC (90 degree shift)
271		 *
272		 * ID is implicitly disabled for 100Mbps (RG)MII operation.
273		 */
274		id_mode_dis = BIT(16);
275		/* fall through */
276	case PHY_INTERFACE_MODE_RGMII_TXID:
277		if (id_mode_dis)
278			phy_name = "external RGMII (no delay)";
279		else
280			phy_name = "external RGMII (TX delay)";
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	/* This is an external PHY (xMII), so we need to enable the RGMII
290	 * block for the interface to work
291	 */
292	if (priv->ext_phy) {
293		reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
294		reg |= id_mode_dis;
295		if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
296			reg |= RGMII_MODE_EN_V123;
297		else
298			reg |= RGMII_MODE_EN;
299		bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
300	}
301
302	if (init)
303		dev_info(kdev, "configuring instance for %s\n", phy_name);
304
305	return 0;
306}
307
308int bcmgenet_mii_probe(struct net_device *dev)
309{
310	struct bcmgenet_priv *priv = netdev_priv(dev);
311	struct device_node *dn = priv->pdev->dev.of_node;
312	struct phy_device *phydev;
313	u32 phy_flags = 0;
314	int ret;
315
316	/* Communicate the integrated PHY revision */
317	if (priv->internal_phy)
318		phy_flags = priv->gphy_rev;
319
320	/* Initialize link state variables that bcmgenet_mii_setup() uses */
321	priv->old_link = -1;
322	priv->old_speed = -1;
323	priv->old_duplex = -1;
324	priv->old_pause = -1;
325
326	if (dn) {
327		phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
328					phy_flags, priv->phy_interface);
329		if (!phydev) {
330			pr_err("could not attach to PHY\n");
331			return -ENODEV;
332		}
333	} else {
334		phydev = dev->phydev;
335		phydev->dev_flags = phy_flags;
336
337		ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
338					 priv->phy_interface);
339		if (ret) {
340			pr_err("could not attach to PHY\n");
341			return -ENODEV;
342		}
343	}
344
345	/* Configure port multiplexer based on what the probed PHY device since
346	 * reading the 'max-speed' property determines the maximum supported
347	 * PHY speed which is needed for bcmgenet_mii_config() to configure
348	 * things appropriately.
349	 */
350	ret = bcmgenet_mii_config(dev, true);
351	if (ret) {
352		phy_disconnect(dev->phydev);
353		return ret;
354	}
355
356	linkmode_copy(phydev->advertising, phydev->supported);
357
358	/* The internal PHY has its link interrupts routed to the
359	 * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
360	 * that prevents the signaling of link UP interrupts when
361	 * the link operates at 10Mbps, so fallback to polling for
362	 * those versions of GENET.
363	 */
364	if (priv->internal_phy && !GENET_IS_V5(priv))
365		dev->phydev->irq = PHY_IGNORE_INTERRUPT;
366
367	return 0;
368}
369
370static struct device_node *bcmgenet_mii_of_find_mdio(struct bcmgenet_priv *priv)
371{
372	struct device_node *dn = priv->pdev->dev.of_node;
373	struct device *kdev = &priv->pdev->dev;
374	char *compat;
375
376	compat = kasprintf(GFP_KERNEL, "brcm,genet-mdio-v%d", priv->version);
377	if (!compat)
378		return NULL;
379
380	priv->mdio_dn = of_get_compatible_child(dn, compat);
381	kfree(compat);
382	if (!priv->mdio_dn) {
383		dev_err(kdev, "unable to find MDIO bus node\n");
384		return NULL;
385	}
386
387	return priv->mdio_dn;
388}
389
390static void bcmgenet_mii_pdata_init(struct bcmgenet_priv *priv,
391				    struct unimac_mdio_pdata *ppd)
392{
393	struct device *kdev = &priv->pdev->dev;
394	struct bcmgenet_platform_data *pd = kdev->platform_data;
395
396	if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
397		/*
398		 * Internal or external PHY with MDIO access
399		 */
400		if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
401			ppd->phy_mask = 1 << pd->phy_address;
402		else
403			ppd->phy_mask = 0;
404	}
405}
406
407static int bcmgenet_mii_wait(void *wait_func_data)
408{
409	struct bcmgenet_priv *priv = wait_func_data;
410
411	wait_event_timeout(priv->wq,
412			   !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD)
413			   & MDIO_START_BUSY),
414			   HZ / 100);
415	return 0;
416}
417
418static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
419{
420	struct platform_device *pdev = priv->pdev;
421	struct bcmgenet_platform_data *pdata = pdev->dev.platform_data;
422	struct device_node *dn = pdev->dev.of_node;
423	struct unimac_mdio_pdata ppd;
424	struct platform_device *ppdev;
425	struct resource *pres, res;
426	int id, ret;
427
428	pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429	memset(&res, 0, sizeof(res));
430	memset(&ppd, 0, sizeof(ppd));
431
432	ppd.wait_func = bcmgenet_mii_wait;
433	ppd.wait_func_data = priv;
434	ppd.bus_name = "bcmgenet MII bus";
435
436	/* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
437	 * and is 2 * 32-bits word long, 8 bytes total.
438	 */
439	res.start = pres->start + GENET_UMAC_OFF + UMAC_MDIO_CMD;
440	res.end = res.start + 8;
441	res.flags = IORESOURCE_MEM;
442
443	if (dn)
444		id = of_alias_get_id(dn, "eth");
445	else
446		id = pdev->id;
447
448	ppdev = platform_device_alloc(UNIMAC_MDIO_DRV_NAME, id);
449	if (!ppdev)
450		return -ENOMEM;
451
452	/* Retain this platform_device pointer for later cleanup */
453	priv->mii_pdev = ppdev;
454	ppdev->dev.parent = &pdev->dev;
455	ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
456	if (pdata)
457		bcmgenet_mii_pdata_init(priv, &ppd);
458
459	ret = platform_device_add_resources(ppdev, &res, 1);
460	if (ret)
461		goto out;
462
463	ret = platform_device_add_data(ppdev, &ppd, sizeof(ppd));
464	if (ret)
465		goto out;
466
467	ret = platform_device_add(ppdev);
468	if (ret)
469		goto out;
470
471	return 0;
472out:
473	platform_device_put(ppdev);
474	return ret;
475}
476
477static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
478{
479	struct device_node *dn = priv->pdev->dev.of_node;
480	struct device *kdev = &priv->pdev->dev;
481	struct phy_device *phydev;
482	int phy_mode;
483	int ret;
484
485	/* Fetch the PHY phandle */
486	priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0);
487
488	/* In the case of a fixed PHY, the DT node associated
489	 * to the PHY is the Ethernet MAC DT node.
490	 */
491	if (!priv->phy_dn && of_phy_is_fixed_link(dn)) {
492		ret = of_phy_register_fixed_link(dn);
493		if (ret)
494			return ret;
495
496		priv->phy_dn = of_node_get(dn);
497	}
498
499	/* Get the link mode */
500	phy_mode = of_get_phy_mode(dn);
501	if (phy_mode < 0) {
502		dev_err(kdev, "invalid PHY mode property\n");
503		return phy_mode;
504	}
505
506	priv->phy_interface = phy_mode;
507
508	/* We need to specifically look up whether this PHY interface is internal
509	 * or not *before* we even try to probe the PHY driver over MDIO as we
510	 * may have shut down the internal PHY for power saving purposes.
511	 */
512	if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
513		priv->internal_phy = true;
514
515	/* Make sure we initialize MoCA PHYs with a link down */
516	if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
517		phydev = of_phy_find_device(dn);
518		if (phydev) {
519			phydev->link = 0;
520			put_device(&phydev->mdio.dev);
521		}
522	}
523
524	return 0;
525}
526
527static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
528{
529	struct device *kdev = &priv->pdev->dev;
530	struct bcmgenet_platform_data *pd = kdev->platform_data;
531	char phy_name[MII_BUS_ID_SIZE + 3];
532	char mdio_bus_id[MII_BUS_ID_SIZE];
533	struct phy_device *phydev;
534
535	snprintf(mdio_bus_id, MII_BUS_ID_SIZE, "%s-%d",
536		 UNIMAC_MDIO_DRV_NAME, priv->pdev->id);
537
538	if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
539		snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
540			 mdio_bus_id, pd->phy_address);
541
542		/*
543		 * Internal or external PHY with MDIO access
544		 */
545		phydev = phy_attach(priv->dev, phy_name, pd->phy_interface);
546		if (!phydev) {
547			dev_err(kdev, "failed to register PHY device\n");
548			return -ENODEV;
549		}
550	} else {
551		/*
552		 * MoCA port or no MDIO access.
553		 * Use fixed PHY to represent the link layer.
554		 */
555		struct fixed_phy_status fphy_status = {
556			.link = 1,
557			.speed = pd->phy_speed,
558			.duplex = pd->phy_duplex,
559			.pause = 0,
560			.asym_pause = 0,
561		};
562
563		phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
564		if (!phydev || IS_ERR(phydev)) {
565			dev_err(kdev, "failed to register fixed PHY device\n");
566			return -ENODEV;
567		}
568
569		/* Make sure we initialize MoCA PHYs with a link down */
570		phydev->link = 0;
571
572	}
573
574	priv->phy_interface = pd->phy_interface;
575
576	return 0;
577}
578
579static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
580{
581	struct device_node *dn = priv->pdev->dev.of_node;
582
583	if (dn)
584		return bcmgenet_mii_of_init(priv);
585	else
586		return bcmgenet_mii_pd_init(priv);
587}
588
589int bcmgenet_mii_init(struct net_device *dev)
590{
591	struct bcmgenet_priv *priv = netdev_priv(dev);
592	int ret;
593
594	ret = bcmgenet_mii_register(priv);
595	if (ret)
596		return ret;
597
598	ret = bcmgenet_mii_bus_init(priv);
599	if (ret)
600		goto out;
601
602	return 0;
603
604out:
605	bcmgenet_mii_exit(dev);
606	return ret;
607}
608
609void bcmgenet_mii_exit(struct net_device *dev)
610{
611	struct bcmgenet_priv *priv = netdev_priv(dev);
612	struct device_node *dn = priv->pdev->dev.of_node;
613
614	if (of_phy_is_fixed_link(dn))
615		of_phy_deregister_fixed_link(dn);
616	of_node_put(priv->phy_dn);
617	platform_device_unregister(priv->mii_pdev);
618}