aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa/bcm_sf2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa/bcm_sf2.c')
-rw-r--r--drivers/net/dsa/bcm_sf2.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index cedb572bf25a..079897b3a955 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -24,6 +24,7 @@
24#include <net/dsa.h> 24#include <net/dsa.h>
25#include <linux/ethtool.h> 25#include <linux/ethtool.h>
26#include <linux/if_bridge.h> 26#include <linux/if_bridge.h>
27#include <linux/brcmphy.h>
27 28
28#include "bcm_sf2.h" 29#include "bcm_sf2.h"
29#include "bcm_sf2_regs.h" 30#include "bcm_sf2_regs.h"
@@ -695,9 +696,20 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
695 } 696 }
696 697
697 /* Include the pseudo-PHY address and the broadcast PHY address to 698 /* Include the pseudo-PHY address and the broadcast PHY address to
698 * divert reads towards our workaround 699 * divert reads towards our workaround. This is only required for
700 * 7445D0, since 7445E0 disconnects the internal switch pseudo-PHY such
701 * that we can use the regular SWITCH_MDIO master controller instead.
702 *
703 * By default, DSA initializes ds->phys_mii_mask to ds->phys_port_mask
704 * to have a 1:1 mapping between Port address and PHY address in order
705 * to utilize the slave_mii_bus instance to read from Port PHYs. This is
706 * not what we want here, so we initialize phys_mii_mask 0 to always
707 * utilize the "master" MDIO bus backed by the "mdio-unimac" driver.
699 */ 708 */
700 ds->phys_mii_mask |= ((1 << 30) | (1 << 0)); 709 if (of_machine_is_compatible("brcm,bcm7445d0"))
710 ds->phys_mii_mask |= ((1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0));
711 else
712 ds->phys_mii_mask = 0;
701 713
702 rev = reg_readl(priv, REG_SWITCH_REVISION); 714 rev = reg_readl(priv, REG_SWITCH_REVISION);
703 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) & 715 priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) &
@@ -782,7 +794,7 @@ static int bcm_sf2_sw_phy_read(struct dsa_switch *ds, int addr, int regnum)
782 */ 794 */
783 switch (addr) { 795 switch (addr) {
784 case 0: 796 case 0:
785 case 30: 797 case BRCM_PSEUDO_PHY_ADDR:
786 return bcm_sf2_sw_indir_rw(ds, 1, addr, regnum, 0); 798 return bcm_sf2_sw_indir_rw(ds, 1, addr, regnum, 0);
787 default: 799 default:
788 return 0xffff; 800 return 0xffff;
@@ -797,7 +809,7 @@ static int bcm_sf2_sw_phy_write(struct dsa_switch *ds, int addr, int regnum,
797 */ 809 */
798 switch (addr) { 810 switch (addr) {
799 case 0: 811 case 0:
800 case 30: 812 case BRCM_PSEUDO_PHY_ADDR:
801 bcm_sf2_sw_indir_rw(ds, 0, addr, regnum, val); 813 bcm_sf2_sw_indir_rw(ds, 0, addr, regnum, val);
802 break; 814 break;
803 } 815 }
@@ -911,6 +923,13 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
911 */ 923 */
912 if (port == 7) { 924 if (port == 7) {
913 status->link = priv->port_sts[port].link; 925 status->link = priv->port_sts[port].link;
926 /* For MoCA interfaces, also force a link down notification
927 * since some version of the user-space daemon (mocad) use
928 * cmd->autoneg to force the link, which messes up the PHY
929 * state machine and make it go in PHY_FORCING state instead.
930 */
931 if (!status->link)
932 netif_carrier_off(ds->ports[port]);
914 status->duplex = 1; 933 status->duplex = 1;
915 } else { 934 } else {
916 status->link = 1; 935 status->link = 1;