diff options
author | wpaul <wpaul@FreeBSD.org> | 1998-09-25 17:34:19 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1998-09-25 17:34:19 +0000 |
commit | 8b137e029a5d733a43c935be787432fc41c80a47 (patch) | |
tree | 70fb1fd85e358299272b6316159b56edbb9bc3a4 /sys/pci | |
parent | 9f5a84eacbe39a2cd5ee3eb874ef0a194418484c (diff) | |
download | FreeBSD-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.c | 57 | ||||
-rw-r--r-- | sys/pci/if_xlreg.h | 4 |
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 { |