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 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 *); |
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); |
160 callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0); |
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; |
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); |
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; |
478 sc->vx_timer = 1; |
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; |
517 sc->vx_timer = 1; |
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) { |
665 sc->vx_timer = 0; |
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); |
671 sc->vx_timer = 0; |
672 vx_reset(sc); 673 break; 674 } 675 if (status & S_TX_COMPLETE) { |
676 sc->vx_timer = 0; |
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 |
974vx_watchdog(void *arg) |
975{ |
976 struct vx_softc *sc; 977 struct ifnet *ifp; |
978 |
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; |
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); |
991} 992 993void 994vx_stop(struct vx_softc *sc) 995{ |
996 997 VX_LOCK_ASSERT(sc); |
998 sc->vx_timer = 0; 999 callout_stop(&sc->vx_watchdog); |
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 --- |