summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1998-09-25 17:34:19 +0000
committerwpaul <wpaul@FreeBSD.org>1998-09-25 17:34:19 +0000
commit8b137e029a5d733a43c935be787432fc41c80a47 (patch)
tree70fb1fd85e358299272b6316159b56edbb9bc3a4 /sys/pci
parent9f5a84eacbe39a2cd5ee3eb874ef0a194418484c (diff)
downloadFreeBSD-src-8b137e029a5d733a43c935be787432fc41c80a47.zip
FreeBSD-src-8b137e029a5d733a43c935be787432fc41c80a47.tar.gz
Apply patch graciously provided by Jason Wright <jason@thought.net> from
the OpenBSD group to fix a problem with the default ifmedia not being set properly in some cases with a 3c905B, leading to a panic in ifmedia_set(). Also apply a patch to force the transmit start routine to check the transmitter to make sure it isn't wedged if the outbound tx queue appears full. This seems to cure some problems with 'watchdog timeout' errors cropping up in some cases. I tried to do this before by checking for the IFF_OACTIVE flag on entry to xl_start(), but if the IFF_OACTIVE flag is set, ether_output() won't even call xl_start(). It should work now. Lastly, increase the size of the TX queue from 10 descriptors to 16 to hopefully make it less likely that the TX queue will fill up.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_xl.c57
-rw-r--r--sys/pci/if_xlreg.h4
2 files changed, 36 insertions, 25 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c
index 7b24cad..d0923b9 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.53 1998/09/08 16:05:04 wpaul Exp $
+ * $Id: if_xl.c,v 1.11 1998/09/08 23:42:10 wpaul Exp $
*/
/*
@@ -147,7 +147,7 @@
#ifndef lint
static char rcsid[] =
- "$Id: if_xl.c,v 1.53 1998/09/08 16:05:04 wpaul Exp $";
+ "$Id: if_xl.c,v 1.11 1998/09/08 23:42:10 wpaul Exp $";
#endif
/*
@@ -766,6 +766,8 @@ static void xl_autoneg_mii(sc, flag, verbose)
ifm = &sc->ifmedia;
ifp = &sc->arpcom.ac_if;
+ ifm->ifm_media = IFM_ETHER | IFM_AUTO;
+
/*
* The 100baseT4 PHY on the 3c905-T4 has the 'autoneg supported'
* bit cleared in the status register, but has the 'autoneg enabled'
@@ -784,6 +786,14 @@ static void xl_autoneg_mii(sc, flag, verbose)
if (verbose)
printf("xl%d: autonegotiation not supported\n",
sc->xl_unit);
+ ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
+ media = xl_phy_readreg(sc, PHY_BMCR);
+ media &= ~PHY_BMCR_SPEEDSEL;
+ media &= ~PHY_BMCR_DUPLEX;
+ xl_phy_writereg(sc, PHY_BMCR, media);
+ CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
+ (CSR_READ_1(sc, XL_W3_MAC_CTRL) &
+ ~XL_MACCTRL_DUPLEX));
return;
}
#endif
@@ -885,7 +895,14 @@ static void xl_autoneg_mii(sc, flag, verbose)
xl_phy_writereg(sc, PHY_BMCR, media);
} else {
if (verbose)
- printf("no carrier\n");
+ printf("no carrier (forcing half-duplex, 10Mbps)\n");
+ ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
+ media &= ~PHY_BMCR_SPEEDSEL;
+ media &= ~PHY_BMCR_DUPLEX;
+ xl_phy_writereg(sc, PHY_BMCR, media);
+ CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
+ (CSR_READ_1(sc, XL_W3_MAC_CTRL) &
+ ~XL_MACCTRL_DUPLEX));
}
xl_init(sc);
@@ -1615,21 +1632,21 @@ xl_attach(config_id, unit)
xl_setmode(sc, media);
break;
case XL_XCVR_AUTO:
- media = IFM_ETHER|IFM_AUTO;
#ifdef XL_BACKGROUND_AUTONEG
xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1);
#else
xl_autoneg_mii(sc, XL_FLAG_FORCEDELAY, 1);
#endif
+ media = sc->ifmedia.ifm_media;
break;
case XL_XCVR_100BTX:
case XL_XCVR_MII:
- media = sc->ifmedia.ifm_media;
#ifdef XL_BACKGROUND_AUTONEG
xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1);
#else
xl_autoneg_mii(sc, XL_FLAG_FORCEDELAY, 1);
#endif
+ media = sc->ifmedia.ifm_media;
break;
case XL_XCVR_100BFX:
media = IFM_ETHER|IFM_100_FX;
@@ -2192,28 +2209,16 @@ static void xl_start(ifp)
}
/*
- * If the OACTIVE flag is set, make sure the transmitter
- * isn't wedged. Call the txeoc handler to make sure the
- * transmitter is enabled and then call the txeof handler
- * to see if any descriptors can be reclaimed and reload
- * the downlist pointer register if necessary. If after
- * that the OACTIVE flag is still set, return, otherwise
- * proceed and queue up some more frames.
- */
- if (ifp->if_flags & IFF_OACTIVE) {
- xl_txeoc(sc);
- xl_txeof(sc);
- if (ifp->if_flags & IFF_OACTIVE)
- return;
- }
-
- /*
* Check for an available queue slot. If there are none,
* punt.
*/
if (sc->xl_cdata.xl_tx_free == NULL) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
+ xl_txeoc(sc);
+ xl_txeof(sc);
+ if (sc->xl_cdata.xl_tx_free == NULL) {
+ ifp->if_flags |= IFF_OACTIVE;
+ return;
+ }
}
start_tx = sc->xl_cdata.xl_tx_free;
@@ -2653,6 +2658,12 @@ static void xl_watchdog(ifp)
printf("xl%d: no carrier - transceiver cable problem?\n",
sc->xl_unit);
xl_txeoc(sc);
+ xl_txeof(sc);
+ xl_rxeof(sc);
+ xl_init(sc);
+
+ if (ifp->if_snd.ifq_head != NULL)
+ xl_start(ifp);
return;
}
diff --git a/sys/pci/if_xlreg.h b/sys/pci/if_xlreg.h
index 4a6756c..28b3c4e 100644
--- a/sys/pci/if_xlreg.h
+++ b/sys/pci/if_xlreg.h
@@ -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_xlreg.h,v 1.15 1998/09/04 14:43:56 wpaul Exp $
+ * $Id: if_xlreg.h,v 1.4 1998/09/04 16:22:15 wpaul Exp $
*/
#define XL_EE_READ 0x0080 /* read, 5 bit address */
@@ -437,7 +437,7 @@ struct xl_list_onefrag {
#define XL_MAXFRAGS 63
#define XL_RX_LIST_CNT 16
-#define XL_TX_LIST_CNT 10
+#define XL_TX_LIST_CNT 16
#define XL_MIN_FRAMELEN 60
struct xl_list_data {
OpenPOWER on IntegriCloud