From 2104bc0ab0eee8a4768dd80df8ed42eb591543bc Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 3 Aug 2018 11:08:41 -0700 Subject: [PATCH 1/4] net: dsa: bcm_sf2: Allow targeting CPU ports for CFP rules ds->enabled_port_mask only contains a bitmask of user-facing enabled ports, we also need to allow programming CFP rules that target CPU ports (e.g: ports 5 and 8). Signed-off-by: Florian Fainelli Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2_cfp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index b89acaee12d4..1e37b65aab93 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -755,7 +755,8 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES; if (fs->ring_cookie == RX_CLS_FLOW_DISC || - !dsa_is_user_port(ds, port_num) || + !(dsa_is_user_port(ds, port_num) || + dsa_is_cpu_port(ds, port_num)) || port_num >= priv->hw_params.num_ports) return -EINVAL; /* From c0e6820b7e4175171f302df6cc4706b818f4a691 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 3 Aug 2018 11:08:42 -0700 Subject: [PATCH 2/4] net: dsa: bcm_sf2: Disable learning while in WoL When we are in Wake-on-LAN, we operate with the host sofware not running a network stack, so we want to the switch to flood packets in order to cause a system wake-up when matching specific filters (unicast or multicast). This was not necessary before since we supported Magic Packet which are targeting a broadcast MAC address which the switch already floods. Signed-off-by: Florian Fainelli Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2.c | 12 +++++++++++- drivers/net/dsa/bcm_sf2_regs.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index ac96ff40d37e..e0066adcd2f3 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -166,6 +166,11 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, reg &= ~P_TXQ_PSM_VDD(port); core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); + /* Enable learning */ + reg = core_readl(priv, CORE_DIS_LEARN); + reg &= ~BIT(port); + core_writel(priv, reg, CORE_DIS_LEARN); + /* Enable Broadcom tags for that port if requested */ if (priv->brcm_tag_mask & BIT(port)) b53_brcm_hdr_setup(ds, port); @@ -222,8 +227,13 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); u32 reg; - if (priv->wol_ports_mask & (1 << port)) + /* Disable learning while in WoL mode */ + if (priv->wol_ports_mask & (1 << port)) { + reg = core_readl(priv, CORE_DIS_LEARN); + reg |= BIT(port); + core_writel(priv, reg, CORE_DIS_LEARN); return; + } if (port == priv->moca_port) bcm_sf2_port_intr_disable(priv, port); diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h index 3ccd5a865dcb..0a1e530d52b7 100644 --- a/drivers/net/dsa/bcm_sf2_regs.h +++ b/drivers/net/dsa/bcm_sf2_regs.h @@ -168,6 +168,8 @@ enum bcm_sf2_reg_offs { #define CORE_SWITCH_CTRL 0x00088 #define MII_DUMB_FWDG_EN (1 << 6) +#define CORE_DIS_LEARN 0x000f0 + #define CORE_SFT_LRN_CTRL 0x000f8 #define SW_LEARN_CNTL(x) (1 << (x)) From 9e85e22713d6fed4873057493d6307c08b1d86a6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 3 Aug 2018 11:08:43 -0700 Subject: [PATCH 3/4] net: systemport: Do not re-configure upon WoL interrupt We already properly resume from Wake-on-LAN whether such a condition occured or not, no need to process the WoL interrupt for functional changes since that could race with other settings. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 631617d95769..7faad9e1a6f9 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1102,10 +1102,8 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) if (priv->irq0_stat & INTRL2_0_TX_RING_FULL) bcm_sysport_tx_reclaim_all(priv); - if (priv->irq0_stat & INTRL2_0_MPD) { + if (priv->irq0_stat & INTRL2_0_MPD) netdev_info(priv->netdev, "Wake-on-LAN interrupt!\n"); - bcm_sysport_resume_from_wol(priv); - } if (!priv->is_lite) goto out; From 54226116add4dcfe6391ffb810225f78c9c3d245 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 3 Aug 2018 11:08:44 -0700 Subject: [PATCH 4/4] net: systemport: Create helper to set MPD Create a helper function to turn on/off MPD, this will be used to avoid duplicating code as we are going to add additional types of wake-up types. Signed-off-by: Florian Fainelli Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 7faad9e1a6f9..284581c9680e 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1041,17 +1041,25 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget) return work_done; } -static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv) +static void mpd_enable_set(struct bcm_sysport_priv *priv, bool enable) { u32 reg; + reg = umac_readl(priv, UMAC_MPD_CTRL); + if (enable) + reg |= MPD_EN; + else + reg &= ~MPD_EN; + umac_writel(priv, reg, UMAC_MPD_CTRL); +} + +static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv) +{ /* Stop monitoring MPD interrupt */ intrl2_0_mask_set(priv, INTRL2_0_MPD); /* Clear the MagicPacket detection logic */ - reg = umac_readl(priv, UMAC_MPD_CTRL); - reg &= ~MPD_EN; - umac_writel(priv, reg, UMAC_MPD_CTRL); + mpd_enable_set(priv, false); netif_dbg(priv, wol, priv->netdev, "resumed from WOL\n"); } @@ -2447,9 +2455,7 @@ static int bcm_sysport_suspend_to_wol(struct bcm_sysport_priv *priv) /* Do not leave the UniMAC RBUF matching only MPD packets */ if (!timeout) { - reg = umac_readl(priv, UMAC_MPD_CTRL); - reg &= ~MPD_EN; - umac_writel(priv, reg, UMAC_MPD_CTRL); + mpd_enable_set(priv, false); netif_err(priv, wol, ndev, "failed to enter WOL mode\n"); return -ETIMEDOUT; }