diff options
author | wpaul <wpaul@FreeBSD.org> | 1999-08-02 21:06:16 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1999-08-02 21:06:16 +0000 |
commit | 257891ab9f791bf4ad243b183a30572083606160 (patch) | |
tree | 27633d7467917fe8fc310ad38a26f7ed947dd885 /sys | |
parent | 8711d2ece04e789ccc10558015c1d4100a3f17e3 (diff) | |
download | FreeBSD-src-257891ab9f791bf4ad243b183a30572083606160.zip FreeBSD-src-257891ab9f791bf4ad243b183a30572083606160.tar.gz |
Perform an RX reset and TX reset in xl_reset() along with the master
reset command.
I observed some anomalous behavior while testing a 3c905C with a
Dell PowerEdge 4300/500 dual PIII 500Mhz system. The NIC would seem
to work correctly most of the time but would sometimes fail to receive
certain packets, in particular NFS create requests. I could mount
an NFS filesystem from the PowerEdge and do an ls on it, but trying
to do a "touch foo" would hang. Monitoring traffic from another host
revealed that the client was properly sending an NFS create request
but the server was not receiving it. It *did* receive it when I
ran the same test with an Intel fxp card.
I don't understand the exact mechanics of this strange behavior, but
resetting the receiver and transmitter seems to get rid of it. I used
to perform an RX and TX reset in xl_init(), but stopped doing it there
because on 3c905B and later cards this causes the autoneg session to
restart, which would lead to the NIC waiting a long time before exchanging
traffic after being brought up the first time. Apparently the receiver
and transmitter resets should be performed at least once when initializing
the card.
Hopefully this will cure problems that people have been having with the
3c905C -- this was the only strange behavior that I have observed with
the 3c905C so far which does not appear with the 3c905B or 3c905.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/pci/if_xl.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 930227e..afc9567 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_xl.c,v 1.44 1999/07/08 00:42:02 wpaul Exp $ + * $Id: if_xl.c,v 1.48 1999/07/23 02:06:57 wpaul Exp $ */ /* @@ -163,7 +163,7 @@ #if !defined(lint) static const char rcsid[] = - "$Id: if_xl.c,v 1.44 1999/07/08 00:42:02 wpaul Exp $"; + "$Id: if_xl.c,v 1.48 1999/07/23 02:06:57 wpaul Exp $"; #endif /* @@ -1261,6 +1261,12 @@ static void xl_reset(sc) if (i == XL_TIMEOUT) printf("xl%d: reset didn't complete\n", sc->xl_unit); + /* Reset TX and RX. */ + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET); + xl_wait(sc); + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET); + xl_wait(sc); + /* Wait a little while for the chip to get its brains in order. */ DELAY(100000); return; @@ -1787,11 +1793,15 @@ static int xl_attach(dev) case XL_XCVR_AUTO: #ifdef XL_BACKGROUND_AUTONEG xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1); + xl_stop(sc); #else - if (cold) + if (cold) { xl_autoneg_mii(sc, XL_FLAG_FORCEDELAY, 1); - else + xl_stop(sc); + } else { + xl_init(sc); xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1); + } #endif media = sc->ifmedia.ifm_media; break; @@ -1799,11 +1809,15 @@ static int xl_attach(dev) case XL_XCVR_MII: #ifdef XL_BACKGROUND_AUTONEG xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1); + xl_stop(sc); #else - if (cold) + if (cold) { xl_autoneg_mii(sc, XL_FLAG_FORCEDELAY, 1); - else + xl_stop(sc); + } else { + xl_init(sc); xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1); + } #endif media = sc->ifmedia.ifm_media; break; @@ -2895,6 +2909,8 @@ static void xl_watchdog(ifp) if (sc->xl_autoneg) { xl_autoneg_mii(sc, XL_FLAG_DELAYTIMEO, 1); + if (!(ifp->if_flags & IFF_UP)) + xl_stop(sc); return; } @@ -2909,6 +2925,7 @@ static void xl_watchdog(ifp) xl_txeoc(sc); xl_txeof(sc); xl_rxeof(sc); + xl_reset(sc); xl_init(sc); if (ifp->if_snd.ifq_head != NULL) |