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.faine...@gmail.com>
---
 drivers/net/ethernet/broadcom/bcmsysport.c | 12 ++++++++++++
 drivers/net/ethernet/broadcom/bcmsysport.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c 
b/drivers/net/ethernet/broadcom/bcmsysport.c
index 0e2d99c737e3..2e60dda32adc 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -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;
 }
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h 
b/drivers/net/ethernet/broadcom/bcmsysport.h
index a7a230884a87..7a0b7bfedd19 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -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;
 
-- 
2.17.1

Reply via email to