Пример #1
0
void
smsc_setmulti(struct smsc_softc *sc)
{
    struct ifnet		*ifp = &sc->sc_ec.ec_if;
    struct ether_multi	*enm;
    struct ether_multistep	 step;
    uint32_t		 hashtbl[2] = { 0, 0 };
    uint32_t		 hash;

    if (sc->sc_dying)
        return;

    if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
allmulti:
        smsc_dbg_printf(sc, "receive all multicast enabled\n");
        sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
        sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT;
        smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
        return;
    } else {
        sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;
        sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS);
    }

    ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
    while (enm != NULL) {
        if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
                   ETHER_ADDR_LEN) != 0)
            goto allmulti;

        hash = smsc_hash(enm->enm_addrlo);
        hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
        ETHER_NEXT_MULTI(step, enm);
    }

    /* Debug */
    if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) {
        smsc_dbg_printf(sc, "receive select group of macs\n");
    } else {
        smsc_dbg_printf(sc, "receive own packets only\n");
    }

    /* Write the hash table and mac control registers */
    ifp->if_flags &= ~IFF_ALLMULTI;
    smsc_write_reg(sc, SMSC_HASHH, hashtbl[1]);
    smsc_write_reg(sc, SMSC_HASHL, hashtbl[0]);
    smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
}
Пример #2
0
void
smsc_iff(struct smsc_softc *sc)
{
	struct ifnet		*ifp = &sc->sc_ac.ac_if;
	struct arpcom		*ac = &sc->sc_ac;
	struct ether_multi	*enm;
	struct ether_multistep	 step;
	uint32_t		 hashtbl[2] = { 0, 0 };
	uint32_t		 hash;

	if (usbd_is_dying(sc->sc_udev))
		return;

	sc->sc_mac_csr &= ~(SMSC_MAC_CSR_HPFILT | SMSC_MAC_CSR_MCPAS |
	    SMSC_MAC_CSR_PRMS);
	ifp->if_flags &= ~IFF_ALLMULTI;

	if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
		ifp->if_flags |= IFF_ALLMULTI;
		sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
		if (ifp->if_flags & IFF_PROMISC)
			sc->sc_mac_csr |= SMSC_MAC_CSR_PRMS;
	} else {
		sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;

		ETHER_FIRST_MULTI(step, ac, enm);
		while (enm != NULL) {
			hash = smsc_hash(enm->enm_addrlo);

			hashtbl[hash >> 5] |= 1 << (hash & 0x1F);

			ETHER_NEXT_MULTI(step, enm);
		}
	}

	/* Debug */
	if (sc->sc_mac_csr & SMSC_MAC_CSR_MCPAS)
		smsc_dbg_printf(sc, "receive all multicast enabled\n");
	else if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT)
		smsc_dbg_printf(sc, "receive select group of macs\n");

	/* Write the hash table and mac control registers */
	smsc_write_reg(sc, SMSC_HASHH, hashtbl[1]);
	smsc_write_reg(sc, SMSC_HASHL, hashtbl[0]);
	smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
}