Skip to content

Commit 1c0130f

Browse files
ffainellidavem330
authored andcommitted
net: dsa: bcm_sf2: Restore CFP rules during system resume
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ce24b08 commit 1c0130f

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

drivers/net/dsa/bcm_sf2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,10 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
710710
return ret;
711711
}
712712

713+
ret = bcm_sf2_cfp_resume(ds);
714+
if (ret)
715+
return ret;
716+
713717
if (priv->hw_params.num_gphy == 1)
714718
bcm_sf2_gphy_enable_set(ds, true);
715719

drivers/net/dsa/bcm_sf2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,6 @@ int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
215215
struct ethtool_rxnfc *nfc);
216216
int bcm_sf2_cfp_rst(struct bcm_sf2_priv *priv);
217217
void bcm_sf2_cfp_exit(struct dsa_switch *ds);
218+
int bcm_sf2_cfp_resume(struct dsa_switch *ds);
218219

219220
#endif /* __BCM_SF2_H */

drivers/net/dsa/bcm_sf2_cfp.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,3 +1443,39 @@ void bcm_sf2_cfp_exit(struct dsa_switch *ds)
14431443
list_for_each_entry_safe_reverse(rule, n, &priv->cfp.rules_list, next)
14441444
bcm_sf2_cfp_rule_del(priv, rule->port, rule->fs.location);
14451445
}
1446+
1447+
int bcm_sf2_cfp_resume(struct dsa_switch *ds)
1448+
{
1449+
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
1450+
struct cfp_rule *rule;
1451+
int ret = 0;
1452+
u32 reg;
1453+
1454+
if (list_empty(&priv->cfp.rules_list))
1455+
return ret;
1456+
1457+
reg = core_readl(priv, CORE_CFP_CTL_REG);
1458+
reg &= ~CFP_EN_MAP_MASK;
1459+
core_writel(priv, reg, CORE_CFP_CTL_REG);
1460+
1461+
ret = bcm_sf2_cfp_rst(priv);
1462+
if (ret)
1463+
return ret;
1464+
1465+
list_for_each_entry(rule, &priv->cfp.rules_list, next) {
1466+
ret = bcm_sf2_cfp_rule_remove(priv, rule->port,
1467+
rule->fs.location);
1468+
if (ret) {
1469+
dev_err(ds->dev, "failed to remove rule\n");
1470+
return ret;
1471+
}
1472+
1473+
ret = bcm_sf2_cfp_rule_insert(ds, rule->port, &rule->fs);
1474+
if (ret) {
1475+
dev_err(ds->dev, "failed to restore rule\n");
1476+
return ret;
1477+
}
1478+
};
1479+
1480+
return ret;
1481+
}

0 commit comments

Comments
 (0)