diff options
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_ale.c')
| -rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index ca0d48a7e508..0e9ccc2cf91f 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/stat.h> | 21 | #include <linux/stat.h> |
| 22 | #include <linux/sysfs.h> | 22 | #include <linux/sysfs.h> |
| 23 | #include <linux/etherdevice.h> | ||
| 23 | 24 | ||
| 24 | #include "cpsw_ale.h" | 25 | #include "cpsw_ale.h" |
| 25 | 26 | ||
| @@ -211,10 +212,34 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, | |||
| 211 | mask &= ~port_mask; | 212 | mask &= ~port_mask; |
| 212 | 213 | ||
| 213 | /* free if only remaining port is host port */ | 214 | /* free if only remaining port is host port */ |
| 214 | if (mask == BIT(ale->params.ale_ports)) | 215 | if (mask) |
| 215 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | ||
| 216 | else | ||
| 217 | cpsw_ale_set_port_mask(ale_entry, mask); | 216 | cpsw_ale_set_port_mask(ale_entry, mask); |
| 217 | else | ||
| 218 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | ||
| 219 | } | ||
| 220 | |||
| 221 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | ||
| 222 | { | ||
| 223 | u32 ale_entry[ALE_ENTRY_WORDS]; | ||
| 224 | int ret, idx; | ||
| 225 | |||
| 226 | for (idx = 0; idx < ale->params.ale_entries; idx++) { | ||
| 227 | cpsw_ale_read(ale, idx, ale_entry); | ||
| 228 | ret = cpsw_ale_get_entry_type(ale_entry); | ||
| 229 | if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) | ||
| 230 | continue; | ||
| 231 | |||
| 232 | if (cpsw_ale_get_mcast(ale_entry)) { | ||
| 233 | u8 addr[6]; | ||
| 234 | |||
| 235 | cpsw_ale_get_addr(ale_entry, addr); | ||
| 236 | if (!is_broadcast_ether_addr(addr)) | ||
| 237 | cpsw_ale_flush_mcast(ale, ale_entry, port_mask); | ||
| 238 | } | ||
| 239 | |||
| 240 | cpsw_ale_write(ale, idx, ale_entry); | ||
| 241 | } | ||
| 242 | return 0; | ||
| 218 | } | 243 | } |
| 219 | 244 | ||
| 220 | static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry, | 245 | static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry, |
