--- sys/dev/re/if_re.c.orig +++ sys/dev/re/if_re.c @@ -202,6 +202,7 @@ { RL_HWREV_8169_8110SB, RL_8169, "8169SB"}, { RL_HWREV_8169_8110SC, RL_8169, "8169SC"}, { RL_HWREV_8169_8110SBL, RL_8169, "8169SBL"}, + { RL_HWREV_8169_8110SCE, RL_8169, "8169SC"}, { RL_HWREV_8100, RL_8139, "8100"}, { RL_HWREV_8101, RL_8139, "8101"}, { RL_HWREV_8100E, RL_8169, "8100E"}, @@ -583,20 +584,17 @@ re_setmulti(struct rl_softc *sc) { struct ifnet *ifp; - int h = 0; - u_int32_t hashes[2] = { 0, 0 }; struct ifmultiaddr *ifma; - u_int32_t rxfilt; - int mcnt = 0; + uint32_t hashes[2] = { 0, 0 }; + uint32_t h, rxfilt; RL_LOCK_ASSERT(sc); ifp = sc->rl_ifp; + rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD; - rxfilt = CSR_READ_4(sc, RL_RXCFG); - rxfilt &= ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_MULTI); - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { + if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { if (ifp->if_flags & IFF_PROMISC) rxfilt |= RL_RXCFG_RX_ALLPHYS; /* @@ -605,17 +603,10 @@ * promiscuous mode. */ rxfilt |= RL_RXCFG_RX_MULTI; - CSR_WRITE_4(sc, RL_RXCFG, rxfilt); - CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); - CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); - return; + hashes[0] = hashes[1] = 0xffffffff; + goto done; } - /* first, zot all the existing hash bits */ - CSR_WRITE_4(sc, RL_MAR0, 0); - CSR_WRITE_4(sc, RL_MAR4, 0); - - /* now program new ones */ IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) @@ -626,31 +617,29 @@ hashes[0] |= (1 << h); else hashes[1] |= (1 << (h - 32)); - mcnt++; } IF_ADDR_UNLOCK(ifp); - if (mcnt) + if (hashes[0] != 0 || hashes[1] != 0) { + /* + * For some unfathomable reason, RealTek decided to + * reverse the order of the multicast hash registers + * in the PCI Express parts. This means we have to + * write the hash pattern in reverse order for those + * devices. + */ + if ((sc->rl_flags & RL_FLAG_INVMAR) != 0) { + h = bswap32(hashes[0]); + hashes[0] = bswap32(hashes[1]); + hashes[1] = h; + } rxfilt |= RL_RXCFG_RX_MULTI; - else - rxfilt &= ~RL_RXCFG_RX_MULTI; + } +done: + CSR_WRITE_4(sc, RL_MAR0, hashes[0]); + CSR_WRITE_4(sc, RL_MAR4, hashes[1]); CSR_WRITE_4(sc, RL_RXCFG, rxfilt); - - /* - * For some unfathomable reason, RealTek decided to reverse - * the order of the multicast hash registers in the PCI Express - * parts. This means we have to write the hash pattern in reverse - * order for those devices. - */ - - if ((sc->rl_flags & RL_FLAG_INVMAR) != 0) { - CSR_WRITE_4(sc, RL_MAR0, bswap32(hashes[1])); - CSR_WRITE_4(sc, RL_MAR4, bswap32(hashes[0])); - } else { - CSR_WRITE_4(sc, RL_MAR0, hashes[0]); - CSR_WRITE_4(sc, RL_MAR4, hashes[1]); - } } static void @@ -670,7 +659,16 @@ if (i == RL_TIMEOUT) device_printf(sc->rl_dev, "reset never completed!\n"); - CSR_WRITE_1(sc, 0x82, 1); + if ((sc->rl_flags & (0x0800 | 0x0400)) != 0) + CSR_WRITE_1(sc, 0x82, 1); + pci_write_config(sc->rl_dev, PCIR_LATTIMER, 0x40, 1); + if ((sc->rl_flags & (0x0800 | 0x0400)) != 0) { + pci_write_config(sc->rl_dev, PCIR_CACHELNSZ, 0x08, 1); + if ((sc->rl_flags & 0x0800) != 0) { + CSR_WRITE_1(sc, 0x82, 1); + re_gmii_writereg(sc->rl_dev, 1, 0x0b, 0); + } + } } #ifdef RE_DIAG @@ -1186,9 +1184,18 @@ hw_rev = re_hwrevs; hwrev = CSR_READ_4(sc, RL_TXCFG); - device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000); + switch (hwrev & 0x70000000) { + case 0x00000000: + case 0x10000000: + device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0xfc800000); + hwrev &= RL_TXCFG_HWREV | 0x80000000; + break; + default: + device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000); + hwrev &= RL_TXCFG_HWREV; + break; + } device_printf(dev, "MAC rev. 0x%08x\n", hwrev & 0x00700000); - hwrev &= RL_TXCFG_HWREV; while (hw_rev->rl_desc != NULL) { if (hw_rev->rl_rev == hwrev) { sc->rl_type = hw_rev->rl_type; @@ -1206,6 +1213,9 @@ case RL_HWREV_8139CPLUS: sc->rl_flags |= RL_FLAG_NOJUMBO; break; + case RL_HWREV_8110S: + sc->rl_flags |= 0x0800; + break; case RL_HWREV_8100E: case RL_HWREV_8101E: sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR | @@ -1241,11 +1251,20 @@ */ sc->rl_flags |= RL_FLAG_NOJUMBO; break; + case RL_HWREV_8169: + case RL_HWREV_8169S: + sc->rl_flags |= 0x0400; + break; case RL_HWREV_8169_8110SB: - case RL_HWREV_8169_8110SC: case RL_HWREV_8169_8110SBL: - sc->rl_flags |= RL_FLAG_PHYWAKE; + sc->rl_flags |= RL_FLAG_PHYWAKE | 0x0400; break; + case RL_HWREV_8169_8110SC: + sc->rl_flags |= RL_FLAG_PHYWAKE | 0x0400 | 0x10000; + break; + case RL_HWREV_8169_8110SCE: + sc->rl_flags |= RL_FLAG_PHYWAKE | 0x0400 | 0x10000 | 0x20000; + break; default: break; } @@ -2457,7 +2476,7 @@ { struct ifnet *ifp = sc->rl_ifp; struct mii_data *mii; - u_int32_t rxcfg = 0; + uint32_t reg; uint16_t cfg; union { uint32_t align_dummy; @@ -2490,6 +2509,16 @@ } else cfg |= RL_CPLUSCMD_RXENB | RL_CPLUSCMD_TXENB; CSR_WRITE_2(sc, RL_CPLUS_CMD, cfg); + if ((sc->rl_flags & 0x10000) != 0) { + reg = 0x000fff00; + if ((CSR_READ_1(sc, RL_CFG2) & RL_CFG2_PCI66MHZ) != 0) + reg |= 0x000000ff; + if ((sc->rl_flags & 0x20000) != 0) + reg |= 0x00f00000; + CSR_WRITE_4(sc, 0x7c, reg); + /* Disable interrupt mitigation. */ + CSR_WRITE_2(sc, 0xe2, 0); + } /* * Disable TSO if interface MTU size is greater than MSS * allowed in controller. @@ -2539,7 +2568,7 @@ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); /* - * Set the initial TX and RX configuration. + * Set the initial TX configuration. */ if (sc->rl_testmode) { if (sc->rl_type == RL_8169) @@ -2553,31 +2582,10 @@ CSR_WRITE_1(sc, RL_EARLY_TX_THRESH, 16); - CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); - - /* Set the individual bit to receive frames for this host only. */ - rxcfg = CSR_READ_4(sc, RL_RXCFG); - rxcfg |= RL_RXCFG_RX_INDIV; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - rxcfg |= RL_RXCFG_RX_ALLPHYS; - else - rxcfg &= ~RL_RXCFG_RX_ALLPHYS; - CSR_WRITE_4(sc, RL_RXCFG, rxcfg); - /* - * Set capture broadcast bit to capture broadcast frames. + * Set the initial RX configuration and + * program the multicast filter, if necessary. */ - if (ifp->if_flags & IFF_BROADCAST) - rxcfg |= RL_RXCFG_RX_BROAD; - else - rxcfg &= ~RL_RXCFG_RX_BROAD; - CSR_WRITE_4(sc, RL_RXCFG, rxcfg); - - /* - * Program the multicast filter, if necessary. - */ re_setmulti(sc); #ifdef DEVICE_POLLING --- sys/pci/if_rlreg.h.orig +++ sys/pci/if_rlreg.h @@ -178,6 +178,7 @@ #define RL_HWREV_8101 0x74c00000 #define RL_HWREV_8100 0x78800000 #define RL_HWREV_8169_8110SBL 0x7CC00000 +#define RL_HWREV_8169_8110SCE 0x98000000 #define RL_TXDMA_16BYTES 0x00000000 #define RL_TXDMA_32BYTES 0x00000100