2 * Broadcom GENET MDIO routines
4 * Copyright (c) 2014-2017 Broadcom
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.
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>
24 #include <linux/of_net.h>
25 #include <linux/of_mdio.h>
26 #include <linux/platform_data/bcmgenet.h>
27 #include <linux/platform_data/mdio-bcm-unimac.h>
31 /* setup netdev link state when PHY link status change and
32 * update UMAC and RGMII block when link up
34 void bcmgenet_mii_setup(struct net_device
*dev
)
36 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
37 struct phy_device
*phydev
= dev
->phydev
;
38 u32 reg
, cmd_bits
= 0;
39 bool status_changed
= false;
41 if (priv
->old_link
!= phydev
->link
) {
42 status_changed
= true;
43 priv
->old_link
= phydev
->link
;
47 /* check speed/duplex/pause changes */
48 if (priv
->old_speed
!= phydev
->speed
) {
49 status_changed
= true;
50 priv
->old_speed
= phydev
->speed
;
53 if (priv
->old_duplex
!= phydev
->duplex
) {
54 status_changed
= true;
55 priv
->old_duplex
= phydev
->duplex
;
58 if (priv
->old_pause
!= phydev
->pause
) {
59 status_changed
= true;
60 priv
->old_pause
= phydev
->pause
;
63 /* done if nothing has changed */
68 if (phydev
->speed
== SPEED_1000
)
69 cmd_bits
= UMAC_SPEED_1000
;
70 else if (phydev
->speed
== SPEED_100
)
71 cmd_bits
= UMAC_SPEED_100
;
73 cmd_bits
= UMAC_SPEED_10
;
74 cmd_bits
<<= CMD_SPEED_SHIFT
;
77 if (phydev
->duplex
!= DUPLEX_FULL
)
78 cmd_bits
|= CMD_HD_EN
;
80 /* pause capability */
82 cmd_bits
|= CMD_RX_PAUSE_IGNORE
| CMD_TX_PAUSE_IGNORE
;
85 * Program UMAC and RGMII block based on established
86 * link speed, duplex, and pause. The speed set in
87 * umac->cmd tell RGMII block which clock to use for
88 * transmit -- 25MHz(100Mbps) or 125MHz(1Gbps).
89 * Receive clock is provided by the PHY.
91 reg
= bcmgenet_ext_readl(priv
, EXT_RGMII_OOB_CTRL
);
94 bcmgenet_ext_writel(priv
, reg
, EXT_RGMII_OOB_CTRL
);
96 reg
= bcmgenet_umac_readl(priv
, UMAC_CMD
);
97 reg
&= ~((CMD_SPEED_MASK
<< CMD_SPEED_SHIFT
) |
99 CMD_RX_PAUSE_IGNORE
| CMD_TX_PAUSE_IGNORE
);
101 bcmgenet_umac_writel(priv
, reg
, UMAC_CMD
);
103 /* done if nothing has changed */
107 /* needed for MoCA fixed PHY to reflect correct link status */
108 netif_carrier_off(dev
);
111 phy_print_status(phydev
);
115 static int bcmgenet_fixed_phy_link_update(struct net_device
*dev
,
116 struct fixed_phy_status
*status
)
118 if (dev
&& dev
->phydev
&& status
)
119 status
->link
= dev
->phydev
->link
;
124 void bcmgenet_phy_power_set(struct net_device
*dev
, bool enable
)
126 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
129 /* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
130 if (GENET_IS_V4(priv
)) {
131 reg
= bcmgenet_ext_readl(priv
, EXT_GPHY_CTRL
);
133 reg
&= ~EXT_CK25_DIS
;
134 bcmgenet_ext_writel(priv
, reg
, EXT_GPHY_CTRL
);
137 reg
&= ~(EXT_CFG_IDDQ_BIAS
| EXT_CFG_PWR_DOWN
);
138 reg
|= EXT_GPHY_RESET
;
139 bcmgenet_ext_writel(priv
, reg
, EXT_GPHY_CTRL
);
142 reg
&= ~EXT_GPHY_RESET
;
144 reg
|= EXT_CFG_IDDQ_BIAS
| EXT_CFG_PWR_DOWN
|
146 bcmgenet_ext_writel(priv
, reg
, EXT_GPHY_CTRL
);
150 bcmgenet_ext_writel(priv
, reg
, EXT_GPHY_CTRL
);
157 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv
*priv
)
161 if (!GENET_IS_V5(priv
)) {
162 /* Speed settings are set in bcmgenet_mii_setup() */
163 reg
= bcmgenet_sys_readl(priv
, SYS_PORT_CTRL
);
164 reg
|= LED_ACT_SOURCE_MAC
;
165 bcmgenet_sys_writel(priv
, reg
, SYS_PORT_CTRL
);
168 if (priv
->hw_params
->flags
& GENET_HAS_MOCA_LINK_DET
)
169 fixed_phy_set_link_update(priv
->dev
->phydev
,
170 bcmgenet_fixed_phy_link_update
);
173 int bcmgenet_mii_config(struct net_device
*dev
, bool init
)
175 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
176 struct phy_device
*phydev
= dev
->phydev
;
177 struct device
*kdev
= &priv
->pdev
->dev
;
178 const char *phy_name
= NULL
;
183 priv
->ext_phy
= !priv
->internal_phy
&&
184 (priv
->phy_interface
!= PHY_INTERFACE_MODE_MOCA
);
186 switch (priv
->phy_interface
) {
187 case PHY_INTERFACE_MODE_INTERNAL
:
188 case PHY_INTERFACE_MODE_MOCA
:
189 /* Irrespective of the actually configured PHY speed (100 or
190 * 1000) GENETv4 only has an internal GPHY so we will just end
191 * up masking the Gigabit features from what we support, not
192 * switching to the EPHY
194 if (GENET_IS_V4(priv
))
195 port_ctrl
= PORT_MODE_INT_GPHY
;
197 port_ctrl
= PORT_MODE_INT_EPHY
;
199 bcmgenet_sys_writel(priv
, port_ctrl
, SYS_PORT_CTRL
);
201 if (priv
->internal_phy
) {
202 phy_name
= "internal PHY";
203 } else if (priv
->phy_interface
== PHY_INTERFACE_MODE_MOCA
) {
205 bcmgenet_moca_phy_setup(priv
);
209 case PHY_INTERFACE_MODE_MII
:
210 phy_name
= "external MII";
211 phydev
->supported
&= PHY_BASIC_FEATURES
;
212 bcmgenet_sys_writel(priv
,
213 PORT_MODE_EXT_EPHY
, SYS_PORT_CTRL
);
216 case PHY_INTERFACE_MODE_REVMII
:
217 phy_name
= "external RvMII";
218 /* of_mdiobus_register took care of reading the 'max-speed'
219 * PHY property for us, effectively limiting the PHY supported
220 * capabilities, use that knowledge to also configure the
221 * Reverse MII interface correctly.
223 if ((dev
->phydev
->supported
& PHY_BASIC_FEATURES
) ==
225 port_ctrl
= PORT_MODE_EXT_RVMII_25
;
227 port_ctrl
= PORT_MODE_EXT_RVMII_50
;
228 bcmgenet_sys_writel(priv
, port_ctrl
, SYS_PORT_CTRL
);
231 case PHY_INTERFACE_MODE_RGMII
:
232 /* RGMII_NO_ID: TXC transitions at the same time as TXD
233 * (requires PCB or receiver-side delay)
234 * RGMII: Add 2ns delay on TXC (90 degree shift)
236 * ID is implicitly disabled for 100Mbps (RG)MII operation.
238 id_mode_dis
= BIT(16);
240 case PHY_INTERFACE_MODE_RGMII_TXID
:
242 phy_name
= "external RGMII (no delay)";
244 phy_name
= "external RGMII (TX delay)";
245 bcmgenet_sys_writel(priv
,
246 PORT_MODE_EXT_GPHY
, SYS_PORT_CTRL
);
249 dev_err(kdev
, "unknown phy mode: %d\n", priv
->phy_interface
);
253 /* This is an external PHY (xMII), so we need to enable the RGMII
254 * block for the interface to work
257 reg
= bcmgenet_ext_readl(priv
, EXT_RGMII_OOB_CTRL
);
258 reg
|= RGMII_MODE_EN
| id_mode_dis
;
259 bcmgenet_ext_writel(priv
, reg
, EXT_RGMII_OOB_CTRL
);
263 dev_info(kdev
, "configuring instance for %s\n", phy_name
);
268 int bcmgenet_mii_probe(struct net_device
*dev
)
270 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
271 struct device_node
*dn
= priv
->pdev
->dev
.of_node
;
272 struct phy_device
*phydev
;
276 /* Communicate the integrated PHY revision */
277 phy_flags
= priv
->gphy_rev
;
279 /* Initialize link state variables that bcmgenet_mii_setup() uses */
281 priv
->old_speed
= -1;
282 priv
->old_duplex
= -1;
283 priv
->old_pause
= -1;
286 phydev
= of_phy_connect(dev
, priv
->phy_dn
, bcmgenet_mii_setup
,
287 phy_flags
, priv
->phy_interface
);
289 pr_err("could not attach to PHY\n");
293 phydev
= dev
->phydev
;
294 phydev
->dev_flags
= phy_flags
;
296 ret
= phy_connect_direct(dev
, phydev
, bcmgenet_mii_setup
,
297 priv
->phy_interface
);
299 pr_err("could not attach to PHY\n");
304 /* Configure port multiplexer based on what the probed PHY device since
305 * reading the 'max-speed' property determines the maximum supported
306 * PHY speed which is needed for bcmgenet_mii_config() to configure
307 * things appropriately.
309 ret
= bcmgenet_mii_config(dev
, true);
311 phy_disconnect(dev
->phydev
);
315 phydev
->advertising
= phydev
->supported
;
317 /* The internal PHY has its link interrupts routed to the
320 if (priv
->internal_phy
)
321 dev
->phydev
->irq
= PHY_IGNORE_INTERRUPT
;
326 static struct device_node
*bcmgenet_mii_of_find_mdio(struct bcmgenet_priv
*priv
)
328 struct device_node
*dn
= priv
->pdev
->dev
.of_node
;
329 struct device
*kdev
= &priv
->pdev
->dev
;
332 compat
= kasprintf(GFP_KERNEL
, "brcm,genet-mdio-v%d", priv
->version
);
336 priv
->mdio_dn
= of_find_compatible_node(dn
, NULL
, compat
);
338 if (!priv
->mdio_dn
) {
339 dev_err(kdev
, "unable to find MDIO bus node\n");
343 return priv
->mdio_dn
;
346 static void bcmgenet_mii_pdata_init(struct bcmgenet_priv
*priv
,
347 struct unimac_mdio_pdata
*ppd
)
349 struct device
*kdev
= &priv
->pdev
->dev
;
350 struct bcmgenet_platform_data
*pd
= kdev
->platform_data
;
352 if (pd
->phy_interface
!= PHY_INTERFACE_MODE_MOCA
&& pd
->mdio_enabled
) {
354 * Internal or external PHY with MDIO access
356 if (pd
->phy_address
>= 0 && pd
->phy_address
< PHY_MAX_ADDR
)
357 ppd
->phy_mask
= 1 << pd
->phy_address
;
363 static int bcmgenet_mii_wait(void *wait_func_data
)
365 struct bcmgenet_priv
*priv
= wait_func_data
;
367 wait_event_timeout(priv
->wq
,
368 !(bcmgenet_umac_readl(priv
, UMAC_MDIO_CMD
)
374 static int bcmgenet_mii_register(struct bcmgenet_priv
*priv
)
376 struct platform_device
*pdev
= priv
->pdev
;
377 struct bcmgenet_platform_data
*pdata
= pdev
->dev
.platform_data
;
378 struct device_node
*dn
= pdev
->dev
.of_node
;
379 struct unimac_mdio_pdata ppd
;
380 struct platform_device
*ppdev
;
381 struct resource
*pres
, res
;
384 pres
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
385 memset(&res
, 0, sizeof(res
));
386 memset(&ppd
, 0, sizeof(ppd
));
388 ppd
.wait_func
= bcmgenet_mii_wait
;
389 ppd
.wait_func_data
= priv
;
390 ppd
.bus_name
= "bcmgenet MII bus";
392 /* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
393 * and is 2 * 32-bits word long, 8 bytes total.
395 res
.start
= pres
->start
+ GENET_UMAC_OFF
+ UMAC_MDIO_CMD
;
396 res
.end
= res
.start
+ 8;
397 res
.flags
= IORESOURCE_MEM
;
400 id
= of_alias_get_id(dn
, "eth");
404 ppdev
= platform_device_alloc(UNIMAC_MDIO_DRV_NAME
, id
);
408 /* Retain this platform_device pointer for later cleanup */
409 priv
->mii_pdev
= ppdev
;
410 ppdev
->dev
.parent
= &pdev
->dev
;
411 ppdev
->dev
.of_node
= bcmgenet_mii_of_find_mdio(priv
);
413 bcmgenet_mii_pdata_init(priv
, &ppd
);
415 ret
= platform_device_add_resources(ppdev
, &res
, 1);
419 ret
= platform_device_add_data(ppdev
, &ppd
, sizeof(ppd
));
423 ret
= platform_device_add(ppdev
);
429 platform_device_put(ppdev
);
433 static int bcmgenet_mii_of_init(struct bcmgenet_priv
*priv
)
435 struct device_node
*dn
= priv
->pdev
->dev
.of_node
;
436 struct device
*kdev
= &priv
->pdev
->dev
;
437 struct phy_device
*phydev
;
441 /* Fetch the PHY phandle */
442 priv
->phy_dn
= of_parse_phandle(dn
, "phy-handle", 0);
444 /* In the case of a fixed PHY, the DT node associated
445 * to the PHY is the Ethernet MAC DT node.
447 if (!priv
->phy_dn
&& of_phy_is_fixed_link(dn
)) {
448 ret
= of_phy_register_fixed_link(dn
);
452 priv
->phy_dn
= of_node_get(dn
);
455 /* Get the link mode */
456 phy_mode
= of_get_phy_mode(dn
);
458 dev_err(kdev
, "invalid PHY mode property\n");
462 priv
->phy_interface
= phy_mode
;
464 /* We need to specifically look up whether this PHY interface is internal
465 * or not *before* we even try to probe the PHY driver over MDIO as we
466 * may have shut down the internal PHY for power saving purposes.
468 if (priv
->phy_interface
== PHY_INTERFACE_MODE_INTERNAL
)
469 priv
->internal_phy
= true;
471 /* Make sure we initialize MoCA PHYs with a link down */
472 if (phy_mode
== PHY_INTERFACE_MODE_MOCA
) {
473 phydev
= of_phy_find_device(dn
);
476 put_device(&phydev
->mdio
.dev
);
483 static int bcmgenet_mii_pd_init(struct bcmgenet_priv
*priv
)
485 struct device
*kdev
= &priv
->pdev
->dev
;
486 struct bcmgenet_platform_data
*pd
= kdev
->platform_data
;
487 char phy_name
[MII_BUS_ID_SIZE
+ 3];
488 char mdio_bus_id
[MII_BUS_ID_SIZE
];
489 struct phy_device
*phydev
;
491 snprintf(mdio_bus_id
, MII_BUS_ID_SIZE
, "%s-%d",
492 UNIMAC_MDIO_DRV_NAME
, priv
->pdev
->id
);
494 if (pd
->phy_interface
!= PHY_INTERFACE_MODE_MOCA
&& pd
->mdio_enabled
) {
495 snprintf(phy_name
, MII_BUS_ID_SIZE
, PHY_ID_FMT
,
496 mdio_bus_id
, pd
->phy_address
);
499 * Internal or external PHY with MDIO access
501 phydev
= phy_attach(priv
->dev
, phy_name
, pd
->phy_interface
);
503 dev_err(kdev
, "failed to register PHY device\n");
508 * MoCA port or no MDIO access.
509 * Use fixed PHY to represent the link layer.
511 struct fixed_phy_status fphy_status
= {
513 .speed
= pd
->phy_speed
,
514 .duplex
= pd
->phy_duplex
,
519 phydev
= fixed_phy_register(PHY_POLL
, &fphy_status
, -1, NULL
);
520 if (!phydev
|| IS_ERR(phydev
)) {
521 dev_err(kdev
, "failed to register fixed PHY device\n");
525 /* Make sure we initialize MoCA PHYs with a link down */
530 priv
->phy_interface
= pd
->phy_interface
;
535 static int bcmgenet_mii_bus_init(struct bcmgenet_priv
*priv
)
537 struct device_node
*dn
= priv
->pdev
->dev
.of_node
;
540 return bcmgenet_mii_of_init(priv
);
542 return bcmgenet_mii_pd_init(priv
);
545 int bcmgenet_mii_init(struct net_device
*dev
)
547 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
550 ret
= bcmgenet_mii_register(priv
);
554 ret
= bcmgenet_mii_bus_init(priv
);
561 bcmgenet_mii_exit(dev
);
565 void bcmgenet_mii_exit(struct net_device
*dev
)
567 struct bcmgenet_priv
*priv
= netdev_priv(dev
);
568 struct device_node
*dn
= priv
->pdev
->dev
.of_node
;
570 if (of_phy_is_fixed_link(dn
))
571 of_phy_deregister_fixed_link(dn
);
572 of_node_put(priv
->phy_dn
);
573 platform_device_unregister(priv
->mii_pdev
);