Index: sys/dev/re/if_re.c =================================================================== --- sys/dev/re/if_re.c (revision 184573) +++ sys/dev/re/if_re.c (working copy) @@ -669,7 +669,12 @@ if (i == RL_TIMEOUT) device_printf(sc->rl_dev, "reset never completed!\n"); - CSR_WRITE_1(sc, 0x82, 1); + if ((sc->rl_flags & RL_FLAG_PHY8169) != 0) + CSR_WRITE_1(sc, 0x82, 1); + if ((sc->rl_flags & RL_FLAG_PHY8110S) != 0) { + CSR_WRITE_1(sc, 0x82, 1); + re_gmii_writereg(sc->rl_dev, 1, 0xb, 0); + } } #ifdef RE_DIAG @@ -725,7 +730,6 @@ ifp->if_flags |= IFF_PROMISC; sc->rl_testmode = 1; - re_reset(sc); re_init_locked(sc); sc->rl_flags |= RL_FLAG_LINK; if (sc->rl_type == RL_8169) @@ -1205,6 +1209,9 @@ case RL_HWREV_8139CPLUS: sc->rl_flags |= RL_FLAG_NOJUMBO; break; + case RL_HWREV_8110S: + sc->rl_flags |= RL_FLAG_PHY8110S; + break; case RL_HWREV_8100E: case RL_HWREV_8101E: sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR | @@ -1214,19 +1221,20 @@ case RL_HWREV_8102EL: sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR | RL_FLAG_PHYWAKE | RL_FLAG_PAR | RL_FLAG_DESCV2 | - RL_FLAG_MACSTAT; + RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP; break; case RL_HWREV_8168_SPIN1: case RL_HWREV_8168_SPIN2: case RL_HWREV_8168_SPIN3: sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE | - RL_FLAG_MACSTAT; + RL_FLAG_MACSTAT | RL_FLAG_WOLRXENB; break; case RL_HWREV_8168C: case RL_HWREV_8168C_SPIN2: case RL_HWREV_8168CP: sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE | - RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT; + RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | + RL_FLAG_CMDSTOP; /* * These controllers support jumbo frame but it seems * that enabling it requires touching additional magic @@ -1239,10 +1247,14 @@ */ sc->rl_flags |= RL_FLAG_NOJUMBO; break; + case RL_HWREV_8169: + case RL_HWREV_8169S: + sc->rl_flags |= RL_FLAG_PHY8169; + 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 | RL_FLAG_PHY8169; break; default: break; @@ -2075,10 +2087,8 @@ * XXX check behaviour on receiver stalls. */ - if (status & RL_ISR_SYSTEM_ERR) { - re_reset(sc); + if (status & RL_ISR_SYSTEM_ERR) re_init_locked(sc); - } } } #endif /* DEVICE_POLLING */ @@ -2142,10 +2152,8 @@ RL_ISR_TX_ERR|RL_ISR_TX_DESC_UNAVAIL)) re_txeof(sc); - if (status & RL_ISR_SYSTEM_ERR) { - re_reset(sc); + if (status & RL_ISR_SYSTEM_ERR) re_init_locked(sc); - } if (status & RL_ISR_LINKCHG) { callout_stop(&sc->rl_stat_callout); @@ -2471,6 +2479,9 @@ */ re_stop(sc); + /* Put controller into known state. */ + re_reset(sc); + /* * Enable C+ RX and TX mode, as well as VLAN stripping and * RX checksum offload. We must configure the C+ register @@ -2846,7 +2857,12 @@ callout_stop(&sc->rl_stat_callout); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - CSR_WRITE_1(sc, RL_COMMAND, 0x00); + if ((sc->rl_flags & RL_FLAG_CMDSTOP) != 0) + CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_STOPREQ | RL_CMD_TX_ENB | + RL_CMD_RX_ENB); + else + CSR_WRITE_1(sc, RL_COMMAND, 0x00); + DELAY(1000); CSR_WRITE_2(sc, RL_IMR, 0x0000); CSR_WRITE_2(sc, RL_ISR, 0xFFFF); @@ -2976,6 +2992,10 @@ return; ifp = sc->rl_ifp; + if ((ifp->if_capenable & IFCAP_WOL) != 0 && + (sc->rl_flags & RL_FLAG_WOLRXENB) != 0) + CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB); + /* Enable config register write. */ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); Index: sys/pci/if_rlreg.h =================================================================== --- sys/pci/if_rlreg.h (revision 184576) +++ sys/pci/if_rlreg.h (working copy) @@ -307,6 +307,7 @@ #define RL_CMD_TX_ENB 0x0004 #define RL_CMD_RX_ENB 0x0008 #define RL_CMD_RESET 0x0010 +#define RL_CMD_STOPREQ 0x0080 /* * Twister register values. These are completely undocumented and derived @@ -881,6 +882,10 @@ #define RL_FLAG_PAR 0x0020 #define RL_FLAG_DESCV2 0x0040 #define RL_FLAG_MACSTAT 0x0080 +#define RL_FLAG_CMDSTOP 0x0100 +#define RL_FLAG_PHY8169 0x0200 +#define RL_FLAG_PHY8110S 0x0400 +#define RL_FLAG_WOLRXENB 0x0800 #define RL_FLAG_LINK 0x8000 };