summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1999-08-02 21:06:16 +0000
committerwpaul <wpaul@FreeBSD.org>1999-08-02 21:06:16 +0000
commit257891ab9f791bf4ad243b183a30572083606160 (patch)
tree27633d7467917fe8fc310ad38a26f7ed947dd885 /sys/pci
parent8711d2ece04e789ccc10558015c1d4100a3f17e3 (diff)
downloadFreeBSD-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/pci')
-rw-r--r--sys/pci/if_xl.c29
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)
OpenPOWER on IntegriCloud