-/* $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>
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,
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 *);
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);
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);
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);
+ }
}
}
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;
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;
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)
{
-/* $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>
#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
/* 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)