diff options
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_ale.c')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.c | 29 |
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) | |||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | 445 | ||
446 | void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti) | ||
447 | { | ||
448 | u32 ale_entry[ALE_ENTRY_WORDS]; | ||
449 | int type, idx; | ||
450 | int unreg_mcast = 0; | ||
451 | |||
452 | /* Only bother doing the work if the setting is actually changing */ | ||
453 | if (ale->allmulti == allmulti) | ||
454 | return; | ||
455 | |||
456 | /* Remember the new setting to check against next time */ | ||
457 | ale->allmulti = allmulti; | ||
458 | |||
459 | for (idx = 0; idx < ale->params.ale_entries; idx++) { | ||
460 | cpsw_ale_read(ale, idx, ale_entry); | ||
461 | type = cpsw_ale_get_entry_type(ale_entry); | ||
462 | if (type != ALE_TYPE_VLAN) | ||
463 | continue; | ||
464 | |||
465 | unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry); | ||
466 | if (allmulti) | ||
467 | unreg_mcast |= 1; | ||
468 | else | ||
469 | unreg_mcast &= ~1; | ||
470 | cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast); | ||
471 | cpsw_ale_write(ale, idx, ale_entry); | ||
472 | } | ||
473 | } | ||
474 | |||
446 | struct ale_control_info { | 475 | struct ale_control_info { |
447 | const char *name; | 476 | const char *name; |
448 | int offset, port_offset; | 477 | int offset, port_offset; |