Skip to content

Commit 8d88c6e

Browse files
Petri Gyntherdavem330
authored andcommitted
net: bcmgenet: enable MoCA link state change detection
Currently, MoCA fixed PHYs are always in link-up state, regardless of whether the link is actually up or not. Add code to properly detect MoCA link state changes and to reflect the new state in MoCA fixed PHY. Only GENET V3 and V4 MACs are capable of detecting MoCA link state changes. The code works as follows: 1. GENET MAC detects MoCA link state change and issues UMAC_IRQ_LINK_UP or UMAC_IRQ_LINK_DOWN interrupt. 2. Link up/down interrupt is processed in bcmgenet_irq_task(), which calls phy_mac_interrupt(). 3. phy_mac_interrupt() updates the fixed PHY phydev->link and kicks the PHY state machine. 4. PHY state machine proceeds to read the fixed PHY link status register. 5. When the fixed PHY link status register is being read, the new function bcmgenet_fixed_phy_link_update() gets called. It copies the fixed PHY phydev->link value to the fixed PHY status->link. 6. PHY state machine receives the new link state of the fixed PHY. 7. MoCA fixed PHY link state now correctly reflects the real MoCA hardware link state. Signed-off-by: Petri Gynther <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 687908c commit 8d88c6e

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,9 @@ static int init_umac(struct bcmgenet_priv *priv)
17341734
} else if (priv->ext_phy) {
17351735
int0_enable |= UMAC_IRQ_LINK_EVENT;
17361736
} else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
1737+
if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
1738+
int0_enable |= UMAC_IRQ_LINK_EVENT;
1739+
17371740
reg = bcmgenet_bp_mc_get(priv);
17381741
reg |= BIT(priv->hw_params->bp_in_en_shift);
17391742

@@ -2926,7 +2929,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
29262929
.rdma_offset = 0x10000,
29272930
.tdma_offset = 0x11000,
29282931
.words_per_bd = 2,
2929-
.flags = GENET_HAS_EXT | GENET_HAS_MDIO_INTR,
2932+
.flags = GENET_HAS_EXT | GENET_HAS_MDIO_INTR |
2933+
GENET_HAS_MOCA_LINK_DET,
29302934
},
29312935
[GENET_V4] = {
29322936
.tx_queues = 4,
@@ -2944,7 +2948,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
29442948
.rdma_offset = 0x2000,
29452949
.tdma_offset = 0x4000,
29462950
.words_per_bd = 3,
2947-
.flags = GENET_HAS_40BITS | GENET_HAS_EXT | GENET_HAS_MDIO_INTR,
2951+
.flags = GENET_HAS_40BITS | GENET_HAS_EXT |
2952+
GENET_HAS_MDIO_INTR | GENET_HAS_MOCA_LINK_DET,
29482953
},
29492954
};
29502955

drivers/net/ethernet/broadcom/genet/bcmgenet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ enum bcmgenet_version {
508508
#define GENET_HAS_40BITS (1 << 0)
509509
#define GENET_HAS_EXT (1 << 1)
510510
#define GENET_HAS_MDIO_INTR (1 << 2)
511+
#define GENET_HAS_MOCA_LINK_DET (1 << 3)
511512

512513
/* BCMGENET hardware parameters, keep this structure nicely aligned
513514
* since it is going to be used in hot paths

drivers/net/ethernet/broadcom/genet/bcmmii.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,15 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
462462
return 0;
463463
}
464464

465+
static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
466+
struct fixed_phy_status *status)
467+
{
468+
if (dev && dev->phydev && status)
469+
status->link = dev->phydev->link;
470+
471+
return 0;
472+
}
473+
465474
static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
466475
{
467476
struct device *kdev = &priv->pdev->dev;
@@ -513,6 +522,13 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
513522
dev_err(kdev, "failed to register fixed PHY device\n");
514523
return -ENODEV;
515524
}
525+
526+
if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) {
527+
ret = fixed_phy_set_link_update(
528+
phydev, bcmgenet_fixed_phy_link_update);
529+
if (!ret)
530+
phydev->link = 0;
531+
}
516532
}
517533

518534
priv->phydev = phydev;

0 commit comments

Comments
 (0)