if_vx.c (178469) | if_vx.c (199559) |
---|---|
1/*- 2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 3 * 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 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 3 * 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 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/vx/if_vx.c 178469 2008-04-24 22:51:43Z marius $"); | 34__FBSDID("$FreeBSD: head/sys/dev/vx/if_vx.c 199559 2009-11-19 22:06:40Z jhb $"); |
35 36/* 37 * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support 38 * the 3c590 family. 39 */ 40 41/* 42 * Modified from the FreeBSD 1.1.5.1 version by: --- 81 unchanged lines hidden (view full) --- 124 125static void vx_txstat(struct vx_softc *); 126static int vx_status(struct vx_softc *); 127static void vx_init(void *); 128static void vx_init_locked(struct vx_softc *); 129static int vx_ioctl(struct ifnet *, u_long, caddr_t); 130static void vx_start(struct ifnet *); 131static void vx_start_locked(struct ifnet *); | 35 36/* 37 * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support 38 * the 3c590 family. 39 */ 40 41/* 42 * Modified from the FreeBSD 1.1.5.1 version by: --- 81 unchanged lines hidden (view full) --- 124 125static void vx_txstat(struct vx_softc *); 126static int vx_status(struct vx_softc *); 127static void vx_init(void *); 128static void vx_init_locked(struct vx_softc *); 129static int vx_ioctl(struct ifnet *, u_long, caddr_t); 130static void vx_start(struct ifnet *); 131static void vx_start_locked(struct ifnet *); |
132static void vx_watchdog(struct ifnet *); | 132static void vx_watchdog(void *); |
133static void vx_reset(struct vx_softc *); 134static void vx_read(struct vx_softc *); 135static struct mbuf *vx_get(struct vx_softc *, u_int); 136static void vx_mbuf_fill(void *); 137static void vx_mbuf_empty(struct vx_softc *); 138static void vx_setfilter(struct vx_softc *); 139static void vx_getlink(struct vx_softc *); 140static void vx_setlink(struct vx_softc *); --- 11 unchanged lines hidden (view full) --- 152 device_printf(dev, "can not if_alloc()\n"); 153 return 0; 154 } 155 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 156 157 mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 158 MTX_DEF); 159 callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0); | 133static void vx_reset(struct vx_softc *); 134static void vx_read(struct vx_softc *); 135static struct mbuf *vx_get(struct vx_softc *, u_int); 136static void vx_mbuf_fill(void *); 137static void vx_mbuf_empty(struct vx_softc *); 138static void vx_setfilter(struct vx_softc *); 139static void vx_getlink(struct vx_softc *); 140static void vx_setlink(struct vx_softc *); --- 11 unchanged lines hidden (view full) --- 152 device_printf(dev, "can not if_alloc()\n"); 153 return 0; 154 } 155 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 156 157 mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 158 MTX_DEF); 159 callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0); |
160 callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0); |
|
160 GO_WINDOW(0); 161 CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET); 162 VX_BUSY_WAIT; 163 164 vx_getlink(sc); 165 166 /* 167 * Read the station address from the eeprom --- 20 unchanged lines hidden (view full) --- 188 } 189 190 ifp->if_mtu = ETHERMTU; 191 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 192 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 193 ifp->if_start = vx_start; 194 ifp->if_ioctl = vx_ioctl; 195 ifp->if_init = vx_init; | 161 GO_WINDOW(0); 162 CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET); 163 VX_BUSY_WAIT; 164 165 vx_getlink(sc); 166 167 /* 168 * Read the station address from the eeprom --- 20 unchanged lines hidden (view full) --- 189 } 190 191 ifp->if_mtu = ETHERMTU; 192 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 193 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 194 ifp->if_start = vx_start; 195 ifp->if_ioctl = vx_ioctl; 196 ifp->if_init = vx_init; |
196 ifp->if_watchdog = vx_watchdog; | |
197 ifp->if_softc = sc; 198 199 ether_ifattach(ifp, eaddr); 200 201 sc->vx_tx_start_thresh = 20; /* probably a good starting point. */ 202 203 VX_LOCK(sc); 204 vx_stop(sc); --- 59 unchanged lines hidden (view full) --- 264 CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE); 265 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE); 266 267 vx_mbuf_fill(sc); 268 269 /* Interface is now `running', with no output active. */ 270 ifp->if_drv_flags |= IFF_DRV_RUNNING; 271 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | 197 ifp->if_softc = sc; 198 199 ether_ifattach(ifp, eaddr); 200 201 sc->vx_tx_start_thresh = 20; /* probably a good starting point. */ 202 203 VX_LOCK(sc); 204 vx_stop(sc); --- 59 unchanged lines hidden (view full) --- 264 CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE); 265 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE); 266 267 vx_mbuf_fill(sc); 268 269 /* Interface is now `running', with no output active. */ 270 ifp->if_drv_flags |= IFF_DRV_RUNNING; 271 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
272 callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc); |
|
272 273 /* Attempt to start output, if any. */ 274 vx_start_locked(ifp); 275} 276 277static void 278vx_setfilter(struct vx_softc *sc) 279{ --- 189 unchanged lines hidden (view full) --- 469 } 470 VX_BUSY_WAIT; 471 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 472 CSR_WRITE_2(sc, VX_COMMAND, 473 SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2)); 474 /* not enough room in FIFO - make sure */ 475 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 476 ifp->if_drv_flags |= IFF_DRV_OACTIVE; | 273 274 /* Attempt to start output, if any. */ 275 vx_start_locked(ifp); 276} 277 278static void 279vx_setfilter(struct vx_softc *sc) 280{ --- 189 unchanged lines hidden (view full) --- 470 } 471 VX_BUSY_WAIT; 472 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 473 CSR_WRITE_2(sc, VX_COMMAND, 474 SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2)); 475 /* not enough room in FIFO - make sure */ 476 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 477 ifp->if_drv_flags |= IFF_DRV_OACTIVE; |
477 ifp->if_timer = 1; | 478 sc->vx_timer = 1; |
478 return; 479 } 480 } 481 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); 482 IF_DEQUEUE(&ifp->if_snd, m); 483 if (m == NULL) /* not really needed */ 484 return; 485 --- 22 unchanged lines hidden (view full) --- 508 VX_W1_TX_PIO_WR_1, 509 mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3); 510 m = m_free(m); 511 } 512 while (pad--) 513 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ 514 515 ++ifp->if_opackets; | 479 return; 480 } 481 } 482 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); 483 IF_DEQUEUE(&ifp->if_snd, m); 484 if (m == NULL) /* not really needed */ 485 return; 486 --- 22 unchanged lines hidden (view full) --- 509 VX_W1_TX_PIO_WR_1, 510 mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3); 511 m = m_free(m); 512 } 513 while (pad--) 514 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ 515 516 ++ifp->if_opackets; |
516 ifp->if_timer = 1; | 517 sc->vx_timer = 1; |
517 518readcheck: 519 if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) { 520 /* We received a complete packet. */ 521 522 if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) { 523 /* 524 * No interrupt, read the packet and continue --- 131 unchanged lines hidden (view full) --- 656 * Due to the i386 interrupt queueing, we may get spurious 657 * interrupts occasionally. 658 */ 659 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status); 660 661 if (status & S_RX_COMPLETE) 662 vx_read(sc); 663 if (status & S_TX_AVAIL) { | 518 519readcheck: 520 if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) { 521 /* We received a complete packet. */ 522 523 if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) { 524 /* 525 * No interrupt, read the packet and continue --- 131 unchanged lines hidden (view full) --- 657 * Due to the i386 interrupt queueing, we may get spurious 658 * interrupts occasionally. 659 */ 660 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status); 661 662 if (status & S_RX_COMPLETE) 663 vx_read(sc); 664 if (status & S_TX_AVAIL) { |
664 ifp->if_timer = 0; | 665 sc->vx_timer = 0; |
665 sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 666 vx_start_locked(sc->vx_ifp); 667 } 668 if (status & S_CARD_FAILURE) { 669 if_printf(ifp, "adapter failure (%x)\n", status); | 666 sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 667 vx_start_locked(sc->vx_ifp); 668 } 669 if (status & S_CARD_FAILURE) { 670 if_printf(ifp, "adapter failure (%x)\n", status); |
670 ifp->if_timer = 0; | 671 sc->vx_timer = 0; |
671 vx_reset(sc); 672 break; 673 } 674 if (status & S_TX_COMPLETE) { | 672 vx_reset(sc); 673 break; 674 } 675 if (status & S_TX_COMPLETE) { |
675 ifp->if_timer = 0; | 676 sc->vx_timer = 0; |
676 vx_txstat(sc); 677 vx_start_locked(ifp); 678 } 679 } 680 VX_UNLOCK(sc); 681 682 /* no more interrupts */ 683 return; --- 281 unchanged lines hidden (view full) --- 965{ 966 967 VX_LOCK_ASSERT(sc); 968 vx_stop(sc); 969 vx_init_locked(sc); 970} 971 972static void | 677 vx_txstat(sc); 678 vx_start_locked(ifp); 679 } 680 } 681 VX_UNLOCK(sc); 682 683 /* no more interrupts */ 684 return; --- 281 unchanged lines hidden (view full) --- 966{ 967 968 VX_LOCK_ASSERT(sc); 969 vx_stop(sc); 970 vx_init_locked(sc); 971} 972 973static void |
973vx_watchdog(struct ifnet *ifp) | 974vx_watchdog(void *arg) |
974{ | 975{ |
975 struct vx_softc *sc = ifp->if_softc; | 976 struct vx_softc *sc; 977 struct ifnet *ifp; |
976 | 978 |
977 VX_LOCK(sc); | 979 sc = arg; 980 VX_LOCK_ASSERT(sc); 981 callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc); 982 if (sc->vx_timer == 0 || --sc->vx_timer > 0) 983 return; 984 985 ifp = sc->vx_ifp; |
978 if (ifp->if_flags & IFF_DEBUG) 979 if_printf(ifp, "device timeout\n"); 980 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 981 vx_start_locked(ifp); 982 vx_intr(sc); | 986 if (ifp->if_flags & IFF_DEBUG) 987 if_printf(ifp, "device timeout\n"); 988 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 989 vx_start_locked(ifp); 990 vx_intr(sc); |
983 VX_UNLOCK(sc); | |
984} 985 986void 987vx_stop(struct vx_softc *sc) 988{ | 991} 992 993void 994vx_stop(struct vx_softc *sc) 995{ |
989 struct ifnet *ifp = sc->vx_ifp; | |
990 991 VX_LOCK_ASSERT(sc); | 996 997 VX_LOCK_ASSERT(sc); |
992 ifp->if_timer = 0; | 998 sc->vx_timer = 0; 999 callout_stop(&sc->vx_watchdog); |
993 994 CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE); 995 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); 996 VX_BUSY_WAIT; 997 CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE); 998 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER); 999 DELAY(800); 1000 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET); --- 71 unchanged lines hidden --- | 1000 1001 CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE); 1002 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); 1003 VX_BUSY_WAIT; 1004 CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE); 1005 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER); 1006 DELAY(800); 1007 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET); --- 71 unchanged lines hidden --- |