aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorPetri Gynther <pgynther@google.com>2015-04-01 03:40:00 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-01 13:40:18 -0400
commit8d88c6ebb34c3e54debe81e9b0d81b60411f8179 (patch)
tree5216318b9e39df95a55d86563ce5270c1f203f84 /drivers/net/ethernet
parent687908c2b6498130172286f3387ec0eb0a20080e (diff)
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 <pgynther@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c9
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h1
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c16
3 files changed, 24 insertions, 2 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index f7855a61e7ad..6043734ea613 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1734,6 +1734,9 @@ static int init_umac(struct bcmgenet_priv *priv)
1734 } else if (priv->ext_phy) { 1734 } else if (priv->ext_phy) {
1735 int0_enable |= UMAC_IRQ_LINK_EVENT; 1735 int0_enable |= UMAC_IRQ_LINK_EVENT;
1736 } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { 1736 } 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
1737 reg = bcmgenet_bp_mc_get(priv); 1740 reg = bcmgenet_bp_mc_get(priv);
1738 reg |= BIT(priv->hw_params->bp_in_en_shift); 1741 reg |= BIT(priv->hw_params->bp_in_en_shift);
1739 1742
@@ -2926,7 +2929,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
2926 .rdma_offset = 0x10000, 2929 .rdma_offset = 0x10000,
2927 .tdma_offset = 0x11000, 2930 .tdma_offset = 0x11000,
2928 .words_per_bd = 2, 2931 .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,
2930 }, 2934 },
2931 [GENET_V4] = { 2935 [GENET_V4] = {
2932 .tx_queues = 4, 2936 .tx_queues = 4,
@@ -2944,7 +2948,8 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
2944 .rdma_offset = 0x2000, 2948 .rdma_offset = 0x2000,
2945 .tdma_offset = 0x4000, 2949 .tdma_offset = 0x4000,
2946 .words_per_bd = 3, 2950 .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,
2948 }, 2953 },
2949}; 2954};
2950 2955
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index ddaa40cb0f21..6f2887a5e0be 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -508,6 +508,7 @@ enum bcmgenet_version {
508#define GENET_HAS_40BITS (1 << 0) 508#define GENET_HAS_40BITS (1 << 0)
509#define GENET_HAS_EXT (1 << 1) 509#define GENET_HAS_EXT (1 << 1)
510#define GENET_HAS_MDIO_INTR (1 << 2) 510#define GENET_HAS_MDIO_INTR (1 << 2)
511#define GENET_HAS_MOCA_LINK_DET (1 << 3)
511 512
512/* BCMGENET hardware parameters, keep this structure nicely aligned 513/* BCMGENET hardware parameters, keep this structure nicely aligned
513 * since it is going to be used in hot paths 514 * since it is going to be used in hot paths
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 6d3b66a103cc..e7651b3c6c57 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -462,6 +462,15 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
462 return 0; 462 return 0;
463} 463}
464 464
465static 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
465static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) 474static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
466{ 475{
467 struct device *kdev = &priv->pdev->dev; 476 struct device *kdev = &priv->pdev->dev;
@@ -513,6 +522,13 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
513 dev_err(kdev, "failed to register fixed PHY device\n"); 522 dev_err(kdev, "failed to register fixed PHY device\n");
514 return -ENODEV; 523 return -ENODEV;
515 } 524 }
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 }
516 } 532 }
517 533
518 priv->phydev = phydev; 534 priv->phydev = phydev;