if_wb.c (199414) | if_wb.c (199560) |
---|---|
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 --- 17 unchanged lines hidden (view full) --- 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 33#include <sys/cdefs.h> | 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 --- 17 unchanged lines hidden (view full) --- 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 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/wb/if_wb.c 199414 2009-11-17 18:22:14Z jhb $"); | 34__FBSDID("$FreeBSD: head/sys/dev/wb/if_wb.c 199560 2009-11-19 22:14:23Z jhb $"); |
35 36/* 37 * Winbond fast ethernet PCI NIC driver 38 * 39 * Supports various cheap network adapters based on the Winbond W89C840F 40 * fast ethernet controller chip. This includes adapters manufactured by 41 * Winbond itself and some made by Linksys. 42 * --- 110 unchanged lines hidden (view full) --- 153static void wb_intr(void *); 154static void wb_tick(void *); 155static void wb_start(struct ifnet *); 156static void wb_start_locked(struct ifnet *); 157static int wb_ioctl(struct ifnet *, u_long, caddr_t); 158static void wb_init(void *); 159static void wb_init_locked(struct wb_softc *); 160static void wb_stop(struct wb_softc *); | 35 36/* 37 * Winbond fast ethernet PCI NIC driver 38 * 39 * Supports various cheap network adapters based on the Winbond W89C840F 40 * fast ethernet controller chip. This includes adapters manufactured by 41 * Winbond itself and some made by Linksys. 42 * --- 110 unchanged lines hidden (view full) --- 153static void wb_intr(void *); 154static void wb_tick(void *); 155static void wb_start(struct ifnet *); 156static void wb_start_locked(struct ifnet *); 157static int wb_ioctl(struct ifnet *, u_long, caddr_t); 158static void wb_init(void *); 159static void wb_init_locked(struct wb_softc *); 160static void wb_stop(struct wb_softc *); |
161static void wb_watchdog(struct ifnet *); | 161static void wb_watchdog(struct wb_softc *); |
162static int wb_shutdown(device_t); 163static int wb_ifmedia_upd(struct ifnet *); 164static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *); 165 166static void wb_eeprom_putbyte(struct wb_softc *, int); 167static void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *); 168static void wb_read_eeprom(struct wb_softc *, caddr_t, int, int, int); 169static void wb_mii_sync(struct wb_softc *); --- 674 unchanged lines hidden (view full) --- 844 goto fail; 845 } 846 ifp->if_softc = sc; 847 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 848 ifp->if_mtu = ETHERMTU; 849 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 850 ifp->if_ioctl = wb_ioctl; 851 ifp->if_start = wb_start; | 162static int wb_shutdown(device_t); 163static int wb_ifmedia_upd(struct ifnet *); 164static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *); 165 166static void wb_eeprom_putbyte(struct wb_softc *, int); 167static void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *); 168static void wb_read_eeprom(struct wb_softc *, caddr_t, int, int, int); 169static void wb_mii_sync(struct wb_softc *); --- 674 unchanged lines hidden (view full) --- 844 goto fail; 845 } 846 ifp->if_softc = sc; 847 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 848 ifp->if_mtu = ETHERMTU; 849 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 850 ifp->if_ioctl = wb_ioctl; 851 ifp->if_start = wb_start; |
852 ifp->if_watchdog = wb_watchdog; | |
853 ifp->if_init = wb_init; 854 ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; 855 856 /* 857 * Do MII setup. 858 */ 859 if (mii_phy_probe(dev, &sc->wb_miibus, 860 wb_ifmedia_upd, wb_ifmedia_sts)) { --- 41 unchanged lines hidden (view full) --- 902 KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized")); 903 ifp = sc->wb_ifp; 904 905 /* 906 * Delete any miibus and phy devices attached to this interface. 907 * This should only be done if attach succeeded. 908 */ 909 if (device_is_attached(dev)) { | 852 ifp->if_init = wb_init; 853 ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; 854 855 /* 856 * Do MII setup. 857 */ 858 if (mii_phy_probe(dev, &sc->wb_miibus, 859 wb_ifmedia_upd, wb_ifmedia_sts)) { --- 41 unchanged lines hidden (view full) --- 901 KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized")); 902 ifp = sc->wb_ifp; 903 904 /* 905 * Delete any miibus and phy devices attached to this interface. 906 * This should only be done if attach succeeded. 907 */ 908 if (device_is_attached(dev)) { |
909 ether_ifdetach(ifp); |
|
910 WB_LOCK(sc); 911 wb_stop(sc); 912 WB_UNLOCK(sc); 913 callout_drain(&sc->wb_stat_callout); | 910 WB_LOCK(sc); 911 wb_stop(sc); 912 WB_UNLOCK(sc); 913 callout_drain(&sc->wb_stat_callout); |
914 ether_ifdetach(ifp); | |
915 } 916 if (sc->wb_miibus) 917 device_delete_child(dev, sc->wb_miibus); 918 bus_generic_detach(dev); 919 920 if (sc->wb_intrhand) 921 bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand); 922 if (sc->wb_irq) --- 229 unchanged lines hidden (view full) --- 1152 struct wb_softc *sc; 1153{ 1154 struct wb_chain *cur_tx; 1155 struct ifnet *ifp; 1156 1157 ifp = sc->wb_ifp; 1158 1159 /* Clear the timeout timer. */ | 914 } 915 if (sc->wb_miibus) 916 device_delete_child(dev, sc->wb_miibus); 917 bus_generic_detach(dev); 918 919 if (sc->wb_intrhand) 920 bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand); 921 if (sc->wb_irq) --- 229 unchanged lines hidden (view full) --- 1151 struct wb_softc *sc; 1152{ 1153 struct wb_chain *cur_tx; 1154 struct ifnet *ifp; 1155 1156 ifp = sc->wb_ifp; 1157 1158 /* Clear the timeout timer. */ |
1160 ifp->if_timer = 0; | 1159 sc->wb_timer = 0; |
1161 1162 if (sc->wb_cdata.wb_tx_head == NULL) 1163 return; 1164 1165 /* 1166 * Go through our tx list and free mbufs for those 1167 * frames that have been transmitted. 1168 */ --- 38 unchanged lines hidden (view full) --- 1207static void 1208wb_txeoc(sc) 1209 struct wb_softc *sc; 1210{ 1211 struct ifnet *ifp; 1212 1213 ifp = sc->wb_ifp; 1214 | 1160 1161 if (sc->wb_cdata.wb_tx_head == NULL) 1162 return; 1163 1164 /* 1165 * Go through our tx list and free mbufs for those 1166 * frames that have been transmitted. 1167 */ --- 38 unchanged lines hidden (view full) --- 1206static void 1207wb_txeoc(sc) 1208 struct wb_softc *sc; 1209{ 1210 struct ifnet *ifp; 1211 1212 ifp = sc->wb_ifp; 1213 |
1215 ifp->if_timer = 0; | 1214 sc->wb_timer = 0; |
1216 1217 if (sc->wb_cdata.wb_tx_head == NULL) { 1218 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1219 sc->wb_cdata.wb_tx_tail = NULL; 1220 } else { 1221 if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) { 1222 WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN; | 1215 1216 if (sc->wb_cdata.wb_tx_head == NULL) { 1217 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1218 sc->wb_cdata.wb_tx_tail = NULL; 1219 } else { 1220 if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) { 1221 WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN; |
1223 ifp->if_timer = 5; | 1222 sc->wb_timer = 5; |
1224 CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF); 1225 } 1226 } 1227 1228 return; 1229} 1230 1231static void --- 92 unchanged lines hidden (view full) --- 1324 struct mii_data *mii; 1325 1326 sc = xsc; 1327 WB_LOCK_ASSERT(sc); 1328 mii = device_get_softc(sc->wb_miibus); 1329 1330 mii_tick(mii); 1331 | 1223 CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF); 1224 } 1225 } 1226 1227 return; 1228} 1229 1230static void --- 92 unchanged lines hidden (view full) --- 1323 struct mii_data *mii; 1324 1325 sc = xsc; 1326 WB_LOCK_ASSERT(sc); 1327 mii = device_get_softc(sc->wb_miibus); 1328 1329 mii_tick(mii); 1330 |
1331 if (sc->wb_timer > 0 && --sc->wb_timer == 0) 1332 wb_watchdog(sc); |
|
1332 callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); 1333 1334 return; 1335} 1336 1337/* 1338 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1339 * pointers to the fragment pointers. --- 184 unchanged lines hidden (view full) --- 1524 * frames. 1525 */ 1526 WB_TXOWN(start_tx) = WB_UNSENT; 1527 } 1528 1529 /* 1530 * Set a timeout in case the chip goes out to lunch. 1531 */ | 1333 callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); 1334 1335 return; 1336} 1337 1338/* 1339 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1340 * pointers to the fragment pointers. --- 184 unchanged lines hidden (view full) --- 1525 * frames. 1526 */ 1527 WB_TXOWN(start_tx) = WB_UNSENT; 1528 } 1529 1530 /* 1531 * Set a timeout in case the chip goes out to lunch. 1532 */ |
1532 ifp->if_timer = 5; | 1533 sc->wb_timer = 5; |
1533 1534 return; 1535} 1536 1537static void 1538wb_init(xsc) 1539 void *xsc; 1540{ --- 202 unchanged lines hidden (view full) --- 1743 error = ether_ioctl(ifp, command, data); 1744 break; 1745 } 1746 1747 return(error); 1748} 1749 1750static void | 1534 1535 return; 1536} 1537 1538static void 1539wb_init(xsc) 1540 void *xsc; 1541{ --- 202 unchanged lines hidden (view full) --- 1744 error = ether_ioctl(ifp, command, data); 1745 break; 1746 } 1747 1748 return(error); 1749} 1750 1751static void |
1751wb_watchdog(ifp) 1752 struct ifnet *ifp; 1753{ | 1752wb_watchdog(sc) |
1754 struct wb_softc *sc; | 1753 struct wb_softc *sc; |
1754{ 1755 struct ifnet *ifp; |
|
1755 | 1756 |
1756 sc = ifp->if_softc; 1757 1758 WB_LOCK(sc); | 1757 WB_LOCK_ASSERT(sc); 1758 ifp = sc->wb_ifp; |
1759 ifp->if_oerrors++; 1760 if_printf(ifp, "watchdog timeout\n"); 1761#ifdef foo 1762 if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) 1763 if_printf(ifp, "no carrier - transceiver cable problem?\n"); 1764#endif 1765 wb_stop(sc); 1766 wb_reset(sc); 1767 wb_init_locked(sc); 1768 1769 if (ifp->if_snd.ifq_head != NULL) 1770 wb_start_locked(ifp); | 1759 ifp->if_oerrors++; 1760 if_printf(ifp, "watchdog timeout\n"); 1761#ifdef foo 1762 if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) 1763 if_printf(ifp, "no carrier - transceiver cable problem?\n"); 1764#endif 1765 wb_stop(sc); 1766 wb_reset(sc); 1767 wb_init_locked(sc); 1768 1769 if (ifp->if_snd.ifq_head != NULL) 1770 wb_start_locked(ifp); |
1771 WB_UNLOCK(sc); | |
1772 1773 return; 1774} 1775 1776/* 1777 * Stop the adapter and free any mbufs allocated to the 1778 * RX and TX lists. 1779 */ 1780static void 1781wb_stop(sc) 1782 struct wb_softc *sc; 1783{ 1784 register int i; 1785 struct ifnet *ifp; 1786 1787 WB_LOCK_ASSERT(sc); 1788 ifp = sc->wb_ifp; | 1771 1772 return; 1773} 1774 1775/* 1776 * Stop the adapter and free any mbufs allocated to the 1777 * RX and TX lists. 1778 */ 1779static void 1780wb_stop(sc) 1781 struct wb_softc *sc; 1782{ 1783 register int i; 1784 struct ifnet *ifp; 1785 1786 WB_LOCK_ASSERT(sc); 1787 ifp = sc->wb_ifp; |
1789 ifp->if_timer = 0; | 1788 sc->wb_timer = 0; |
1790 1791 callout_stop(&sc->wb_stat_callout); 1792 1793 WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON)); 1794 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1795 CSR_WRITE_4(sc, WB_TXADDR, 0x00000000); 1796 CSR_WRITE_4(sc, WB_RXADDR, 0x00000000); 1797 --- 48 unchanged lines hidden --- | 1789 1790 callout_stop(&sc->wb_stat_callout); 1791 1792 WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON)); 1793 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1794 CSR_WRITE_4(sc, WB_TXADDR, 0x00000000); 1795 CSR_WRITE_4(sc, WB_RXADDR, 0x00000000); 1796 --- 48 unchanged lines hidden --- |