if_wb.c (151545) | if_wb.c (151774) |
---|---|
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/pci/if_wb.c 151545 2005-10-22 05:06:55Z imp $"); | 34__FBSDID("$FreeBSD: head/sys/pci/if_wb.c 151774 2005-10-27 21:22:58Z 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 * --- 105 unchanged lines hidden (view full) --- 148 149static void wb_rxeof(struct wb_softc *); 150static void wb_rxeoc(struct wb_softc *); 151static void wb_txeof(struct wb_softc *); 152static void wb_txeoc(struct wb_softc *); 153static void wb_intr(void *); 154static void wb_tick(void *); 155static void wb_start(struct ifnet *); | 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 * --- 105 unchanged lines hidden (view full) --- 148 149static void wb_rxeof(struct wb_softc *); 150static void wb_rxeoc(struct wb_softc *); 151static void wb_txeof(struct wb_softc *); 152static void wb_txeoc(struct wb_softc *); 153static void wb_intr(void *); 154static void wb_tick(void *); 155static void wb_start(struct ifnet *); |
156static void wb_start_locked(struct ifnet *); |
|
156static int wb_ioctl(struct ifnet *, u_long, caddr_t); 157static void wb_init(void *); | 157static int wb_ioctl(struct ifnet *, u_long, caddr_t); 158static void wb_init(void *); |
159static void wb_init_locked(struct wb_softc *); |
|
158static void wb_stop(struct wb_softc *); 159static void wb_watchdog(struct ifnet *); 160static void wb_shutdown(device_t); 161static int wb_ifmedia_upd(struct ifnet *); 162static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *); 163 164static void wb_eeprom_putbyte(struct wb_softc *, int); 165static void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *); --- 219 unchanged lines hidden (view full) --- 385static int 386wb_mii_readreg(sc, frame) 387 struct wb_softc *sc; 388 struct wb_mii_frame *frame; 389 390{ 391 int i, ack; 392 | 160static void wb_stop(struct wb_softc *); 161static void wb_watchdog(struct ifnet *); 162static void 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 *); --- 219 unchanged lines hidden (view full) --- 387static int 388wb_mii_readreg(sc, frame) 389 struct wb_softc *sc; 390 struct wb_mii_frame *frame; 391 392{ 393 int i, ack; 394 |
393 WB_LOCK(sc); 394 | |
395 /* 396 * Set up frame for RX. 397 */ 398 frame->mii_stdelim = WB_MII_STARTDELIM; 399 frame->mii_opcode = WB_MII_READOP; 400 frame->mii_turnaround = 0; 401 frame->mii_data = 0; 402 --- 61 unchanged lines hidden (view full) --- 464 465fail: 466 467 SIO_CLR(WB_SIO_MII_CLK); 468 DELAY(1); 469 SIO_SET(WB_SIO_MII_CLK); 470 DELAY(1); 471 | 395 /* 396 * Set up frame for RX. 397 */ 398 frame->mii_stdelim = WB_MII_STARTDELIM; 399 frame->mii_opcode = WB_MII_READOP; 400 frame->mii_turnaround = 0; 401 frame->mii_data = 0; 402 --- 61 unchanged lines hidden (view full) --- 464 465fail: 466 467 SIO_CLR(WB_SIO_MII_CLK); 468 DELAY(1); 469 SIO_SET(WB_SIO_MII_CLK); 470 DELAY(1); 471 |
472 WB_UNLOCK(sc); 473 | |
474 if (ack) 475 return(1); 476 return(0); 477} 478 479/* 480 * Write to a PHY register through the MII. 481 */ 482static int 483wb_mii_writereg(sc, frame) 484 struct wb_softc *sc; 485 struct wb_mii_frame *frame; 486 487{ | 472 if (ack) 473 return(1); 474 return(0); 475} 476 477/* 478 * Write to a PHY register through the MII. 479 */ 480static int 481wb_mii_writereg(sc, frame) 482 struct wb_softc *sc; 483 struct wb_mii_frame *frame; 484 485{ |
488 WB_LOCK(sc); | |
489 490 /* 491 * Set up frame for TX. 492 */ 493 494 frame->mii_stdelim = WB_MII_STARTDELIM; 495 frame->mii_opcode = WB_MII_WRITEOP; 496 frame->mii_turnaround = WB_MII_TURNAROUND; --- 18 unchanged lines hidden (view full) --- 515 SIO_CLR(WB_SIO_MII_CLK); 516 DELAY(1); 517 518 /* 519 * Turn off xmit. 520 */ 521 SIO_CLR(WB_SIO_MII_DIR); 522 | 486 487 /* 488 * Set up frame for TX. 489 */ 490 491 frame->mii_stdelim = WB_MII_STARTDELIM; 492 frame->mii_opcode = WB_MII_WRITEOP; 493 frame->mii_turnaround = WB_MII_TURNAROUND; --- 18 unchanged lines hidden (view full) --- 512 SIO_CLR(WB_SIO_MII_CLK); 513 DELAY(1); 514 515 /* 516 * Turn off xmit. 517 */ 518 SIO_CLR(WB_SIO_MII_DIR); 519 |
523 WB_UNLOCK(sc); 524 | |
525 return(0); 526} 527 528static int 529wb_miibus_readreg(dev, phy, reg) 530 device_t dev; 531 int phy, reg; 532{ --- 35 unchanged lines hidden (view full) --- 568static void 569wb_miibus_statchg(dev) 570 device_t dev; 571{ 572 struct wb_softc *sc; 573 struct mii_data *mii; 574 575 sc = device_get_softc(dev); | 520 return(0); 521} 522 523static int 524wb_miibus_readreg(dev, phy, reg) 525 device_t dev; 526 int phy, reg; 527{ --- 35 unchanged lines hidden (view full) --- 563static void 564wb_miibus_statchg(dev) 565 device_t dev; 566{ 567 struct wb_softc *sc; 568 struct mii_data *mii; 569 570 sc = device_get_softc(dev); |
576 WB_LOCK(sc); | |
577 mii = device_get_softc(sc->wb_miibus); 578 wb_setcfg(sc, mii->mii_media_active); | 571 mii = device_get_softc(sc->wb_miibus); 572 wb_setcfg(sc, mii->mii_media_active); |
579 WB_UNLOCK(sc); | |
580 581 return; 582} 583 584/* 585 * Program the 64-bit multicast hash filter. 586 */ 587static void --- 200 unchanged lines hidden (view full) --- 788 u_char eaddr[ETHER_ADDR_LEN]; 789 struct wb_softc *sc; 790 struct ifnet *ifp; 791 int error = 0, rid; 792 793 sc = device_get_softc(dev); 794 795 mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, | 573 574 return; 575} 576 577/* 578 * Program the 64-bit multicast hash filter. 579 */ 580static void --- 200 unchanged lines hidden (view full) --- 781 u_char eaddr[ETHER_ADDR_LEN]; 782 struct wb_softc *sc; 783 struct ifnet *ifp; 784 int error = 0, rid; 785 786 sc = device_get_softc(dev); 787 788 mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, |
796 MTX_DEF | MTX_RECURSE); | 789 MTX_DEF); 790 callout_init_mtx(&sc->wb_stat_callout, &sc->wb_mtx, 0); 791 |
797 /* 798 * Map control/status registers. 799 */ 800 pci_enable_busmaster(dev); 801 802 rid = WB_RID; 803 sc->wb_res = bus_alloc_resource_any(dev, WB_RES, &rid, RF_ACTIVE); 804 --- 43 unchanged lines hidden (view full) --- 848 if (ifp == NULL) { 849 device_printf(dev, "can not if_alloc()\n"); 850 error = ENOSPC; 851 goto fail; 852 } 853 ifp->if_softc = sc; 854 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 855 ifp->if_mtu = ETHERMTU; | 792 /* 793 * Map control/status registers. 794 */ 795 pci_enable_busmaster(dev); 796 797 rid = WB_RID; 798 sc->wb_res = bus_alloc_resource_any(dev, WB_RES, &rid, RF_ACTIVE); 799 --- 43 unchanged lines hidden (view full) --- 843 if (ifp == NULL) { 844 device_printf(dev, "can not if_alloc()\n"); 845 error = ENOSPC; 846 goto fail; 847 } 848 ifp->if_softc = sc; 849 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 850 ifp->if_mtu = ETHERMTU; |
856 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 857 IFF_NEEDSGIANT; | 851 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; |
858 ifp->if_ioctl = wb_ioctl; 859 ifp->if_start = wb_start; 860 ifp->if_watchdog = wb_watchdog; 861 ifp->if_init = wb_init; 862 ifp->if_baudrate = 10000000; 863 ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; 864 865 /* --- 6 unchanged lines hidden (view full) --- 872 } 873 874 /* 875 * Call MI attach routine. 876 */ 877 ether_ifattach(ifp, eaddr); 878 879 /* Hook interrupt last to avoid having to lock softc */ | 852 ifp->if_ioctl = wb_ioctl; 853 ifp->if_start = wb_start; 854 ifp->if_watchdog = wb_watchdog; 855 ifp->if_init = wb_init; 856 ifp->if_baudrate = 10000000; 857 ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; 858 859 /* --- 6 unchanged lines hidden (view full) --- 866 } 867 868 /* 869 * Call MI attach routine. 870 */ 871 ether_ifattach(ifp, eaddr); 872 873 /* Hook interrupt last to avoid having to lock softc */ |
880 error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET, | 874 error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET | INTR_MPSAFE, |
881 wb_intr, sc, &sc->wb_intrhand); 882 883 if (error) { 884 device_printf(dev, "couldn't set up irq\n"); 885 ether_ifdetach(ifp); 886 goto fail; 887 } 888 --- 15 unchanged lines hidden (view full) --- 904wb_detach(dev) 905 device_t dev; 906{ 907 struct wb_softc *sc; 908 struct ifnet *ifp; 909 910 sc = device_get_softc(dev); 911 KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized")); | 875 wb_intr, sc, &sc->wb_intrhand); 876 877 if (error) { 878 device_printf(dev, "couldn't set up irq\n"); 879 ether_ifdetach(ifp); 880 goto fail; 881 } 882 --- 15 unchanged lines hidden (view full) --- 898wb_detach(dev) 899 device_t dev; 900{ 901 struct wb_softc *sc; 902 struct ifnet *ifp; 903 904 sc = device_get_softc(dev); 905 KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized")); |
912 WB_LOCK(sc); | |
913 ifp = sc->wb_ifp; 914 915 /* 916 * Delete any miibus and phy devices attached to this interface. 917 * This should only be done if attach succeeded. 918 */ 919 if (device_is_attached(dev)) { | 906 ifp = sc->wb_ifp; 907 908 /* 909 * Delete any miibus and phy devices attached to this interface. 910 * This should only be done if attach succeeded. 911 */ 912 if (device_is_attached(dev)) { |
913 WB_LOCK(sc); |
|
920 wb_stop(sc); | 914 wb_stop(sc); |
915 WB_UNLOCK(sc); 916 callout_drain(&sc->wb_stat_callout); |
|
921 ether_ifdetach(ifp); 922 } 923 if (sc->wb_miibus) 924 device_delete_child(dev, sc->wb_miibus); 925 bus_generic_detach(dev); 926 927 if (sc->wb_intrhand) 928 bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand); --- 5 unchanged lines hidden (view full) --- 934 if (ifp) 935 if_free(ifp); 936 937 if (sc->wb_ldata) { 938 contigfree(sc->wb_ldata, sizeof(struct wb_list_data) + 8, 939 M_DEVBUF); 940 } 941 | 917 ether_ifdetach(ifp); 918 } 919 if (sc->wb_miibus) 920 device_delete_child(dev, sc->wb_miibus); 921 bus_generic_detach(dev); 922 923 if (sc->wb_intrhand) 924 bus_teardown_intr(dev, sc->wb_irq, sc->wb_intrhand); --- 5 unchanged lines hidden (view full) --- 930 if (ifp) 931 if_free(ifp); 932 933 if (sc->wb_ldata) { 934 contigfree(sc->wb_ldata, sizeof(struct wb_list_data) + 8, 935 M_DEVBUF); 936 } 937 |
942 WB_UNLOCK(sc); | |
943 mtx_destroy(&sc->wb_mtx); 944 945 return(0); 946} 947 948/* 949 * Initialize the transmit descriptors. 950 */ --- 141 unchanged lines hidden (view full) --- 1092 !(rxstat & WB_RXSTAT_LASTFRAG) || 1093 !(rxstat & WB_RXSTAT_RXCMP)) { 1094 ifp->if_ierrors++; 1095 wb_newbuf(sc, cur_rx, m); 1096 if_printf(ifp, "receiver babbling: possible chip " 1097 "bug, forcing reset\n"); 1098 wb_fixmedia(sc); 1099 wb_reset(sc); | 938 mtx_destroy(&sc->wb_mtx); 939 940 return(0); 941} 942 943/* 944 * Initialize the transmit descriptors. 945 */ --- 141 unchanged lines hidden (view full) --- 1087 !(rxstat & WB_RXSTAT_LASTFRAG) || 1088 !(rxstat & WB_RXSTAT_RXCMP)) { 1089 ifp->if_ierrors++; 1090 wb_newbuf(sc, cur_rx, m); 1091 if_printf(ifp, "receiver babbling: possible chip " 1092 "bug, forcing reset\n"); 1093 wb_fixmedia(sc); 1094 wb_reset(sc); |
1100 wb_init(sc); | 1095 wb_init_locked(sc); |
1101 return; 1102 } 1103 1104 if (rxstat & WB_RXSTAT_RXERR) { 1105 ifp->if_ierrors++; 1106 wb_newbuf(sc, cur_rx, m); 1107 break; 1108 } --- 133 unchanged lines hidden (view full) --- 1242 struct wb_softc *sc; 1243 struct ifnet *ifp; 1244 u_int32_t status; 1245 1246 sc = arg; 1247 WB_LOCK(sc); 1248 ifp = sc->wb_ifp; 1249 | 1096 return; 1097 } 1098 1099 if (rxstat & WB_RXSTAT_RXERR) { 1100 ifp->if_ierrors++; 1101 wb_newbuf(sc, cur_rx, m); 1102 break; 1103 } --- 133 unchanged lines hidden (view full) --- 1237 struct wb_softc *sc; 1238 struct ifnet *ifp; 1239 u_int32_t status; 1240 1241 sc = arg; 1242 WB_LOCK(sc); 1243 ifp = sc->wb_ifp; 1244 |
1250 if (!(ifp->if_flags & IFF_UP)) { | 1245 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { |
1251 WB_UNLOCK(sc); 1252 return; 1253 } 1254 1255 /* Disable interrupts. */ 1256 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1257 1258 for (;;) { --- 5 unchanged lines hidden (view full) --- 1264 if ((status & WB_INTRS) == 0) 1265 break; 1266 1267 if ((status & WB_ISR_RX_NOBUF) || (status & WB_ISR_RX_ERR)) { 1268 ifp->if_ierrors++; 1269 wb_reset(sc); 1270 if (status & WB_ISR_RX_ERR) 1271 wb_fixmedia(sc); | 1246 WB_UNLOCK(sc); 1247 return; 1248 } 1249 1250 /* Disable interrupts. */ 1251 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1252 1253 for (;;) { --- 5 unchanged lines hidden (view full) --- 1259 if ((status & WB_INTRS) == 0) 1260 break; 1261 1262 if ((status & WB_ISR_RX_NOBUF) || (status & WB_ISR_RX_ERR)) { 1263 ifp->if_ierrors++; 1264 wb_reset(sc); 1265 if (status & WB_ISR_RX_ERR) 1266 wb_fixmedia(sc); |
1272 wb_init(sc); | 1267 wb_init_locked(sc); |
1273 continue; 1274 } 1275 1276 if (status & WB_ISR_RX_OK) 1277 wb_rxeof(sc); 1278 1279 if (status & WB_ISR_RX_IDLE) 1280 wb_rxeoc(sc); --- 20 unchanged lines hidden (view full) --- 1301 sc->wb_txthresh += WB_TXTHRESH_CHUNK; 1302 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH); 1303 WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh)); 1304 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON); 1305 } 1306 1307 if (status & WB_ISR_BUS_ERR) { 1308 wb_reset(sc); | 1268 continue; 1269 } 1270 1271 if (status & WB_ISR_RX_OK) 1272 wb_rxeof(sc); 1273 1274 if (status & WB_ISR_RX_IDLE) 1275 wb_rxeoc(sc); --- 20 unchanged lines hidden (view full) --- 1296 sc->wb_txthresh += WB_TXTHRESH_CHUNK; 1297 WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH); 1298 WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh)); 1299 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON); 1300 } 1301 1302 if (status & WB_ISR_BUS_ERR) { 1303 wb_reset(sc); |
1309 wb_init(sc); | 1304 wb_init_locked(sc); |
1310 } 1311 1312 } 1313 1314 /* Re-enable interrupts. */ 1315 CSR_WRITE_4(sc, WB_IMR, WB_INTRS); 1316 1317 if (ifp->if_snd.ifq_head != NULL) { | 1305 } 1306 1307 } 1308 1309 /* Re-enable interrupts. */ 1310 CSR_WRITE_4(sc, WB_IMR, WB_INTRS); 1311 1312 if (ifp->if_snd.ifq_head != NULL) { |
1318 wb_start(ifp); | 1313 wb_start_locked(ifp); |
1319 } 1320 1321 WB_UNLOCK(sc); 1322 1323 return; 1324} 1325 1326static void 1327wb_tick(xsc) 1328 void *xsc; 1329{ 1330 struct wb_softc *sc; 1331 struct mii_data *mii; 1332 1333 sc = xsc; | 1314 } 1315 1316 WB_UNLOCK(sc); 1317 1318 return; 1319} 1320 1321static void 1322wb_tick(xsc) 1323 void *xsc; 1324{ 1325 struct wb_softc *sc; 1326 struct mii_data *mii; 1327 1328 sc = xsc; |
1334 WB_LOCK(sc); | 1329 WB_LOCK_ASSERT(sc); |
1335 mii = device_get_softc(sc->wb_miibus); 1336 1337 mii_tick(mii); 1338 | 1330 mii = device_get_softc(sc->wb_miibus); 1331 1332 mii_tick(mii); 1333 |
1339 sc->wb_stat_ch = timeout(wb_tick, sc, hz); | 1334 callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); |
1340 | 1335 |
1341 WB_UNLOCK(sc); 1342 | |
1343 return; 1344} 1345 1346/* 1347 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1348 * pointers to the fragment pointers. 1349 */ 1350static int --- 91 unchanged lines hidden (view full) --- 1442 * physical addresses. 1443 */ 1444 1445static void 1446wb_start(ifp) 1447 struct ifnet *ifp; 1448{ 1449 struct wb_softc *sc; | 1336 return; 1337} 1338 1339/* 1340 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1341 * pointers to the fragment pointers. 1342 */ 1343static int --- 91 unchanged lines hidden (view full) --- 1435 * physical addresses. 1436 */ 1437 1438static void 1439wb_start(ifp) 1440 struct ifnet *ifp; 1441{ 1442 struct wb_softc *sc; |
1443 1444 sc = ifp->if_softc; 1445 WB_LOCK(sc); 1446 wb_start_locked(ifp); 1447 WB_UNLOCK(sc); 1448} 1449 1450static void 1451wb_start_locked(ifp) 1452 struct ifnet *ifp; 1453{ 1454 struct wb_softc *sc; |
|
1450 struct mbuf *m_head = NULL; 1451 struct wb_chain *cur_tx = NULL, *start_tx; 1452 1453 sc = ifp->if_softc; | 1455 struct mbuf *m_head = NULL; 1456 struct wb_chain *cur_tx = NULL, *start_tx; 1457 1458 sc = ifp->if_softc; |
1454 WB_LOCK(sc); | 1459 WB_LOCK_ASSERT(sc); |
1455 1456 /* 1457 * Check for an available queue slot. If there are none, 1458 * punt. 1459 */ 1460 if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) { 1461 ifp->if_drv_flags |= IFF_DRV_OACTIVE; | 1460 1461 /* 1462 * Check for an available queue slot. If there are none, 1463 * punt. 1464 */ 1465 if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) { 1466 ifp->if_drv_flags |= IFF_DRV_OACTIVE; |
1462 WB_UNLOCK(sc); | |
1463 return; 1464 } 1465 1466 start_tx = sc->wb_cdata.wb_tx_free; 1467 1468 while(sc->wb_cdata.wb_tx_free->wb_mbuf == NULL) { 1469 IF_DEQUEUE(&ifp->if_snd, m_head); 1470 if (m_head == NULL) --- 14 unchanged lines hidden (view full) --- 1485 * to him. 1486 */ 1487 BPF_MTAP(ifp, cur_tx->wb_mbuf); 1488 } 1489 1490 /* 1491 * If there are no packets queued, bail. 1492 */ | 1467 return; 1468 } 1469 1470 start_tx = sc->wb_cdata.wb_tx_free; 1471 1472 while(sc->wb_cdata.wb_tx_free->wb_mbuf == NULL) { 1473 IF_DEQUEUE(&ifp->if_snd, m_head); 1474 if (m_head == NULL) --- 14 unchanged lines hidden (view full) --- 1489 * to him. 1490 */ 1491 BPF_MTAP(ifp, cur_tx->wb_mbuf); 1492 } 1493 1494 /* 1495 * If there are no packets queued, bail. 1496 */ |
1493 if (cur_tx == NULL) { 1494 WB_UNLOCK(sc); | 1497 if (cur_tx == NULL) |
1495 return; | 1498 return; |
1496 } | |
1497 1498 /* 1499 * Place the request for the upload interrupt 1500 * in the last descriptor in the chain. This way, if 1501 * we're chaining several packets at once, we'll only 1502 * get an interupt once for the whole chain rather than 1503 * once for each packet. 1504 */ --- 20 unchanged lines hidden (view full) --- 1525 */ 1526 WB_TXOWN(start_tx) = WB_UNSENT; 1527 } 1528 1529 /* 1530 * Set a timeout in case the chip goes out to lunch. 1531 */ 1532 ifp->if_timer = 5; | 1499 1500 /* 1501 * Place the request for the upload interrupt 1502 * in the last descriptor in the chain. This way, if 1503 * we're chaining several packets at once, we'll only 1504 * get an interupt once for the whole chain rather than 1505 * once for each packet. 1506 */ --- 20 unchanged lines hidden (view full) --- 1527 */ 1528 WB_TXOWN(start_tx) = WB_UNSENT; 1529 } 1530 1531 /* 1532 * Set a timeout in case the chip goes out to lunch. 1533 */ 1534 ifp->if_timer = 5; |
1533 WB_UNLOCK(sc); | |
1534 1535 return; 1536} 1537 1538static void 1539wb_init(xsc) 1540 void *xsc; 1541{ 1542 struct wb_softc *sc = xsc; | 1535 1536 return; 1537} 1538 1539static void 1540wb_init(xsc) 1541 void *xsc; 1542{ 1543 struct wb_softc *sc = xsc; |
1544 1545 WB_LOCK(sc); 1546 wb_init_locked(sc); 1547 WB_UNLOCK(sc); 1548} 1549 1550static void 1551wb_init_locked(sc) 1552 struct wb_softc *sc; 1553{ |
|
1543 struct ifnet *ifp = sc->wb_ifp; 1544 int i; 1545 struct mii_data *mii; 1546 | 1554 struct ifnet *ifp = sc->wb_ifp; 1555 int i; 1556 struct mii_data *mii; 1557 |
1547 WB_LOCK(sc); | 1558 WB_LOCK_ASSERT(sc); |
1548 mii = device_get_softc(sc->wb_miibus); 1549 1550 /* 1551 * Cancel pending I/O and free all RX/TX buffers. 1552 */ 1553 wb_stop(sc); 1554 wb_reset(sc); 1555 --- 34 unchanged lines hidden (view full) --- 1590 CSR_WRITE_1(sc, WB_NODE0 + i, IFP2ENADDR(sc->wb_ifp)[i]); 1591 } 1592 1593 /* Init circular RX list. */ 1594 if (wb_list_rx_init(sc) == ENOBUFS) { 1595 if_printf(ifp, 1596 "initialization failed: no memory for rx buffers\n"); 1597 wb_stop(sc); | 1559 mii = device_get_softc(sc->wb_miibus); 1560 1561 /* 1562 * Cancel pending I/O and free all RX/TX buffers. 1563 */ 1564 wb_stop(sc); 1565 wb_reset(sc); 1566 --- 34 unchanged lines hidden (view full) --- 1601 CSR_WRITE_1(sc, WB_NODE0 + i, IFP2ENADDR(sc->wb_ifp)[i]); 1602 } 1603 1604 /* Init circular RX list. */ 1605 if (wb_list_rx_init(sc) == ENOBUFS) { 1606 if_printf(ifp, 1607 "initialization failed: no memory for rx buffers\n"); 1608 wb_stop(sc); |
1598 WB_UNLOCK(sc); | |
1599 return; 1600 } 1601 1602 /* Init TX descriptors. */ 1603 wb_list_tx_init(sc); 1604 1605 /* If we want promiscuous mode, set the allframes bit. */ 1606 if (ifp->if_flags & IFF_PROMISC) { --- 36 unchanged lines hidden (view full) --- 1643 CSR_WRITE_4(sc, WB_TXADDR, vtophys(&sc->wb_ldata->wb_tx_list[0])); 1644 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON); 1645 1646 mii_mediachg(mii); 1647 1648 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1649 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1650 | 1609 return; 1610 } 1611 1612 /* Init TX descriptors. */ 1613 wb_list_tx_init(sc); 1614 1615 /* If we want promiscuous mode, set the allframes bit. */ 1616 if (ifp->if_flags & IFF_PROMISC) { --- 36 unchanged lines hidden (view full) --- 1653 CSR_WRITE_4(sc, WB_TXADDR, vtophys(&sc->wb_ldata->wb_tx_list[0])); 1654 WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON); 1655 1656 mii_mediachg(mii); 1657 1658 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1659 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1660 |
1651 sc->wb_stat_ch = timeout(wb_tick, sc, hz); 1652 WB_UNLOCK(sc); | 1661 callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); |
1653 1654 return; 1655} 1656 1657/* 1658 * Set media options. 1659 */ 1660static int 1661wb_ifmedia_upd(ifp) 1662 struct ifnet *ifp; 1663{ 1664 struct wb_softc *sc; 1665 1666 sc = ifp->if_softc; 1667 | 1662 1663 return; 1664} 1665 1666/* 1667 * Set media options. 1668 */ 1669static int 1670wb_ifmedia_upd(ifp) 1671 struct ifnet *ifp; 1672{ 1673 struct wb_softc *sc; 1674 1675 sc = ifp->if_softc; 1676 |
1677 WB_LOCK(sc); |
|
1668 if (ifp->if_flags & IFF_UP) | 1678 if (ifp->if_flags & IFF_UP) |
1669 wb_init(sc); | 1679 wb_init_locked(sc); 1680 WB_UNLOCK(sc); |
1670 1671 return(0); 1672} 1673 1674/* 1675 * Report current media status. 1676 */ 1677static void 1678wb_ifmedia_sts(ifp, ifmr) 1679 struct ifnet *ifp; 1680 struct ifmediareq *ifmr; 1681{ 1682 struct wb_softc *sc; 1683 struct mii_data *mii; 1684 1685 sc = ifp->if_softc; 1686 | 1681 1682 return(0); 1683} 1684 1685/* 1686 * Report current media status. 1687 */ 1688static void 1689wb_ifmedia_sts(ifp, ifmr) 1690 struct ifnet *ifp; 1691 struct ifmediareq *ifmr; 1692{ 1693 struct wb_softc *sc; 1694 struct mii_data *mii; 1695 1696 sc = ifp->if_softc; 1697 |
1698 WB_LOCK(sc); |
|
1687 mii = device_get_softc(sc->wb_miibus); 1688 1689 mii_pollstat(mii); 1690 ifmr->ifm_active = mii->mii_media_active; 1691 ifmr->ifm_status = mii->mii_media_status; | 1699 mii = device_get_softc(sc->wb_miibus); 1700 1701 mii_pollstat(mii); 1702 ifmr->ifm_active = mii->mii_media_active; 1703 ifmr->ifm_status = mii->mii_media_status; |
1704 WB_UNLOCK(sc); |
|
1692 1693 return; 1694} 1695 1696static int 1697wb_ioctl(ifp, command, data) 1698 struct ifnet *ifp; 1699 u_long command; 1700 caddr_t data; 1701{ 1702 struct wb_softc *sc = ifp->if_softc; 1703 struct mii_data *mii; 1704 struct ifreq *ifr = (struct ifreq *) data; 1705 int error = 0; 1706 | 1705 1706 return; 1707} 1708 1709static int 1710wb_ioctl(ifp, command, data) 1711 struct ifnet *ifp; 1712 u_long command; 1713 caddr_t data; 1714{ 1715 struct wb_softc *sc = ifp->if_softc; 1716 struct mii_data *mii; 1717 struct ifreq *ifr = (struct ifreq *) data; 1718 int error = 0; 1719 |
1707 WB_LOCK(sc); 1708 | |
1709 switch(command) { 1710 case SIOCSIFFLAGS: | 1720 switch(command) { 1721 case SIOCSIFFLAGS: |
1722 WB_LOCK(sc); |
|
1711 if (ifp->if_flags & IFF_UP) { | 1723 if (ifp->if_flags & IFF_UP) { |
1712 wb_init(sc); | 1724 wb_init_locked(sc); |
1713 } else { 1714 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1715 wb_stop(sc); 1716 } | 1725 } else { 1726 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1727 wb_stop(sc); 1728 } |
1729 WB_UNLOCK(sc); |
|
1717 error = 0; 1718 break; 1719 case SIOCADDMULTI: 1720 case SIOCDELMULTI: | 1730 error = 0; 1731 break; 1732 case SIOCADDMULTI: 1733 case SIOCDELMULTI: |
1734 WB_LOCK(sc); |
|
1721 wb_setmulti(sc); | 1735 wb_setmulti(sc); |
1736 WB_UNLOCK(sc); |
|
1722 error = 0; 1723 break; 1724 case SIOCGIFMEDIA: 1725 case SIOCSIFMEDIA: 1726 mii = device_get_softc(sc->wb_miibus); 1727 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 1728 break; 1729 default: --- 18 unchanged lines hidden (view full) --- 1748 ifp->if_oerrors++; 1749 if_printf(ifp, "watchdog timeout\n"); 1750#ifdef foo 1751 if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) 1752 if_printf(ifp, "no carrier - transceiver cable problem?\n"); 1753#endif 1754 wb_stop(sc); 1755 wb_reset(sc); | 1737 error = 0; 1738 break; 1739 case SIOCGIFMEDIA: 1740 case SIOCSIFMEDIA: 1741 mii = device_get_softc(sc->wb_miibus); 1742 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 1743 break; 1744 default: --- 18 unchanged lines hidden (view full) --- 1763 ifp->if_oerrors++; 1764 if_printf(ifp, "watchdog timeout\n"); 1765#ifdef foo 1766 if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) 1767 if_printf(ifp, "no carrier - transceiver cable problem?\n"); 1768#endif 1769 wb_stop(sc); 1770 wb_reset(sc); |
1756 wb_init(sc); | 1771 wb_init_locked(sc); |
1757 1758 if (ifp->if_snd.ifq_head != NULL) | 1772 1773 if (ifp->if_snd.ifq_head != NULL) |
1759 wb_start(ifp); | 1774 wb_start_locked(ifp); |
1760 WB_UNLOCK(sc); 1761 1762 return; 1763} 1764 1765/* 1766 * Stop the adapter and free any mbufs allocated to the 1767 * RX and TX lists. 1768 */ 1769static void 1770wb_stop(sc) 1771 struct wb_softc *sc; 1772{ 1773 register int i; 1774 struct ifnet *ifp; 1775 | 1775 WB_UNLOCK(sc); 1776 1777 return; 1778} 1779 1780/* 1781 * Stop the adapter and free any mbufs allocated to the 1782 * RX and TX lists. 1783 */ 1784static void 1785wb_stop(sc) 1786 struct wb_softc *sc; 1787{ 1788 register int i; 1789 struct ifnet *ifp; 1790 |
1776 WB_LOCK(sc); | 1791 WB_LOCK_ASSERT(sc); |
1777 ifp = sc->wb_ifp; 1778 ifp->if_timer = 0; 1779 | 1792 ifp = sc->wb_ifp; 1793 ifp->if_timer = 0; 1794 |
1780 untimeout(wb_tick, sc, sc->wb_stat_ch); | 1795 callout_stop(&sc->wb_stat_callout); |
1781 1782 WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON)); 1783 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1784 CSR_WRITE_4(sc, WB_TXADDR, 0x00000000); 1785 CSR_WRITE_4(sc, WB_RXADDR, 0x00000000); 1786 1787 /* 1788 * Free data in the RX lists. --- 16 unchanged lines hidden (view full) --- 1805 sc->wb_cdata.wb_tx_chain[i].wb_mbuf = NULL; 1806 } 1807 } 1808 1809 bzero((char *)&sc->wb_ldata->wb_tx_list, 1810 sizeof(sc->wb_ldata->wb_tx_list)); 1811 1812 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); | 1796 1797 WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON)); 1798 CSR_WRITE_4(sc, WB_IMR, 0x00000000); 1799 CSR_WRITE_4(sc, WB_TXADDR, 0x00000000); 1800 CSR_WRITE_4(sc, WB_RXADDR, 0x00000000); 1801 1802 /* 1803 * Free data in the RX lists. --- 16 unchanged lines hidden (view full) --- 1820 sc->wb_cdata.wb_tx_chain[i].wb_mbuf = NULL; 1821 } 1822 } 1823 1824 bzero((char *)&sc->wb_ldata->wb_tx_list, 1825 sizeof(sc->wb_ldata->wb_tx_list)); 1826 1827 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); |
1813 WB_UNLOCK(sc); | |
1814 1815 return; 1816} 1817 1818/* 1819 * Stop all chip I/O so that the kernel's probe routines don't 1820 * get confused by errant DMAs when rebooting. 1821 */ 1822static void 1823wb_shutdown(dev) 1824 device_t dev; 1825{ 1826 struct wb_softc *sc; 1827 1828 sc = device_get_softc(dev); | 1828 1829 return; 1830} 1831 1832/* 1833 * Stop all chip I/O so that the kernel's probe routines don't 1834 * get confused by errant DMAs when rebooting. 1835 */ 1836static void 1837wb_shutdown(dev) 1838 device_t dev; 1839{ 1840 struct wb_softc *sc; 1841 1842 sc = device_get_softc(dev); |
1843 1844 WB_LOCK(sc); |
|
1829 wb_stop(sc); | 1845 wb_stop(sc); |
1846 WB_UNLOCK(sc); |
|
1830 1831 return; 1832} | 1847 1848 return; 1849} |