diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2017-01-20 23:36:30 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-23 00:58:31 +0300 |
commit | 0fe9933804eb860b7c26fd3fcd5839dc6bb66533 (patch) | |
tree | 2d41430683db486ddd11cab1b491f4f24e88316f /drivers/net/dsa/bcm_sf2.c | |
parent | a78e86ed586dba0808f765a9498f1fcd803f6ac6 (diff) | |
download | linux-0fe9933804eb860b7c26fd3fcd5839dc6bb66533.tar.xz |
net: dsa: bcm_sf2: Add support for BCM7278 integrated switch
Add support for the integrated switch found on BCM7278:
- core_reg_align is set to 1, to force a translation into the target
address space which is 8 bytes aligned
- an alternate SWITCH_REG layout is provided since registers are largely
bit/masks compatible but have different offsets
- conditional for all CORE_STS_OVERRIDE_{IMP,GMII_P} since those got
moved way out of the traditional register space
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/bcm_sf2.c')
-rw-r--r-- | drivers/net/dsa/bcm_sf2.c | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index d952099afc60..02afa0598b24 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -64,7 +64,12 @@ static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); - u32 reg, val; + u32 reg, val, offset; + + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_IMP; + else + offset = CORE_STS_OVERRIDE_IMP2; /* Enable the port memories */ reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); @@ -121,9 +126,9 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) core_writel(priv, reg, CORE_BRCM_HDR_TX_DIS); /* Force link status for IMP port */ - reg = core_readl(priv, CORE_STS_OVERRIDE_IMP); + reg = core_readl(priv, offset); reg |= (MII_SW_OR | LINK_STS); - core_writel(priv, reg, CORE_STS_OVERRIDE_IMP); + core_writel(priv, reg, offset); } static void bcm_sf2_eee_enable_set(struct dsa_switch *ds, int port, bool enable) @@ -591,7 +596,12 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, struct ethtool_eee *p = &priv->port_sts[port].eee; u32 id_mode_dis = 0, port_mode; const char *str = NULL; - u32 reg; + u32 reg, offset; + + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_GMIIP_PORT(port); + else + offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port); switch (phydev->interface) { case PHY_INTERFACE_MODE_RGMII: @@ -662,7 +672,7 @@ force_link: if (phydev->duplex == DUPLEX_FULL) reg |= DUPLX_MODE; - core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); + core_writel(priv, reg, offset); if (!phydev->is_pseudo_fixed_link) p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); @@ -672,9 +682,14 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, struct fixed_phy_status *status) { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); - u32 duplex, pause; + u32 duplex, pause, offset; u32 reg; + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_GMIIP_PORT(port); + else + offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port); + duplex = core_readl(priv, CORE_DUPSTS); pause = core_readl(priv, CORE_PAUSESTS); @@ -703,13 +718,13 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, status->duplex = !!(duplex & (1 << port)); } - reg = core_readl(priv, CORE_STS_OVERRIDE_GMIIP_PORT(port)); + reg = core_readl(priv, offset); reg |= SW_OVERRIDE; if (status->link) reg |= LINK_STS; else reg &= ~LINK_STS; - core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); + core_writel(priv, reg, offset); if ((pause & (1 << port)) && (pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) { @@ -1038,10 +1053,35 @@ static const struct bcm_sf2_of_data bcm_sf2_7445_data = { .reg_offsets = bcm_sf2_7445_reg_offsets, }; +static const u16 bcm_sf2_7278_reg_offsets[] = { + [REG_SWITCH_CNTRL] = 0x00, + [REG_SWITCH_STATUS] = 0x04, + [REG_DIR_DATA_WRITE] = 0x08, + [REG_DIR_DATA_READ] = 0x0c, + [REG_SWITCH_REVISION] = 0x10, + [REG_PHY_REVISION] = 0x14, + [REG_SPHY_CNTRL] = 0x24, + [REG_RGMII_0_CNTRL] = 0xe0, + [REG_RGMII_1_CNTRL] = 0xec, + [REG_RGMII_2_CNTRL] = 0xf8, + [REG_LED_0_CNTRL] = 0x40, + [REG_LED_1_CNTRL] = 0x4c, + [REG_LED_2_CNTRL] = 0x58, +}; + +static const struct bcm_sf2_of_data bcm_sf2_7278_data = { + .type = BCM7278_DEVICE_ID, + .core_reg_align = 1, + .reg_offsets = bcm_sf2_7278_reg_offsets, +}; + static const struct of_device_id bcm_sf2_of_match[] = { { .compatible = "brcm,bcm7445-switch-v4.0", .data = &bcm_sf2_7445_data }, + { .compatible = "brcm,bcm7278-switch-v4.0", + .data = &bcm_sf2_7278_data + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, bcm_sf2_of_match); |