Deleted Added
sdiff udiff text old ( 45629 ) new ( 45693 )
full compact
1/*
2 * Copyright (c) 1997, 1998
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * $Id: if_xl.c,v 1.75 1999/04/12 20:23:08 wpaul Exp $
33 */
34
35/*
36 * 3Com 3c90x Etherlink XL PCI NIC driver
37 *
38 * Supports the 3Com "boomerang" and "cyclone" PCI
39 * bus-master chips (3c90x cards and embedded controllers) including
40 * the following:
41 *
42 * 3Com 3c900-TPO 10Mbps/RJ-45
43 * 3Com 3c900-COMBO 10Mbps/RJ-45,AUI,BNC
44 * 3Com 3c905-TX 10/100Mbps/RJ-45
45 * 3Com 3c905-T4 10/100Mbps/RJ-45
46 * 3Com 3c900B-TPO 10Mbps/RJ-45
47 * 3Com 3c900B-COMBO 10Mbps/RJ-45,AUI,BNC
48 * 3Com 3c905B-COMBO 10/100Mbps/RJ-45,AUI,BNC
49 * 3Com 3c905B-TX 10/100Mbps/RJ-45
50 * 3Com 3c905B-FL/FX 10/100Mbps/Fiber-optic
51 * 3Com 3c980-TX 10/100Mbps server adapter
52 * 3Com 3cSOHO100-TX 10/100Mbps/RJ-45
53 * Dell Optiplex GX1 on-board 3c918 10/100Mbps/RJ-45
54 * Dell Precision on-board 3c905B 10/100Mbps/RJ-45
55 * Dell Latitude laptop docking station embedded 3c905-TX

--- 91 unchanged lines hidden (view full) ---

147 * recompile.
148 */
149/* #define XL_BACKGROUND_AUTONEG */
150
151#include <pci/if_xlreg.h>
152
153#if !defined(lint)
154static const char rcsid[] =
155 "$Id: if_xl.c,v 1.75 1999/04/12 20:23:08 wpaul Exp $";
156#endif
157
158/*
159 * Various supported device vendors/types and their names.
160 */
161static struct xl_type xl_devs[] = {
162 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
163 "3Com 3c900-TPO Etherlink XL" },
164 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
165 "3Com 3c900-COMBO Etherlink XL" },
166 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10_100BT,
167 "3Com 3c905-TX Fast Etherlink XL" },
168 { TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
169 "3Com 3c905-T4 Fast Etherlink XL" },
170 { TC_VENDORID, TC_DEVICEID_CYCLONE_10BT,
171 "3Com 3c900B-TPO Etherlink XL" },
172 { TC_VENDORID, TC_DEVICEID_CYCLONE_10BT_COMBO,
173 "3Com 3c900B-COMBO Etherlink XL" },
174 { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT,
175 "3Com 3c905B-TX Fast Etherlink XL" },
176 { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT4,
177 "3Com 3c905B-T4 Fast Etherlink XL" },
178 { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100FX,
179 "3Com 3c905B-FX/SC Fast Etherlink XL" },
180 { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100_COMBO,
181 "3Com 3c905B-COMBO Fast Etherlink XL" },

--- 261 unchanged lines hidden (view full) ---

443 */
444static int xl_mii_writereg(sc, frame)
445 struct xl_softc *sc;
446 struct xl_mii_frame *frame;
447
448{
449 int s;
450
451
452
453 s = splimp();
454 /*
455 * Set up frame for TX.
456 */
457
458 frame->mii_stdelim = XL_MII_STARTDELIM;
459 frame->mii_opcode = XL_MII_WRITEOP;
460 frame->mii_turnaround = XL_MII_TURNAROUND;

--- 282 unchanged lines hidden (view full) ---

743
744/*
745 * Initiate an autonegotiation session.
746 */
747static void xl_autoneg_xmit(sc)
748 struct xl_softc *sc;
749{
750 u_int16_t phy_sts;
751
752 xl_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
753 DELAY(500);
754 while(xl_phy_readreg(sc, XL_PHY_GENCTL)
755 & PHY_BMCR_RESET);
756
757 phy_sts = xl_phy_readreg(sc, PHY_BMCR);
758 phy_sts |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
759 xl_phy_writereg(sc, PHY_BMCR, phy_sts);

--- 525 unchanged lines hidden (view full) ---

1285 printf("xl%d: guessing 10BaseT transceiver\n", sc->xl_unit);
1286 break;
1287 case TC_DEVICEID_BOOMERANG_10BT_COMBO: /* 3c900-COMBO */
1288 case TC_DEVICEID_CYCLONE_10BT_COMBO: /* 3c900B-COMBO */
1289 sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1290 sc->xl_xcvr = XL_XCVR_10BT;
1291 printf("xl%d: guessing COMBO (AUI/BNC/TP)\n", sc->xl_unit);
1292 break;
1293 case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
1294 sc->xl_media = XL_MEDIAOPT_MII;
1295 sc->xl_xcvr = XL_XCVR_MII;
1296 printf("xl%d: guessing MII\n", sc->xl_unit);
1297 break;
1298 case TC_DEVICEID_BOOMERANG_100BT4: /* 3c905-T4 */
1299 case TC_DEVICEID_CYCLONE_10_100BT4: /* 3c905B-T4 */
1300 sc->xl_media = XL_MEDIAOPT_BT4;
1301 sc->xl_xcvr = XL_XCVR_MII;
1302 printf("xl%d: guessing 100BaseT4/MII\n", sc->xl_unit);
1303 break;
1304 case TC_DEVICEID_CYCLONE_10_100BT: /* 3c905B-TX */
1305 case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
1306 case TC_DEVICEID_CYCLONE_10_100BT_SERV: /* 3c980-TX */
1307 case TC_DEVICEID_HURRICANE_SOHO100TX: /* 3cSOHO100-TX */
1308 sc->xl_media = XL_MEDIAOPT_BTX;
1309 sc->xl_xcvr = XL_XCVR_AUTO;
1310 printf("xl%d: guessing 10/100 internal\n", sc->xl_unit);
1311 break;
1312 default:
1313 printf("xl%d: unknown device ID: %x -- "
1314 "defaulting to 10baseT\n", sc->xl_unit, devid);
1315 sc->xl_media = XL_MEDIAOPT_BT;
1316 break;
1317 }
1318
1319 return;

--- 415 unchanged lines hidden (view full) ---

1735 struct xl_chain_data *cd;
1736 struct xl_list_data *ld;
1737 int i;
1738
1739 cd = &sc->xl_cdata;
1740 ld = sc->xl_ldata;
1741 for (i = 0; i < XL_TX_LIST_CNT; i++) {
1742 cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
1743 if (i == (XL_TX_LIST_CNT - 1))
1744 cd->xl_tx_chain[i].xl_next = NULL;
1745 else
1746 cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[i + 1];
1747 }
1748
1749 cd->xl_tx_free = &cd->xl_tx_chain[0];
1750 cd->xl_tx_tail = cd->xl_tx_head = NULL;

--- 133 unchanged lines hidden (view full) ---

1884 * can do in this situation.
1885 */
1886 if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
1887 ifp->if_ierrors++;
1888 cur_rx->xl_ptr->xl_status = 0;
1889 continue;
1890 }
1891
1892 eh = mtod(m, struct ether_header *);
1893 m->m_pkthdr.rcvif = ifp;
1894#if NBPFILTER > 0
1895 /*
1896 * Handle BPF listeners. Let the BPF user see the packet, but
1897 * don't pass it up to the ether_input() layer unless it's
1898 * a broadcast packet, multicast packet, matches our ethernet
1899 * address or the interface is in promiscuous mode.

--- 65 unchanged lines hidden (view full) ---

1965 * know that a frame has been downloaded, but the
1966 * original 3c900/3c905 adapters don't do that.
1967 * Consequently, we have to use a different test if
1968 * xl_type != XL_TYPE_905B.
1969 */
1970 while(sc->xl_cdata.xl_tx_head != NULL) {
1971 cur_tx = sc->xl_cdata.xl_tx_head;
1972 if ((sc->xl_type == XL_TYPE_905B &&
1973 !(cur_tx->xl_ptr->xl_status & XL_TXSTAT_DL_COMPLETE)) ||
1974 CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
1975 break;
1976 }
1977 sc->xl_cdata.xl_tx_head = cur_tx->xl_next;
1978
1979 m_freem(cur_tx->xl_mbuf);
1980 cur_tx->xl_mbuf = NULL;
1981
1982 cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
1983 sc->xl_cdata.xl_tx_free = cur_tx;
1984 }
1985
1986 if (sc->xl_cdata.xl_tx_head == NULL) {
1987 ifp->if_flags &= ~IFF_OACTIVE;
1988 sc->xl_cdata.xl_tx_tail = NULL;
1989 if (sc->xl_want_auto)
1990 xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1);
1991 } else {
1992 if (CSR_READ_4(sc, XL_DMACTL) & XL_DMACTL_DOWN_STALLED ||
1993 !CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
1994 CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
1995 vtophys(sc->xl_cdata.xl_tx_head->xl_ptr));
1996 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
1997 }
1998 }
1999
2000 return;
2001}

--- 129 unchanged lines hidden (view full) ---

2131 p = (u_int8_t *)&xl_stats;
2132
2133 /* Read all the stats registers. */
2134 XL_SEL_WIN(6);
2135
2136 for (i = 0; i < 16; i++)
2137 *p++ = CSR_READ_1(sc, XL_W6_CARRIER_LOST + i);
2138
2139 ifp->if_ipackets += xl_rx_goodframes(xl_stats);
2140 ifp->if_opackets += xl_tx_goodframes(xl_stats);
2141
2142 ifp->if_ierrors += xl_stats.xl_rx_overrun;
2143
2144 ifp->if_collisions += xl_stats.xl_tx_multi_collision +
2145 xl_stats.xl_tx_single_collision +
2146 xl_stats.xl_tx_late_collision;
2147
2148 /*
2149 * Boomerang and cyclone chips have an extra stats counter

--- 167 unchanged lines hidden (view full) ---

2317 * Place the request for the upload interrupt
2318 * in the last descriptor in the chain. This way, if
2319 * we're chaining several packets at once, we'll only
2320 * get an interupt once for the whole chain rather than
2321 * once for each packet.
2322 */
2323 cur_tx->xl_ptr->xl_status |= XL_TXSTAT_DL_INTR;
2324
2325 /*
2326 * Queue the packets. If the TX channel is clear, update
2327 * the downlist pointer register.
2328 */
2329 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
2330 xl_wait(sc);
2331
2332 if (CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
2333 sc->xl_cdata.xl_tx_tail->xl_next = start_tx;
2334 sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next =
2335 vtophys(start_tx->xl_ptr);
2336 sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &=
2337 ~XL_TXSTAT_DL_INTR;
2338 sc->xl_cdata.xl_tx_tail = cur_tx;
2339 } else {
2340 sc->xl_cdata.xl_tx_head = start_tx;
2341 sc->xl_cdata.xl_tx_tail = cur_tx;
2342 CSR_WRITE_4(sc, XL_DOWNLIST_PTR, vtophys(start_tx->xl_ptr));
2343 }
2344 CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
2345
2346 XL_SEL_WIN(7);
2347
2348 /*
2349 * Set a timeout in case the chip goes out to lunch.
2350 */
2351 ifp->if_timer = 5;
2352
2353 /*
2354 * XXX Under certain conditions, usually on slower machines
2355 * where interrupts may be dropped, it's possible for the

--- 207 unchanged lines hidden (view full) ---

2563 struct ifmedia *ifm;
2564
2565 sc = ifp->if_softc;
2566 ifm = &sc->ifmedia;
2567
2568 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
2569 return(EINVAL);
2570
2571 if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
2572 || sc->xl_media & XL_MEDIAOPT_BT4) {
2573 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
2574 xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1);
2575 else
2576 xl_setmode_mii(sc, ifm->ifm_media);
2577 } else {
2578 xl_setmode(sc, ifm->ifm_media);

--- 252 unchanged lines hidden ---