net: systemport: Restore Broadcom tag match filters upon resume
authorFlorian Fainelli <f.fainelli@gmail.com>
Tue, 6 Nov 2018 20:58:41 +0000 (12:58 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 6 Nov 2018 23:05:22 +0000 (15:05 -0800)
Some of the system suspend states that we support wipe out entirely the
HW contents. If we had a Wake-on-LAN filter programmed prior to going
into suspend, but we did not actually wake-up from Wake-on-LAN and
instead used a deeper suspend state, make sure we restore the CID number
that we need to match against.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bcmsysport.h

index 0e2d99c737e35192b90d0bf3ce541ef2d6ecd4d1..2e60dda32adcbe6cff82352474ed8b4965679700 100644 (file)
@@ -1068,6 +1068,7 @@ static void mpd_enable_set(struct bcm_sysport_priv *priv, bool enable)
 
 static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
 {
+       unsigned int index;
        u32 reg;
 
        /* Disable RXCHK, active filters and Broadcom tag matching */
@@ -1076,6 +1077,15 @@ static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
                 RXCHK_BRCM_TAG_MATCH_SHIFT | RXCHK_EN | RXCHK_BRCM_TAG_EN);
        rxchk_writel(priv, reg, RXCHK_CONTROL);
 
+       /* Make sure we restore correct CID index in case HW lost
+        * its context during deep idle state
+        */
+       for_each_set_bit(index, priv->filters, RXCHK_BRCM_TAG_MAX) {
+               rxchk_writel(priv, priv->filters_loc[index] <<
+                            RXCHK_BRCM_TAG_CID_SHIFT, RXCHK_BRCM_TAG(index));
+               rxchk_writel(priv, 0xff00ffff, RXCHK_BRCM_TAG_MASK(index));
+       }
+
        /* Clear the MagicPacket detection logic */
        mpd_enable_set(priv, false);
 
@@ -2189,6 +2199,7 @@ static int bcm_sysport_rule_set(struct bcm_sysport_priv *priv,
        rxchk_writel(priv, reg, RXCHK_BRCM_TAG(index));
        rxchk_writel(priv, 0xff00ffff, RXCHK_BRCM_TAG_MASK(index));
 
+       priv->filters_loc[index] = nfc->fs.location;
        set_bit(index, priv->filters);
 
        return 0;
@@ -2208,6 +2219,7 @@ static int bcm_sysport_rule_del(struct bcm_sysport_priv *priv,
         * be taken care of during suspend time by bcm_sysport_suspend_to_wol
         */
        clear_bit(index, priv->filters);
+       priv->filters_loc[index] = 0;
 
        return 0;
 }
index a7a230884a87116c251404e95c01ae27be47c402..7a0b7bfedd19a33ec6488886c5df263662f0bfaa 100644 (file)
@@ -786,6 +786,7 @@ struct bcm_sysport_priv {
        /* Ethtool */
        u32                     msg_enable;
        DECLARE_BITMAP(filters, RXCHK_BRCM_TAG_MAX);
+       u32                     filters_loc[RXCHK_BRCM_TAG_MAX];
 
        struct bcm_sysport_stats64      stats64;