From: patrick Date: Thu, 3 Jun 2021 21:42:23 +0000 (+0000) Subject: Implement multicast support in mvpp(4) to make IPv6 work. With this X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ce595ab8b9144494e2ff2f2d79b52594ef403178;p=openbsd Implement multicast support in mvpp(4) to make IPv6 work. With this change it's also not necessary to remember the old lladdr, since the old one will be purged automatically prior to installing the current set of multicast addresses. Complaint filed by matthieu@ --- 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 * Copyright (c) 2017, 2020 Patrick Wildt @@ -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 * Copyright (c) 2017, 2020 Patrick Wildt @@ -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)