summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ti/cpsw_ale.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-11-26 20:37:57 +0000
committerMark Brown <broonie@kernel.org>2014-11-26 20:37:57 +0000
commitcf2394f70cf7774a107fbaa1ef5010db4bd69baa (patch)
treee79e3e479d04213a67ecd47b31c7db648b0313c2 /drivers/net/ethernet/ti/cpsw_ale.c
parent45fc84c668ba6cc08cbae74042be838bf9283d98 (diff)
parent206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff)
Merge tag 'v3.18-rc4' into regulator-max77802
Linux 3.18-rc4
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_ale.c')
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 0579b2243bb6..3ae83879a75f 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -443,6 +443,35 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
return 0;
}
+void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti)
+{
+ u32 ale_entry[ALE_ENTRY_WORDS];
+ int type, idx;
+ int unreg_mcast = 0;
+
+ /* Only bother doing the work if the setting is actually changing */
+ if (ale->allmulti == allmulti)
+ return;
+
+ /* Remember the new setting to check against next time */
+ ale->allmulti = allmulti;
+
+ for (idx = 0; idx < ale->params.ale_entries; idx++) {
+ cpsw_ale_read(ale, idx, ale_entry);
+ type = cpsw_ale_get_entry_type(ale_entry);
+ if (type != ALE_TYPE_VLAN)
+ continue;
+
+ unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry);
+ if (allmulti)
+ unreg_mcast |= 1;
+ else
+ unreg_mcast &= ~1;
+ cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast);
+ cpsw_ale_write(ale, idx, ale_entry);
+ }
+}
+
struct ale_control_info {
const char *name;
int offset, port_offset;