Module Name: src Committed By: msaitoh Date: Thu Nov 21 09:12:30 UTC 2019
Modified Files: src/sys/dev/pci: if_age.c if_alc.c if_ale.c if_cas.c Log Message: Fix a bug that IFF_ALLMULTI is almost always set. OpenBSD's ac_multirangecnt is not NetBSD's ec_multicnt. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/dev/pci/if_age.c cvs rdiff -u -r1.43 -r1.44 src/sys/dev/pci/if_alc.c cvs rdiff -u -r1.34 -r1.35 src/sys/dev/pci/if_ale.c cvs rdiff -u -r1.35 -r1.36 src/sys/dev/pci/if_cas.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_age.c diff -u src/sys/dev/pci/if_age.c:1.63 src/sys/dev/pci/if_age.c:1.64 --- src/sys/dev/pci/if_age.c:1.63 Thu Nov 21 06:22:09 2019 +++ src/sys/dev/pci/if_age.c Thu Nov 21 09:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_age.c,v 1.63 2019/11/21 06:22:09 msaitoh Exp $ */ +/* $NetBSD: if_age.c,v 1.64 2019/11/21 09:12:30 msaitoh Exp $ */ /* $OpenBSD: if_age.c,v 1.1 2009/01/16 05:00:34 kevlo Exp $ */ /*- @@ -31,7 +31,7 @@ /* Driver for Attansic Technology Corp. L1 Gigabit Ethernet. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.63 2019/11/21 06:22:09 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.64 2019/11/21 09:12:30 msaitoh Exp $"); #include "vlan.h" @@ -2275,27 +2275,37 @@ age_rxfilter(struct age_softc *sc) */ rxcfg |= MAC_CFG_BCAST; - if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) { - ifp->if_flags |= IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC) + /* Program new filter. */ + if ((ifp->if_flags & IFF_PROMISC) != 0) + goto update; + + memset(mchash, 0, sizeof(mchash)); + + ETHER_LOCK(ec); + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + ETHER_UNLOCK(ec); + goto update; + } + crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); + mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); + ETHER_NEXT_MULTI(step, enm); + } + ETHER_UNLOCK(ec); + +update: + if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + if (ifp->if_flags & IFF_PROMISC) { rxcfg |= MAC_CFG_PROMISC; - else + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + } else rxcfg |= MAC_CFG_ALLMULTI; mchash[0] = mchash[1] = 0xFFFFFFFF; - } else { - /* Program new filter. */ - memset(mchash, 0, sizeof(mchash)); - - ETHER_LOCK(ec); - ETHER_FIRST_MULTI(step, ec, enm); - while (enm != NULL) { - crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); - mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); - ETHER_NEXT_MULTI(step, enm); - } - ETHER_UNLOCK(ec); } - CSR_WRITE_4(sc, AGE_MAR0, mchash[0]); CSR_WRITE_4(sc, AGE_MAR1, mchash[1]); CSR_WRITE_4(sc, AGE_MAC_CFG, rxcfg); Index: src/sys/dev/pci/if_alc.c diff -u src/sys/dev/pci/if_alc.c:1.43 src/sys/dev/pci/if_alc.c:1.44 --- src/sys/dev/pci/if_alc.c:1.43 Wed Oct 30 07:26:28 2019 +++ src/sys/dev/pci/if_alc.c Thu Nov 21 09:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_alc.c,v 1.43 2019/10/30 07:26:28 msaitoh Exp $ */ +/* $NetBSD: if_alc.c,v 1.44 2019/11/21 09:12:30 msaitoh Exp $ */ /* $OpenBSD: if_alc.c,v 1.1 2009/08/08 09:31:13 kevlo Exp $ */ /*- * Copyright (c) 2009, Pyun YongHyeon <yong...@freebsd.org> @@ -3443,27 +3443,37 @@ alc_iff(struct alc_softc *sc) */ rxcfg |= MAC_CFG_BCAST; - if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) { - ifp->if_flags |= IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC) + /* Program new filter. */ + if ((ifp->if_flags & IFF_PROMISC) != 0) + goto update; + + memset(mchash, 0, sizeof(mchash)); + + ETHER_LOCK(ec); + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + ETHER_UNLOCK(ec); + goto update; + } + crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); + mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); + ETHER_NEXT_MULTI(step, enm); + } + ETHER_UNLOCK(ec); + +update: + if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + if (ifp->if_flags & IFF_PROMISC) { rxcfg |= MAC_CFG_PROMISC; - else + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + } else rxcfg |= MAC_CFG_ALLMULTI; mchash[0] = mchash[1] = 0xFFFFFFFF; - } else { - /* Program new filter. */ - memset(mchash, 0, sizeof(mchash)); - - ETHER_LOCK(ec); - ETHER_FIRST_MULTI(step, ec, enm); - while (enm != NULL) { - crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); - mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); - ETHER_NEXT_MULTI(step, enm); - } - ETHER_UNLOCK(ec); } - CSR_WRITE_4(sc, ALC_MAR0, mchash[0]); CSR_WRITE_4(sc, ALC_MAR1, mchash[1]); CSR_WRITE_4(sc, ALC_MAC_CFG, rxcfg); Index: src/sys/dev/pci/if_ale.c diff -u src/sys/dev/pci/if_ale.c:1.34 src/sys/dev/pci/if_ale.c:1.35 --- src/sys/dev/pci/if_ale.c:1.34 Wed Oct 30 07:26:28 2019 +++ src/sys/dev/pci/if_ale.c Thu Nov 21 09:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ale.c,v 1.34 2019/10/30 07:26:28 msaitoh Exp $ */ +/* $NetBSD: if_ale.c,v 1.35 2019/11/21 09:12:30 msaitoh Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yong...@freebsd.org> @@ -32,7 +32,7 @@ /* Driver for Atheros AR8121/AR8113/AR8114 PCIe Ethernet. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ale.c,v 1.34 2019/10/30 07:26:28 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ale.c,v 1.35 2019/11/21 09:12:30 msaitoh Exp $"); #include "vlan.h" @@ -136,10 +136,9 @@ ale_miibus_readreg(device_t dev, int phy if (phy != sc->ale_phyaddr) return -1; +#if 1 if (sc->ale_flags & ALE_FLAG_FASTETHER) { switch (reg) { - case MII_100T2CR: - case MII_100T2SR: case MII_EXTSR: *val = 0; return 0; @@ -147,6 +146,7 @@ ale_miibus_readreg(device_t dev, int phy break; } } +#endif CSR_WRITE_4(sc, ALE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ | MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg)); @@ -177,19 +177,23 @@ ale_miibus_writereg(device_t dev, int ph if (phy != sc->ale_phyaddr) return -1; +#if 1 if (sc->ale_flags & ALE_FLAG_FASTETHER) { +#if 0 switch (reg) { - case MII_100T2CR: - case MII_100T2SR: case MII_EXTSR: + printf("%s: XXXX write EXTSR with %04hx\n", __func__, + val); return 0; default: break; } +#endif } +#endif CSR_WRITE_4(sc, ALE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE | - (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT | + ((uint32_t)val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT | MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg)); for (i = ALE_PHY_TIMEOUT; i > 0; i--) { DELAY(5); @@ -255,6 +259,9 @@ ale_mediastatus(struct ifnet *ifp, struc struct ale_softc *sc = ifp->if_softc; struct mii_data *mii = &sc->sc_miibus; + if ((ifp->if_flags & IFF_UP) == 0) + return; + mii_pollstat(mii); ifmr->ifm_status = mii->mii_media_status; ifmr->ifm_active = mii->mii_media_active; @@ -267,6 +274,7 @@ ale_mediachange(struct ifnet *ifp) struct mii_data *mii = &sc->sc_miibus; int error; + printf("%s: called\n", __func__); if (mii->mii_instance != 0) { struct mii_softc *miisc; @@ -335,16 +343,20 @@ ale_get_macaddr(struct ale_softc *sc) void ale_phy_reset(struct ale_softc *sc) { +// int error; + + printf("%s: called\n", __func__); /* Reset magic from Linux. */ CSR_WRITE_2(sc, ALE_GPHY_CTRL, GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON); - DELAY(1000); + DELAY(2000); CSR_WRITE_2(sc, ALE_GPHY_CTRL, GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON); - DELAY(1000); + DELAY(2000); +#define ATPHY_INT_CTRL 0x12 #define ATPHY_DBG_ADDR 0x1D #define ATPHY_DBG_DATA 0x1E @@ -374,9 +386,10 @@ ale_phy_reset(struct ale_softc *sc) ale_miibus_writereg(sc->sc_dev, sc->ale_phyaddr, ATPHY_DBG_DATA, 0x2C46); + DELAY(1000); + #undef ATPHY_DBG_ADDR #undef ATPHY_DBG_DATA - DELAY(1000); } void @@ -389,7 +402,7 @@ ale_attach(device_t parent, device_t sel const char *intrstr; struct ifnet *ifp; struct mii_data * const mii = &sc->sc_miibus; - pcireg_t memtype; + pcireg_t memtype, pcireg, capoff; int mii_flags, error = 0; uint32_t rxf_len, txf_len; const char *chipname; @@ -423,6 +436,26 @@ ale_attach(device_t parent, device_t sel return; } + pcireg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, + PCI_COMMAND_STATUS_REG); + printf("%s: command = %08x\n", __func__, pcireg); + pcireg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; + pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, pcireg); + +#if 1 + if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &capoff, + NULL) != 0) { + pcireg = pci_conf_read(pa->pa_pc, pa->pa_tag, + PCI_COMMAND_STATUS_REG); + printf("%s: CSR was %#08x\n", __func__, pcireg); + pcireg = pci_conf_read(pa->pa_pc, pa->pa_tag, + capoff + PCI_PMCSR); + printf("%s: PMCSR was %#08x\n", __func__, pcireg); + pci_conf_write(pa->pa_pc, pa->pa_tag, capoff + PCI_PMCSR, 0); + delay(1000); + } +#endif + if (pci_intr_map(pa, &ih) != 0) { aprint_error_dev(self, "could not map interrupt\n"); goto fail; @@ -446,11 +479,6 @@ ale_attach(device_t parent, device_t sel sc->ale_phyaddr = ALE_PHY_ADDR; /* Reset PHY. */ - ale_phy_reset(sc); - - /* Reset the ethernet controller. */ - ale_reset(sc); - /* Get PCI and chip id/revision. */ sc->ale_rev = PCI_REVISION(pa->pa_class); if (sc->ale_rev >= 0xF0) { @@ -470,6 +498,11 @@ ale_attach(device_t parent, device_t sel } aprint_normal_dev(self, "%s, %s\n", chipname, intrstr); + ale_phy_reset(sc); + + /* Reset the ethernet controller. */ + ale_reset(sc); + /* * All known controllers seems to require 4 bytes alignment * of Tx buffers to make Tx checksum offload with custom @@ -1046,13 +1079,13 @@ ale_start(struct ifnet *ifp) struct mbuf *m_head; int enq; - if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) - return; - /* Reclaim transmitted frames. */ if (sc->ale_cdata.ale_tx_cnt >= ALE_TX_DESC_HIWAT) ale_txeof(sc); + if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) + return; + enq = 0; for (;;) { IFQ_DEQUEUE(&ifp->if_snd, m_head); @@ -1248,7 +1281,6 @@ ale_stats_update(struct ale_softc *sc) stat->tx_multi_colls += smb->tx_multi_colls; stat->tx_late_colls += smb->tx_late_colls; stat->tx_excess_colls += smb->tx_excess_colls; - stat->tx_abort += smb->tx_abort; stat->tx_underrun += smb->tx_underrun; stat->tx_desc_underrun += smb->tx_desc_underrun; stat->tx_lenerrs += smb->tx_lenerrs; @@ -1261,17 +1293,10 @@ ale_stats_update(struct ale_softc *sc) ifp->if_collisions += smb->tx_single_colls + smb->tx_multi_colls * 2 + smb->tx_late_colls + - smb->tx_abort * HDPX_CFG_RETRY_DEFAULT; + smb->tx_excess_colls * HDPX_CFG_RETRY_DEFAULT; - /* - * XXX - * tx_pkts_truncated counter looks suspicious. It constantly - * increments with no sign of Tx errors. This may indicate - * the counter name is not correct one so I've removed the - * counter in output errors. - */ - ifp->if_oerrors += smb->tx_abort + smb->tx_late_colls + - smb->tx_underrun; + ifp->if_oerrors += smb->tx_late_colls + smb->tx_excess_colls + + smb->tx_underrun + smb->tx_pkts_truncated; ifp->if_ierrors += smb->rx_crcerrs + smb->rx_lenerrs + smb->rx_runts + smb->rx_pkts_truncated + @@ -1287,6 +1312,7 @@ ale_intr(void *xsc) uint32_t status; status = CSR_READ_4(sc, ALE_INTR_STATUS); + printf("%s: status = %#08x\n", __func__, status); if ((status & ALE_INTRS) == 0) return 0; @@ -1561,6 +1587,7 @@ ale_tick(void *xsc) struct mii_data *mii = &sc->sc_miibus; int s; + printf("%s: called\n", __func__); s = splnet(); mii_tick(mii); ale_stats_update(sc); @@ -1575,10 +1602,8 @@ ale_reset(struct ale_softc *sc) uint32_t reg; int i; - /* Initialize PCIe module. From Linux. */ - CSR_WRITE_4(sc, 0x1008, CSR_READ_4(sc, 0x1008) | 0x8000); + CSR_WRITE_4(sc, ALE_MASTER_CFG, MASTER_LED_MODE | MASTER_RESET); - CSR_WRITE_4(sc, ALE_MASTER_CFG, MASTER_RESET); for (i = ALE_RESET_TIMEOUT; i > 0; i--) { DELAY(10); if ((CSR_READ_4(sc, ALE_MASTER_CFG) & MASTER_RESET) == 0) @@ -1596,6 +1621,9 @@ ale_reset(struct ale_softc *sc) if (i == 0) printf("%s: reset timeout(0x%08x)!\n", device_xname(sc->sc_dev), reg); + + /* Initialize PCIe module. From Linux. */ + CSR_WRITE_4(sc, 0x1008, CSR_READ_4(sc, 0x1008) | 0x8000); } static int @@ -1996,27 +2024,37 @@ ale_rxfilter(struct ale_softc *sc) */ rxcfg |= MAC_CFG_BCAST; - if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) { - ifp->if_flags |= IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC) + /* Program new filter. */ + if ((ifp->if_flags & IFF_PROMISC) != 0) + goto update; + + memset(mchash, 0, sizeof(mchash)); + + ETHER_LOCK(ec); + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + ETHER_UNLOCK(ec); + goto update; + } + crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); + mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); + ETHER_NEXT_MULTI(step, enm); + } + ETHER_UNLOCK(ec); + +update: + if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + if (ifp->if_flags & IFF_PROMISC) { rxcfg |= MAC_CFG_PROMISC; - else + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + } else rxcfg |= MAC_CFG_ALLMULTI; mchash[0] = mchash[1] = 0xFFFFFFFF; - } else { - /* Program new filter. */ - memset(mchash, 0, sizeof(mchash)); - - ETHER_LOCK(ec); - ETHER_FIRST_MULTI(step, ec, enm); - while (enm != NULL) { - crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); - mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); - ETHER_NEXT_MULTI(step, enm); - } - ETHER_UNLOCK(ec); } - CSR_WRITE_4(sc, ALE_MAR0, mchash[0]); CSR_WRITE_4(sc, ALE_MAR1, mchash[1]); CSR_WRITE_4(sc, ALE_MAC_CFG, rxcfg); Index: src/sys/dev/pci/if_cas.c diff -u src/sys/dev/pci/if_cas.c:1.35 src/sys/dev/pci/if_cas.c:1.36 --- src/sys/dev/pci/if_cas.c:1.35 Tue May 28 07:41:49 2019 +++ src/sys/dev/pci/if_cas.c Thu Nov 21 09:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_cas.c,v 1.35 2019/05/28 07:41:49 msaitoh Exp $ */ +/* $NetBSD: if_cas.c,v 1.36 2019/11/21 09:12:30 msaitoh Exp $ */ /* $OpenBSD: if_cas.c,v 1.29 2009/11/29 16:19:38 kettenis Exp $ */ /* @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_cas.c,v 1.35 2019/05/28 07:41:49 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_cas.c,v 1.36 2019/11/21 09:12:30 msaitoh Exp $"); #ifndef _MODULE #include "opt_inet.h" @@ -1905,52 +1905,62 @@ cas_iff(struct cas_softc *sc) CAS_MAC_RX_PROMISC_GRP); ifp->if_flags &= ~IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) { - ifp->if_flags |= IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC) - rxcfg |= CAS_MAC_RX_PROMISCUOUS; - else - rxcfg |= CAS_MAC_RX_PROMISC_GRP; - } else { - /* - * Set up multicast address filter by passing all multicast - * addresses through a crc generator, and then using the - * high order 8 bits as an index into the 256 bit logical - * address filter. The high order 4 bits selects the word, - * while the other 4 bits select the bit within the word - * (where bit 0 is the MSB). - */ + if ((ifp->if_flags & IFF_PROMISC) != 0) + goto update; + + /* + * Set up multicast address filter by passing all multicast + * addresses through a crc generator, and then using the + * high order 8 bits as an index into the 256 bit logical + * address filter. The high order 4 bits selects the word, + * while the other 4 bits select the bit within the word + * (where bit 0 is the MSB). + */ - rxcfg |= CAS_MAC_RX_HASH_FILTER; + /* Clear hash table */ + for (i = 0; i < 16; i++) + hash[i] = 0; - /* Clear hash table */ - for (i = 0; i < 16; i++) - hash[i] = 0; + ETHER_LOCK(ec); + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + ETHER_UNLOCK(ec); + goto update; + } - ETHER_LOCK(ec); - ETHER_FIRST_MULTI(step, ec, enm); - while (enm != NULL) { - crc = ether_crc32_le(enm->enm_addrlo, - ETHER_ADDR_LEN); + crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); - /* Just want the 8 most significant bits. */ - crc >>= 24; + /* Just want the 8 most significant bits. */ + crc >>= 24; - /* Set the corresponding bit in the filter. */ - hash[crc >> 4] |= 1 << (15 - (crc & 15)); + /* Set the corresponding bit in the filter. */ + hash[crc >> 4] |= 1 << (15 - (crc & 15)); - ETHER_NEXT_MULTI(step, enm); - } - ETHER_UNLOCK(ec); + ETHER_NEXT_MULTI(step, enm); + } + ETHER_UNLOCK(ec); - /* Now load the hash table into the chip (if we are using it) */ - for (i = 0; i < 16; i++) { - bus_space_write_4(t, h, - CAS_MAC_HASH0 + i * (CAS_MAC_HASH1 - CAS_MAC_HASH0), - hash[i]); - } + rxcfg |= CAS_MAC_RX_HASH_FILTER; + + /* Now load the hash table into the chip (if we are using it) */ + for (i = 0; i < 16; i++) { + bus_space_write_4(t, h, + CAS_MAC_HASH0 + i * (CAS_MAC_HASH1 - CAS_MAC_HASH0), + hash[i]); } +update: + if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + if (ifp->if_flags & IFF_PROMISC) { + rxcfg |= CAS_MAC_RX_PROMISCUOUS; + /* XXX Use ETHER_F_ALLMULTI in future. */ + ifp->if_flags |= IFF_ALLMULTI; + } else + rxcfg |= CAS_MAC_RX_PROMISC_GRP; + } bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, rxcfg); }