if_vx.c (79885) | if_vx.c (90227) |
---|---|
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 --- 13 unchanged lines hidden (view full) --- 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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 * | 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 --- 13 unchanged lines hidden (view full) --- 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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 * $FreeBSD: head/sys/dev/vx/if_vx.c 79885 2001-07-19 02:16:24Z kris $ | 30 * $FreeBSD: head/sys/dev/vx/if_vx.c 90227 2002-02-05 02:00:56Z dillon $ |
31 * 32 */ 33 34/* 35 * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support 36 * the 3c590 family. 37 */ 38 --- 346 unchanged lines hidden (view full) --- 385 prev_conn = i; 386} 387 388static void 389vxstart(ifp) 390 struct ifnet *ifp; 391{ 392 register struct vx_softc *sc = ifp->if_softc; | 31 * 32 */ 33 34/* 35 * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support 36 * the 3c590 family. 37 */ 38 --- 346 unchanged lines hidden (view full) --- 385 prev_conn = i; 386} 387 388static void 389vxstart(ifp) 390 struct ifnet *ifp; 391{ 392 register struct vx_softc *sc = ifp->if_softc; |
393 register struct mbuf *m, *m0; | 393 register struct mbuf *m; |
394 int sh, len, pad; 395 396 /* Don't transmit if interface is busy or not running */ 397 if ((sc->arpcom.ac_if.if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 398 return; 399 400startagain: 401 /* Sneak a peek at the next packet */ | 394 int sh, len, pad; 395 396 /* Don't transmit if interface is busy or not running */ 397 if ((sc->arpcom.ac_if.if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 398 return; 399 400startagain: 401 /* Sneak a peek at the next packet */ |
402 m0 = ifp->if_snd.ifq_head; 403 if (m0 == 0) { | 402 m = ifp->if_snd.ifq_head; 403 if (m == NULL) { |
404 return; 405 } 406 /* We need to use m->m_pkthdr.len, so require the header */ | 404 return; 405 } 406 /* We need to use m->m_pkthdr.len, so require the header */ |
407 if ((m0->m_flags & M_PKTHDR) == 0) | 407 if ((m->m_flags & M_PKTHDR) == 0) |
408 panic("vxstart: no header mbuf"); | 408 panic("vxstart: no header mbuf"); |
409 len = m0->m_pkthdr.len; | 409 len = m->m_pkthdr.len; |
410 411 pad = (4 - len) & 3; 412 413 /* 414 * The 3c509 automatically pads short packets to minimum ethernet length, 415 * but we drop packets that are too large. Perhaps we should truncate 416 * them instead? 417 */ 418 if (len + pad > ETHER_MAX_LEN) { 419 /* packet is obviously too large: toss it */ 420 ++ifp->if_oerrors; | 410 411 pad = (4 - len) & 3; 412 413 /* 414 * The 3c509 automatically pads short packets to minimum ethernet length, 415 * but we drop packets that are too large. Perhaps we should truncate 416 * them instead? 417 */ 418 if (len + pad > ETHER_MAX_LEN) { 419 /* packet is obviously too large: toss it */ 420 ++ifp->if_oerrors; |
421 IF_DEQUEUE(&ifp->if_snd, m0); 422 m_freem(m0); | 421 IF_DEQUEUE(&ifp->if_snd, m); 422 m_freem(m); |
423 goto readcheck; 424 } 425 VX_BUSY_WAIT; 426 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 427 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2)); 428 /* not enough room in FIFO */ 429 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { /* make sure */ 430 ifp->if_flags |= IFF_OACTIVE; 431 ifp->if_timer = 1; 432 return; 433 } 434 } 435 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); | 423 goto readcheck; 424 } 425 VX_BUSY_WAIT; 426 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { 427 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2)); 428 /* not enough room in FIFO */ 429 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { /* make sure */ 430 ifp->if_flags |= IFF_OACTIVE; 431 ifp->if_timer = 1; 432 return; 433 } 434 } 435 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); |
436 IF_DEQUEUE(&ifp->if_snd, m0); 437 if (m0 == 0) { /* not really needed */ | 436 IF_DEQUEUE(&ifp->if_snd, m); 437 if (m == NULL) /* not really needed */ |
438 return; | 438 return; |
439 } | |
440 441 VX_BUSY_WAIT; 442 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH | 443 ((len / 4 + sc->tx_start_thresh) >> 2)); 444 445 if (sc->arpcom.ac_if.if_bpf) { | 439 440 VX_BUSY_WAIT; 441 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH | 442 ((len / 4 + sc->tx_start_thresh) >> 2)); 443 444 if (sc->arpcom.ac_if.if_bpf) { |
446 bpf_mtap(&sc->arpcom.ac_if, m0); | 445 bpf_mtap(&sc->arpcom.ac_if, m); |
447 } 448 449 /* 450 * Do the output at splhigh() so that an interrupt from another device 451 * won't cause a FIFO underrun. 452 */ 453 sh = splhigh(); 454 455 CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE); 456 | 446 } 447 448 /* 449 * Do the output at splhigh() so that an interrupt from another device 450 * won't cause a FIFO underrun. 451 */ 452 sh = splhigh(); 453 454 CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE); 455 |
457 for (m = m0; m != 0;) { | 456 while (m) { |
458 if (m->m_len > 3) 459 bus_space_write_multi_4(sc->vx_btag, sc->vx_bhandle, 460 VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t), m->m_len / 4); 461 if (m->m_len & 3) 462 bus_space_write_multi_1(sc->vx_btag, sc->vx_bhandle, 463 VX_W1_TX_PIO_WR_1, 464 mtod(m, caddr_t) + (m->m_len & ~3) , m->m_len & 3); | 457 if (m->m_len > 3) 458 bus_space_write_multi_4(sc->vx_btag, sc->vx_bhandle, 459 VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t), m->m_len / 4); 460 if (m->m_len & 3) 461 bus_space_write_multi_1(sc->vx_btag, sc->vx_bhandle, 462 VX_W1_TX_PIO_WR_1, 463 mtod(m, caddr_t) + (m->m_len & ~3) , m->m_len & 3); |
465 MFREE(m, m0); 466 m = m0; | 464 m = m_free(m); |
467 } 468 while (pad--) 469 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ 470 471 splx(sh); 472 473 ++ifp->if_opackets; 474 ifp->if_timer = 1; --- 564 unchanged lines hidden --- | 465 } 466 while (pad--) 467 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ 468 469 splx(sh); 470 471 ++ifp->if_opackets; 472 ifp->if_timer = 1; --- 564 unchanged lines hidden --- |