1/*- 2 * Copyright (c) 2000 Berkeley Software Design, Inc. 3 * Copyright (c) 1997, 1998, 1999, 2000 4 * Bill Paul <wpaul@osd.bsdi.com>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/dev/pcn/if_pcn.c 199560 2009-11-19 22:14:23Z jhb $"); |
36 37/* 38 * AMD Am79c972 fast ethernet PCI NIC driver. Datasheets are available 39 * from http://www.amd.com. 40 * 41 * The AMD PCnet/PCI controllers are more advanced and functional 42 * versions of the venerable 7990 LANCE. The PCnet/PCI chips retain 43 * backwards compatibility with the LANCE and thus can be made --- 94 unchanged lines hidden (view full) --- 138static void pcn_intr(void *); 139static void pcn_tick(void *); 140static void pcn_start(struct ifnet *); 141static void pcn_start_locked(struct ifnet *); 142static int pcn_ioctl(struct ifnet *, u_long, caddr_t); 143static void pcn_init(void *); 144static void pcn_init_locked(struct pcn_softc *); 145static void pcn_stop(struct pcn_softc *); |
146static void pcn_watchdog(struct pcn_softc *); |
147static int pcn_shutdown(device_t); 148static int pcn_ifmedia_upd(struct ifnet *); 149static void pcn_ifmedia_sts(struct ifnet *, struct ifmediareq *); 150 151static int pcn_miibus_readreg(device_t, int, int); 152static int pcn_miibus_writereg(device_t, int, int, int); 153static void pcn_miibus_statchg(device_t); 154 --- 470 unchanged lines hidden (view full) --- 625 error = ENOSPC; 626 goto fail; 627 } 628 ifp->if_softc = sc; 629 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 630 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 631 ifp->if_ioctl = pcn_ioctl; 632 ifp->if_start = pcn_start; |
633 ifp->if_init = pcn_init; 634 ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1; 635 636 /* 637 * Do MII setup. 638 */ 639 sc->pcn_extphyaddr = -1; 640 if (mii_phy_probe(dev, &sc->pcn_miibus, --- 301 unchanged lines hidden (view full) --- 942 PCN_INC(idx, PCN_TX_LIST_CNT); 943 } 944 945 if (idx != sc->pcn_cdata.pcn_tx_cons) { 946 /* Some buffers have been freed. */ 947 sc->pcn_cdata.pcn_tx_cons = idx; 948 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 949 } |
950 sc->pcn_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5; |
951 952 return; 953} 954 955static void 956pcn_tick(xsc) 957 void *xsc; 958{ --- 15 unchanged lines hidden (view full) --- 974 /* link just came up, restart */ 975 if (!sc->pcn_link && mii->mii_media_status & IFM_ACTIVE && 976 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 977 sc->pcn_link++; 978 if (ifp->if_snd.ifq_head != NULL) 979 pcn_start_locked(ifp); 980 } 981 |
982 if (sc->pcn_timer > 0 && --sc->pcn_timer == 0) 983 pcn_watchdog(sc); |
984 callout_reset(&sc->pcn_stat_callout, hz, pcn_tick, sc); 985 986 return; 987} 988 989static void 990pcn_intr(arg) 991 void *arg; --- 151 unchanged lines hidden (view full) --- 1143 1144 /* Transmit */ 1145 sc->pcn_cdata.pcn_tx_prod = idx; 1146 pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_TX|PCN_CSR_INTEN); 1147 1148 /* 1149 * Set a timeout in case the chip goes out to lunch. 1150 */ |
1151 sc->pcn_timer = 5; |
1152 1153 return; 1154} 1155 1156static void 1157pcn_setfilt(ifp) 1158 struct ifnet *ifp; 1159{ --- 265 unchanged lines hidden (view full) --- 1425 error = ether_ioctl(ifp, command, data); 1426 break; 1427 } 1428 1429 return(error); 1430} 1431 1432static void |
1433pcn_watchdog(struct pcn_softc *sc) |
1434{ |
1435 struct ifnet *ifp; |
1436 |
1437 PCN_LOCK_ASSERT(sc); 1438 ifp = sc->pcn_ifp; |
1439 |
1440 ifp->if_oerrors++; 1441 if_printf(ifp, "watchdog timeout\n"); 1442 1443 pcn_stop(sc); 1444 pcn_reset(sc); 1445 pcn_init_locked(sc); 1446 1447 if (ifp->if_snd.ifq_head != NULL) 1448 pcn_start_locked(ifp); |
1449} 1450 1451/* 1452 * Stop the adapter and free any mbufs allocated to the 1453 * RX and TX lists. 1454 */ 1455static void 1456pcn_stop(struct pcn_softc *sc) 1457{ 1458 register int i; 1459 struct ifnet *ifp; 1460 1461 PCN_LOCK_ASSERT(sc); 1462 ifp = sc->pcn_ifp; |
1463 sc->pcn_timer = 0; |
1464 1465 callout_stop(&sc->pcn_stat_callout); 1466 1467 /* Turn off interrupts */ 1468 PCN_CSR_CLRBIT(sc, PCN_CSR_CSR, PCN_CSR_INTEN); 1469 /* Stop adapter */ 1470 PCN_CSR_SETBIT(sc, PCN_CSR_CSR, PCN_CSR_STOP); 1471 sc->pcn_link = 0; --- 49 unchanged lines hidden --- |