Skip to content

Commit

Permalink
net: dsa: bcm_sf2: Restore CFP rules during system resume
Browse files Browse the repository at this point in the history
The hardware can lose its context during system suspend, and depending
on the switch generation (7445 vs. 7278), while the rules are still
there, they will have their valid bit cleared (because that's the
fastest way for the HW to reset things). Just make sure we re-apply them
coming back from resume. The 7445 switch is an older version of the core
that has some quirky RAM technology requiring a delete then re-inser to
guarantee the RAM entries are properly latched.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Florian Fainelli authored and David S. Miller committed Nov 6, 2018
1 parent ce24b08 commit 1c0130f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,10 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
return ret;
}

ret = bcm_sf2_cfp_resume(ds);
if (ret)
return ret;

if (priv->hw_params.num_gphy == 1)
bcm_sf2_gphy_enable_set(ds, true);

Expand Down
1 change: 1 addition & 0 deletions drivers/net/dsa/bcm_sf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,6 @@ int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
struct ethtool_rxnfc *nfc);
int bcm_sf2_cfp_rst(struct bcm_sf2_priv *priv);
void bcm_sf2_cfp_exit(struct dsa_switch *ds);
int bcm_sf2_cfp_resume(struct dsa_switch *ds);

#endif /* __BCM_SF2_H */
36 changes: 36 additions & 0 deletions drivers/net/dsa/bcm_sf2_cfp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,3 +1443,39 @@ void bcm_sf2_cfp_exit(struct dsa_switch *ds)
list_for_each_entry_safe_reverse(rule, n, &priv->cfp.rules_list, next)
bcm_sf2_cfp_rule_del(priv, rule->port, rule->fs.location);
}

int bcm_sf2_cfp_resume(struct dsa_switch *ds)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct cfp_rule *rule;
int ret = 0;
u32 reg;

if (list_empty(&priv->cfp.rules_list))
return ret;

reg = core_readl(priv, CORE_CFP_CTL_REG);
reg &= ~CFP_EN_MAP_MASK;
core_writel(priv, reg, CORE_CFP_CTL_REG);

ret = bcm_sf2_cfp_rst(priv);
if (ret)
return ret;

list_for_each_entry(rule, &priv->cfp.rules_list, next) {
ret = bcm_sf2_cfp_rule_remove(priv, rule->port,
rule->fs.location);
if (ret) {
dev_err(ds->dev, "failed to remove rule\n");
return ret;
}

ret = bcm_sf2_cfp_rule_insert(ds, rule->port, &rule->fs);
if (ret) {
dev_err(ds->dev, "failed to restore rule\n");
return ret;
}
};

return ret;
}

0 comments on commit 1c0130f

Please sign in to comment.