net: bcmgenet: add support for the GENETv5 hardware
This commit adds support for the GENETv5 implementation. The GENETv5 reports a major version of 6 instead of 5 so compensate for this when verifying the configuration of the driver. Also the EPHY revision is now contained in the MDIO registers of the PHY so the EPHY revision of 0 in GENET_VER_FMT is expected for GENETv5. Signed-off-by: Doug Berger <opendmb@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0ce5aa1d6c
commit
421380856d
|
@ -1011,8 +1011,17 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv,
|
|||
/* Power down LED */
|
||||
if (priv->hw_params->flags & GENET_HAS_EXT) {
|
||||
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
|
||||
reg |= (EXT_PWR_DOWN_PHY |
|
||||
EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS);
|
||||
if (GENET_IS_V5(priv))
|
||||
reg |= EXT_PWR_DOWN_PHY_EN |
|
||||
EXT_PWR_DOWN_PHY_RD |
|
||||
EXT_PWR_DOWN_PHY_SD |
|
||||
EXT_PWR_DOWN_PHY_RX |
|
||||
EXT_PWR_DOWN_PHY_TX |
|
||||
EXT_IDDQ_GLBL_PWR;
|
||||
else
|
||||
reg |= EXT_PWR_DOWN_PHY;
|
||||
|
||||
reg |= (EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS);
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
|
||||
bcmgenet_phy_power_set(priv->dev, false);
|
||||
|
@ -1037,12 +1046,34 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
|
|||
|
||||
switch (mode) {
|
||||
case GENET_POWER_PASSIVE:
|
||||
reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_PHY |
|
||||
EXT_PWR_DOWN_BIAS);
|
||||
/* fallthrough */
|
||||
reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS);
|
||||
if (GENET_IS_V5(priv)) {
|
||||
reg &= ~(EXT_PWR_DOWN_PHY_EN |
|
||||
EXT_PWR_DOWN_PHY_RD |
|
||||
EXT_PWR_DOWN_PHY_SD |
|
||||
EXT_PWR_DOWN_PHY_RX |
|
||||
EXT_PWR_DOWN_PHY_TX |
|
||||
EXT_IDDQ_GLBL_PWR);
|
||||
reg |= EXT_PHY_RESET;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
mdelay(1);
|
||||
|
||||
reg &= ~EXT_PHY_RESET;
|
||||
} else {
|
||||
reg &= ~EXT_PWR_DOWN_PHY;
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
}
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
bcmgenet_phy_power_set(priv->dev, true);
|
||||
bcmgenet_mii_reset(priv->dev);
|
||||
break;
|
||||
|
||||
case GENET_POWER_CABLE_SENSE:
|
||||
/* enable APD */
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
if (!GENET_IS_V5(priv)) {
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
}
|
||||
break;
|
||||
case GENET_POWER_WOL_MAGIC:
|
||||
bcmgenet_wol_power_up_cfg(priv, mode);
|
||||
|
@ -1050,12 +1081,6 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
if (mode == GENET_POWER_PASSIVE) {
|
||||
bcmgenet_phy_power_set(priv->dev, true);
|
||||
bcmgenet_mii_reset(priv->dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* ioctl handle special commands that are not present in ethtool. */
|
||||
|
@ -3101,6 +3126,25 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
|
|||
.flags = GENET_HAS_40BITS | GENET_HAS_EXT |
|
||||
GENET_HAS_MDIO_INTR | GENET_HAS_MOCA_LINK_DET,
|
||||
},
|
||||
[GENET_V5] = {
|
||||
.tx_queues = 4,
|
||||
.tx_bds_per_q = 32,
|
||||
.rx_queues = 0,
|
||||
.rx_bds_per_q = 0,
|
||||
.bp_in_en_shift = 17,
|
||||
.bp_in_mask = 0x1ffff,
|
||||
.hfb_filter_cnt = 48,
|
||||
.hfb_filter_size = 128,
|
||||
.qtag_mask = 0x3F,
|
||||
.tbuf_offset = 0x0600,
|
||||
.hfb_offset = 0x8000,
|
||||
.hfb_reg_offset = 0xfc00,
|
||||
.rdma_offset = 0x2000,
|
||||
.tdma_offset = 0x4000,
|
||||
.words_per_bd = 3,
|
||||
.flags = GENET_HAS_40BITS | GENET_HAS_EXT |
|
||||
GENET_HAS_MDIO_INTR | GENET_HAS_MOCA_LINK_DET,
|
||||
},
|
||||
};
|
||||
|
||||
/* Infer hardware parameters from the detected GENET version */
|
||||
|
@ -3111,7 +3155,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
|
|||
u8 major;
|
||||
u16 gphy_rev;
|
||||
|
||||
if (GENET_IS_V4(priv)) {
|
||||
if (GENET_IS_V5(priv) || GENET_IS_V4(priv)) {
|
||||
bcmgenet_dma_regs = bcmgenet_dma_regs_v3plus;
|
||||
genet_dma_ring_regs = genet_dma_ring_regs_v4;
|
||||
priv->dma_rx_chk_bit = DMA_RX_CHK_V3PLUS;
|
||||
|
@ -3136,7 +3180,9 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
|
|||
/* Read GENET HW version */
|
||||
reg = bcmgenet_sys_readl(priv, SYS_REV_CTRL);
|
||||
major = (reg >> 24 & 0x0f);
|
||||
if (major == 5)
|
||||
if (major == 6)
|
||||
major = 5;
|
||||
else if (major == 5)
|
||||
major = 4;
|
||||
else if (major == 0)
|
||||
major = 1;
|
||||
|
@ -3164,16 +3210,22 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
|
|||
*/
|
||||
gphy_rev = reg & 0xffff;
|
||||
|
||||
if (GENET_IS_V5(priv)) {
|
||||
/* The EPHY revision should come from the MDIO registers of
|
||||
* the PHY not from GENET.
|
||||
*/
|
||||
if (gphy_rev != 0) {
|
||||
pr_warn("GENET is reporting EPHY revision: 0x%04x\n",
|
||||
gphy_rev);
|
||||
}
|
||||
/* This is the good old scheme, just GPHY major, no minor nor patch */
|
||||
if ((gphy_rev & 0xf0) != 0)
|
||||
} else if ((gphy_rev & 0xf0) != 0) {
|
||||
priv->gphy_rev = gphy_rev << 8;
|
||||
|
||||
/* This is the new scheme, GPHY major rolls over with 0x10 = rev G0 */
|
||||
else if ((gphy_rev & 0xff00) != 0)
|
||||
} else if ((gphy_rev & 0xff00) != 0) {
|
||||
priv->gphy_rev = gphy_rev;
|
||||
|
||||
/* This is reserved so should require special treatment */
|
||||
else if (gphy_rev == 0 || gphy_rev == 0x01ff) {
|
||||
} else if (gphy_rev == 0 || gphy_rev == 0x01ff) {
|
||||
pr_warn("Invalid GPHY revision detected: 0x%04x\n", gphy_rev);
|
||||
return;
|
||||
}
|
||||
|
@ -3206,6 +3258,7 @@ static const struct of_device_id bcmgenet_match[] = {
|
|||
{ .compatible = "brcm,genet-v2", .data = (void *)GENET_V2 },
|
||||
{ .compatible = "brcm,genet-v3", .data = (void *)GENET_V3 },
|
||||
{ .compatible = "brcm,genet-v4", .data = (void *)GENET_V4 },
|
||||
{ .compatible = "brcm,genet-v5", .data = (void *)GENET_V5 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcmgenet_match);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Broadcom Corporation
|
||||
* Copyright (c) 2014-2017 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -351,8 +351,14 @@ struct bcmgenet_mib_counters {
|
|||
#define EXT_PWR_DN_EN_LD (1 << 3)
|
||||
#define EXT_ENERGY_DET (1 << 4)
|
||||
#define EXT_IDDQ_FROM_PHY (1 << 5)
|
||||
#define EXT_IDDQ_GLBL_PWR (1 << 7)
|
||||
#define EXT_PHY_RESET (1 << 8)
|
||||
#define EXT_ENERGY_DET_MASK (1 << 12)
|
||||
#define EXT_PWR_DOWN_PHY_TX (1 << 16)
|
||||
#define EXT_PWR_DOWN_PHY_RX (1 << 17)
|
||||
#define EXT_PWR_DOWN_PHY_SD (1 << 18)
|
||||
#define EXT_PWR_DOWN_PHY_RD (1 << 19)
|
||||
#define EXT_PWR_DOWN_PHY_EN (1 << 20)
|
||||
|
||||
#define EXT_RGMII_OOB_CTRL 0x0C
|
||||
#define RGMII_LINK (1 << 4)
|
||||
|
@ -495,13 +501,15 @@ enum bcmgenet_version {
|
|||
GENET_V1 = 1,
|
||||
GENET_V2,
|
||||
GENET_V3,
|
||||
GENET_V4
|
||||
GENET_V4,
|
||||
GENET_V5
|
||||
};
|
||||
|
||||
#define GENET_IS_V1(p) ((p)->version == GENET_V1)
|
||||
#define GENET_IS_V2(p) ((p)->version == GENET_V2)
|
||||
#define GENET_IS_V3(p) ((p)->version == GENET_V3)
|
||||
#define GENET_IS_V4(p) ((p)->version == GENET_V4)
|
||||
#define GENET_IS_V5(p) ((p)->version == GENET_V5)
|
||||
|
||||
/* Hardware flags */
|
||||
#define GENET_HAS_40BITS (1 << 0)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Broadcom GENET MDIO routines
|
||||
*
|
||||
* Copyright (c) 2014 Broadcom Corporation
|
||||
* Copyright (c) 2014-2017 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -195,29 +195,31 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
|
|||
u32 reg = 0;
|
||||
|
||||
/* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
|
||||
if (!GENET_IS_V4(priv))
|
||||
return;
|
||||
if (GENET_IS_V4(priv)) {
|
||||
reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
|
||||
if (enable) {
|
||||
reg &= ~EXT_CK25_DIS;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
|
||||
reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
|
||||
if (enable) {
|
||||
reg &= ~EXT_CK25_DIS;
|
||||
reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN);
|
||||
reg |= EXT_GPHY_RESET;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
|
||||
reg &= ~EXT_GPHY_RESET;
|
||||
} else {
|
||||
reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN |
|
||||
EXT_GPHY_RESET;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
reg |= EXT_CK25_DIS;
|
||||
}
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
|
||||
reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN);
|
||||
reg |= EXT_GPHY_RESET;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
|
||||
reg &= ~EXT_GPHY_RESET;
|
||||
udelay(60);
|
||||
} else {
|
||||
reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_GPHY_RESET;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
mdelay(1);
|
||||
reg |= EXT_CK25_DIS;
|
||||
}
|
||||
bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
|
||||
udelay(60);
|
||||
}
|
||||
|
||||
static void bcmgenet_internal_phy_setup(struct net_device *dev)
|
||||
|
@ -227,10 +229,12 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev)
|
|||
|
||||
/* Power up PHY */
|
||||
bcmgenet_phy_power_set(dev, true);
|
||||
/* enable APD */
|
||||
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
if (!GENET_IS_V5(priv)) {
|
||||
/* enable APD */
|
||||
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
|
||||
reg |= EXT_PWR_DN_EN_LD;
|
||||
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
|
||||
}
|
||||
bcmgenet_mii_reset(dev);
|
||||
}
|
||||
|
||||
|
@ -238,10 +242,12 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
|
|||
{
|
||||
u32 reg;
|
||||
|
||||
/* Speed settings are set in bcmgenet_mii_setup() */
|
||||
reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
|
||||
reg |= LED_ACT_SOURCE_MAC;
|
||||
bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
|
||||
if (!GENET_IS_V5(priv)) {
|
||||
/* Speed settings are set in bcmgenet_mii_setup() */
|
||||
reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
|
||||
reg |= LED_ACT_SOURCE_MAC;
|
||||
bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
|
||||
}
|
||||
|
||||
if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
|
||||
fixed_phy_set_link_update(priv->phydev,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Broadcom UniMAC MDIO bus controller driver
|
||||
*
|
||||
* Copyright (C) 2014, Broadcom Corporation
|
||||
* Copyright (C) 2014-2017 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -228,6 +228,7 @@ static int unimac_mdio_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id unimac_mdio_ids[] = {
|
||||
{ .compatible = "brcm,genet-mdio-v5", },
|
||||
{ .compatible = "brcm,genet-mdio-v4", },
|
||||
{ .compatible = "brcm,genet-mdio-v3", },
|
||||
{ .compatible = "brcm,genet-mdio-v2", },
|
||||
|
|
Loading…
Reference in New Issue