diff options
-rw-r--r-- | sys/dev/fdt/if_mvpp.c | 89 | ||||
-rw-r--r-- | sys/dev/fdt/if_mvppreg.h | 11 |
2 files changed, 83 insertions, 17 deletions
diff --git a/sys/dev/fdt/if_mvpp.c b/sys/dev/fdt/if_mvpp.c index 0350b467354..1894dd2abfd 100644 --- a/sys/dev/fdt/if_mvpp.c +++ b/sys/dev/fdt/if_mvpp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvpp.c,v 1.45 2021/06/02 21:41:38 kettenis Exp $ */ +/* $OpenBSD: if_mvpp.c,v 1.46 2021/06/03 21:42:23 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se> @@ -194,7 +194,6 @@ struct mvpp2_port { struct mii_data sc_mii; #define sc_media sc_mii.mii_media struct mii_bus *sc_mdio; - char sc_cur_lladdr[ETHER_ADDR_LEN]; enum { PHY_MODE_XAUI, @@ -419,6 +418,7 @@ int mvpp2_prs_mac_da_range_find(struct mvpp2_softc *, int, const uint8_t *, int mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *, const uint8_t *, uint8_t *); int mvpp2_prs_mac_da_accept(struct mvpp2_port *, const uint8_t *, int); +void mvpp2_prs_mac_del_all(struct mvpp2_port *); int mvpp2_prs_tag_mode_set(struct mvpp2_softc *, int, int); int mvpp2_prs_def_flow(struct mvpp2_port *); void mvpp2_cls_flow_write(struct mvpp2_softc *, struct mvpp2_cls_flow_entry *); @@ -2279,10 +2279,9 @@ mvpp2_up(struct mvpp2_port *sc) sfp_enable(sc->sc_sfp); rw_exit(&mvpp2_sff_lock); } - - memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN); + mvpp2_prs_mac_da_accept(sc, etherbroadcastaddr, 1); - mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 1); + mvpp2_prs_mac_da_accept(sc, sc->sc_lladdr, 1); mvpp2_prs_tag_mode_set(sc->sc, sc->sc_id, MVPP2_TAG_TYPE_MH); mvpp2_prs_def_flow(sc); @@ -2904,8 +2903,6 @@ mvpp2_down(struct mvpp2_port *sc) for (i = 0; i < sc->sc_nrxq; i++) mvpp2_rxq_hw_deinit(sc, &sc->sc_rxqs[i]); - mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 0); - if (sc->sc_sfp) { rw_enter(&mvpp2_sff_lock, RW_WRITE); sfp_disable(sc->sc_sfp); @@ -3062,12 +3059,40 @@ mvpp2_rxq_short_pool_set(struct mvpp2_port *port, int lrxq, int pool) void mvpp2_iff(struct mvpp2_port *sc) { - /* FIXME: multicast handling */ + struct arpcom *ac = &sc->sc_ac; + struct ifnet *ifp = &sc->sc_ac.ac_if; + struct ether_multi *enm; + struct ether_multistep step; + + ifp->if_flags &= ~IFF_ALLMULTI; + + /* Removes all but broadcast and (new) lladdr */ + mvpp2_prs_mac_del_all(sc); - if (memcmp(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN) != 0) { - mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 0); - memcpy(sc->sc_cur_lladdr, sc->sc_lladdr, ETHER_ADDR_LEN); - mvpp2_prs_mac_da_accept(sc, sc->sc_cur_lladdr, 1); + if (ifp->if_flags & IFF_PROMISC) { + mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, + MVPP2_PRS_L2_UNI_CAST, 1); + mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, + MVPP2_PRS_L2_MULTI_CAST, 1); + return; + } + + mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, + MVPP2_PRS_L2_UNI_CAST, 0); + mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, + MVPP2_PRS_L2_MULTI_CAST, 0); + + if (ac->ac_multirangecnt > 0 || + ac->ac_multicnt > MVPP2_PRS_MAC_MC_FILT_MAX) { + ifp->if_flags |= IFF_ALLMULTI; + mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, + MVPP2_PRS_L2_MULTI_CAST, 1); + } else { + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + mvpp2_prs_mac_da_accept(sc, enm->enm_addrlo, 1); + ETHER_NEXT_MULTI(step, enm); + } } } @@ -4347,7 +4372,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2_softc *sc, int pmap, const uint8_t *da, struct mvpp2_prs_entry pe; int tid; - for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; + for (tid = MVPP2_PE_MAC_RANGE_START; tid <= MVPP2_PE_MAC_RANGE_END; tid++) { uint32_t entry_pmap; @@ -4383,8 +4408,8 @@ mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const uint8_t *da, int add) if (!add) return 0; - tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, - MVPP2_PE_LAST_FREE_TID); + tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_MAC_RANGE_START, + MVPP2_PE_MAC_RANGE_END); if (tid < 0) return tid; @@ -4434,6 +4459,40 @@ mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const uint8_t *da, int add) return 0; } +void +mvpp2_prs_mac_del_all(struct mvpp2_port *port) +{ + struct mvpp2_softc *sc = port->sc; + struct mvpp2_prs_entry pe; + uint32_t pmap; + int index, tid; + + for (tid = MVPP2_PE_MAC_RANGE_START; tid <= MVPP2_PE_MAC_RANGE_END; + tid++) { + uint8_t da[ETHER_ADDR_LEN], da_mask[ETHER_ADDR_LEN]; + + if (!sc->sc_prs_shadow[tid].valid || + (sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) || + (sc->sc_prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)) + continue; + + mvpp2_prs_hw_read(sc, &pe, tid); + pmap = mvpp2_prs_tcam_port_map_get(&pe); + + if (!(pmap & (1 << port->sc_id))) + continue; + + for (index = 0; index < ETHER_ADDR_LEN; index++) + mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index], + &da_mask[index]); + + if (ETHER_IS_BROADCAST(da) || ETHER_IS_EQ(da, port->sc_lladdr)) + continue; + + mvpp2_prs_mac_da_accept(port, da, 0); + } +} + int mvpp2_prs_tag_mode_set(struct mvpp2_softc *sc, int port_id, int type) { diff --git a/sys/dev/fdt/if_mvppreg.h b/sys/dev/fdt/if_mvppreg.h index d50b927a825..1c3b8b57a94 100644 --- a/sys/dev/fdt/if_mvppreg.h +++ b/sys/dev/fdt/if_mvppreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvppreg.h,v 1.15 2020/11/08 00:49:41 patrick Exp $ */ +/* $OpenBSD: if_mvppreg.h,v 1.16 2021/06/03 21:42:23 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se> @@ -993,6 +993,10 @@ enum mvpp2_prs_l3_cast { #define MVPP2_PRS_MCAST_VAL BIT(0) #define MVPP2_PRS_UCAST_VAL 0x0 +#define MVPP2_PRS_MAC_RANGE_SIZE 80 +#define MVPP2_PRS_MAC_UC_FILT_MAX 4 +#define MVPP2_PRS_MAC_MC_FILT_MAX 21 + /* * Tcam structure: * - lookup ID - 4 bits @@ -1014,7 +1018,10 @@ enum mvpp2_prs_l3_cast { /* Tcam entries ID */ #define MVPP2_PE_DROP_ALL 0 #define MVPP2_PE_FIRST_FREE_TID 1 -#define MVPP2_PE_LAST_FREE_TID (MVPP2_PRS_TCAM_SRAM_SIZE - 31) +#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_MAC_RANGE_START - 1) +#define MVPP2_PE_MAC_RANGE_END (MVPP2_PRS_TCAM_SRAM_SIZE - 31) +#define MVPP2_PE_MAC_RANGE_START (MVPP2_PE_MAC_RANGE_END - \ + MVPP2_PRS_MAC_RANGE_SIZE + 1) #define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30) #define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 29) #define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28) |