summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1998-09-08 03:02:59 +0000
committerJason Wright <jason@cvs.openbsd.org>1998-09-08 03:02:59 +0000
commite44014e89d80078f4a9f5f6751beb4e9012c420e (patch)
tree1134c9db045084d60c4f340248e0881208e98204 /sys
parent9ab9afead2fc0558d868c04d776306e3193c9735 (diff)
o Sync with FreeBSD (if_xl.c 1.10)
better handling of memory, typos, 3c980 support o Change tests for 3c980 to match the FreeBSD method in xl_mediacheck() o Added matches for 3c900b and 3c900b-combo (support untested)
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_xl.c112
-rw-r--r--sys/dev/pci/if_xlreg.h6
2 files changed, 80 insertions, 38 deletions
diff --git a/sys/dev/pci/if_xl.c b/sys/dev/pci/if_xl.c
index 9c6fba0200c..73fea4ee386 100644
--- a/sys/dev/pci/if_xl.c
+++ b/sys/dev/pci/if_xl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xl.c,v 1.5 1998/09/04 12:58:12 maja Exp $ */
+/* $OpenBSD: if_xl.c,v 1.6 1998/09/08 03:02:57 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: if_xl.c,v 1.6 1998/08/30 22:24:18 wpaul Exp $
+ * $FreeBSD: if_xl.c,v 1.10 1998/09/06 14:58:46 wpaul Exp $
*/
/*
@@ -45,9 +45,12 @@
* 3Com 3c900-COMBO 10Mbps/RJ-45,AUI,BNC
* 3Com 3c905-TX 10/100Mbps/RJ-45
* 3Com 3c905-T4 10/100Mbps/RJ-45
+ * 3Com 3c900B-TPO 10Mbps/RJ-45
+ * 3Com 3c900B-COMBO 10Mbps/RJ-45,AUI,BNC
* 3Com 3c905B-TX 10/100Mbps/RJ-45
* 3Com 3c905B-FL/FX 10/100Mbps/Fiber-optic
- * Dell Optiplex GX1 on-board 3c905B 10/100Mbps/RJ-45
+ * 3Com 3c980-TX 10/100Mbps server adapter
+ * Dell Optiplex GX1 on-board 3c918 10/100Mbps/RJ-45
* Dell Precision on-board 3c905B 10/100Mbps/RJ-45
* Dell Latitude laptop docking station embedded 3c905-TX
*
@@ -165,7 +168,7 @@
#if !defined(lint) && !defined(__OpenBSD__)
static char rcsid[] =
- "$Id: if_xl.c,v 1.5 1998/09/04 12:58:12 maja Exp $";
+ "$FreeBSD: if_xl.c,v 1.10 1998/09/06 14:58:46 wpaul Exp $";
#endif
#ifdef __FreeBSD__
@@ -182,13 +185,15 @@ static struct xl_type xl_devs[] = {
{ TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
"3Com 3c905 Fast Etherlink XL 10/100BaseT4" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10BT,
- "3Com 3c905B Etherlink XL 10BaseT" },
+ "3Com 3c900B Etherlink XL 10BaseT" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10BT_COMBO,
- "3Com 3c905B Etherlink XL 10BaseT Combo" },
+ "3Com 3c900B Etherlink XL 10BaseT Combo" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT,
"3Com 3c905B Fast Etherlink XL 10/100BaseTX" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT4,
"3Com 3c905B Fast Etherlink XL 10/100BaseT4" },
+ { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT_SERV,
+ "3Com 3c980 Fast Etherlink XL 10/100BaseTX" },
{ 0, 0, NULL }
};
#endif
@@ -1251,15 +1256,28 @@ static void xl_mediacheck(sc)
* XXX I should check for 10baseFL, but I don't have an adapter
* to test with.
*/
- if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO))
- return;
+ if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
+ /*
+ * Check the XCVR value. If it's not in the normal range
+ * of values, we need to fake it up here.
+ */
+ if (sc->xl_xcvr <= XL_XCVR_AUTO)
+ return;
+ else {
+ printf("xl%d: bogus xcvr value "
+ "in EEPROM (%x)\n", sc->xl_unit, sc->xl_xcvr);
+ printf("xl%d: choosing new default based "
+ "on card type\n", sc->xl_unit);
+ }
+ } else {
+ printf("xl%d: WARNING: no media options bits set in "
+ "the media options register!!\n", sc->xl_unit);
+ printf("xl%d: this could be a manufacturing defect in "
+ "your adapter or system\n", sc->xl_unit);
+ printf("xl%d: attempting to guess media type; you "
+ "should probably consult your vendor\n", sc->xl_unit);
+ }
- printf("xl%d: WARNING: no media options bits set in "
- "the media options register!!\n", sc->xl_unit);
- printf("xl%d: this could be a manufacturing defect in "
- "your adapter or system\n", sc->xl_unit);
- printf("xl%d: attempting to guess media type; you "
- "should probably consult your vendor\n", sc->xl_unit);
/*
* Read the device ID from the EEPROM.
@@ -1270,29 +1288,32 @@ static void xl_mediacheck(sc)
switch(devid) {
case TC_DEVICEID_BOOMERANG_10BT: /* 3c900-TP */
- case TC_DEVICEID_CYCLONE_10BT: /* 3c905B-TP */
+ case TC_DEVICEID_CYCLONE_10BT: /* 3c900B-TP */
sc->xl_media = XL_MEDIAOPT_BT;
+ sc->xl_xcvr = XL_XCVR_10BT;
printf("xl%d: guessing 10BaseT transceiver\n", sc->xl_unit);
break;
case TC_DEVICEID_BOOMERANG_10BT_COMBO: /* 3c900-COMBO */
- case TC_DEVICEID_CYCLONE_10BT_COMBO: /* 3c905B-COMBO */
+ case TC_DEVICEID_CYCLONE_10BT_COMBO: /* 3c900B-COMBO */
sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
+ sc->xl_xcvr = XL_XCVR_10BT;
printf("xl%d: guessing COMBO (AUI/BNC/TP)\n", sc->xl_unit);
break;
case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
sc->xl_media = XL_MEDIAOPT_MII;
+ sc->xl_xcvr = XL_XCVR_MII;
printf("xl%d: guessing MII\n", sc->xl_unit);
break;
case TC_DEVICEID_BOOMERANG_100BT4: /* 3c905-T4 */
case TC_DEVICEID_CYCLONE_10_100BT4: /* 3c905B-T4 */
sc->xl_media = XL_MEDIAOPT_BT4;
+ sc->xl_xcvr = XL_XCVR_MII;
printf("xl%d: guessing 100BaseT4/MII\n", sc->xl_unit);
break;
-#if defined(__OpenBSD__)
- case PCI_PRODUCT_3COM_3C980TX: /* 3c980-TX */
-#endif
case TC_DEVICEID_CYCLONE_10_100BT: /* 3c905B-TX */
+ case TC_DEVICEID_CYCLONE_10_100BT_SERV: /* 3c980-TX */
sc->xl_media = XL_MEDIAOPT_BTX;
+ sc->xl_xcvr = XL_XCVR_AUTO;
printf("xl%d: guessing 10/100 internal\n", sc->xl_unit);
break;
default:
@@ -1369,7 +1390,7 @@ xl_attach(config_id, unit)
irq = pci_conf_read(config_id, XL_PCI_INTLINE);
/* Reset the power state. */
- printf("xl%d: chip is is in D%d power mode "
+ printf("xl%d: chip is in D%d power mode "
"-- setting to D0\n", unit, command & XL_PSTATE_MASK);
command &= 0xFFFFFFFC;
pci_conf_write(config_id, XL_PCI_PWRMGMTCTRL, command);
@@ -1493,11 +1514,12 @@ xl_attach(config_id, unit)
printf("xl%d: media options word: %x\n", sc->xl_unit,
sc->xl_media);
- xl_mediacheck(sc);
-
xl_read_eeprom(sc, (char *)&sc->xl_xcvr, XL_EE_ICFG_0, 2, 0);
sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
+
+ xl_mediacheck(sc);
+
if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
|| sc->xl_media & XL_MEDIAOPT_BT4) {
/*
@@ -1721,7 +1743,8 @@ static int xl_list_rx_init(sc)
for (i = 0; i < XL_RX_LIST_CNT; i++) {
cd->xl_rx_chain[i].xl_ptr =
(struct xl_list_onefrag *)&ld->xl_rx_list[i];
- xl_newbuf(sc, &cd->xl_rx_chain[i]);
+ if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
+ return(ENOBUFS);
if (i == (XL_RX_LIST_CNT - 1)) {
cd->xl_rx_chain[i].xl_next = &cd->xl_rx_chain[0];
ld->xl_rx_list[i].xl_next =
@@ -1749,14 +1772,15 @@ static int xl_newbuf(sc, c)
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
- printf("xl%d: no memory for rx list",
- sc->xl_unit);
+ printf("xl%d: no memory for rx list -- packet dropped!\n",
+ sc->xl_unit);
return(ENOBUFS);
}
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
- printf("xl%d: no memory for rx list", sc->xl_unit);
+ printf("xl%d: no memory for rx list -- packet dropped!\n",
+ sc->xl_unit);
m_freem(m_new);
return(ENOBUFS);
}
@@ -1789,6 +1813,8 @@ again:
while((rxstat = sc->xl_cdata.xl_rx_head->xl_ptr->xl_status)) {
cur_rx = sc->xl_cdata.xl_rx_head;
+ sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
+
/*
* If an error occurs, update stats, clear the
* status word and leave the mbuf cluster in place:
@@ -1798,7 +1824,6 @@ again:
if (rxstat & XL_RXSTAT_UP_ERROR) {
ifp->if_ierrors++;
cur_rx->xl_ptr->xl_status = 0;
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
continue;
}
@@ -1812,15 +1837,25 @@ again:
sc->xl_unit);
ifp->if_ierrors++;
cur_rx->xl_ptr->xl_status = 0;
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
continue;
}
/* No errors; receive the packet. */
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
m = cur_rx->xl_mbuf;
total_len = cur_rx->xl_ptr->xl_status & XL_RXSTAT_LENMASK;
- xl_newbuf(sc, cur_rx);
+
+ /*
+ * Try to conjure up a new mbuf cluster. If that
+ * fails, it means we have an out of memory condition and
+ * should leave the buffer in place and continue. This will
+ * result in a lost packet, but there's little else we
+ * can do in this situation.
+ */
+ if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
+ ifp->if_ierrors++;
+ cur_rx->xl_ptr->xl_status = 0;
+ continue;
+ }
eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = ifp;
@@ -1957,7 +1992,8 @@ static void xl_txeoc(sc)
sc->xl_unit, txstat);
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
xl_wait(sc);
- CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
+ if (sc->xl_cdata.xl_tx_head != NULL)
+ CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
vtophys(sc->xl_cdata.xl_tx_head->xl_ptr));
/*
* Remember to set this for the
@@ -2365,8 +2401,10 @@ static void xl_init(xsc)
xl_wait(sc);
/* Init circular RX list. */
- if (xl_list_rx_init(sc)) {
- printf("xl%d: failed to set up rx lists\n", sc->xl_unit);
+ if (xl_list_rx_init(sc) == ENOBUFS) {
+ printf("xl%d: initialization failed: no "
+ "memory for rx buffers\n", sc->xl_unit);
+ xl_stop(sc);
return;
}
@@ -2799,6 +2837,8 @@ xl_probe(parent, match, aux)
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_3COM_3C900TPO:
case PCI_PRODUCT_3COM_3C900COMBO:
+ case PCI_PRODUCT_3COM_3C900B:
+ case PCI_PRODUCT_3COM_3C900BCOMBO:
case PCI_PRODUCT_3COM_3C905TX:
case PCI_PRODUCT_3COM_3C905T4:
case PCI_PRODUCT_3COM_3C905BTX:
@@ -2858,7 +2898,7 @@ xl_attach(parent, self, aux)
XL_PCI_PWRMGMTCTRL);
if (command & XL_PSTATE_MASK) {
/* Reset the power state. */
- printf("%s: chip is is in D%d power mode "
+ printf("%s: chip is in D%d power mode "
"-- setting to D0\n",
sc->sc_dev.dv_xname, command & XL_PSTATE_MASK);
command &= 0xFFFFFFFC;
@@ -2975,11 +3015,13 @@ xl_attach(parent, self, aux)
if (bootverbose)
printf("xl%d: media options word: %x\n",
sc->xl_unit, sc->xl_media);
- xl_mediacheck(sc);
xl_read_eeprom(sc, (char *)&sc->xl_xcvr, XL_EE_ICFG_0, 2, 0);
sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
+
+ xl_mediacheck(sc);
+
if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
|| sc->xl_media & XL_MEDIAOPT_BT4) {
/*
diff --git a/sys/dev/pci/if_xlreg.h b/sys/dev/pci/if_xlreg.h
index f921fb0503f..e9c688a3184 100644
--- a/sys/dev/pci/if_xlreg.h
+++ b/sys/dev/pci/if_xlreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xlreg.h,v 1.3 1998/09/03 06:24:20 jason Exp $ */
+/* $OpenBSD: if_xlreg.h,v 1.4 1998/09/08 03:02:58 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: if_xlreg.h,v 1.3 1998/08/24 17:51:38 wpaul Exp $
+ * $FreeBSD: if_xlreg.h,v 1.4 1998/09/04 16:22:15 wpaul Exp $
*/
#define XL_EE_READ 0x0080 /* read, 5 bit address */
@@ -665,7 +665,7 @@ struct xl_stats {
#define TC_DEVICEID_CYCLONE_10BT_COMBO 0x9005
#define TC_DEVICEID_CYCLONE_10_100BT 0x9055
#define TC_DEVICEID_CYCLONE_10_100BT4 0x9056
-
+#define TC_DEVICEID_CYCLONE_10_100BT_SERV 0x9800
/*
* Texas Instruments PHY identifiers