if_fwip.c (169130) | if_fwip.c (170374) |
---|---|
1/*- 2 * Copyright (c) 2004 3 * Doug Rabson 4 * Copyright (c) 2002-2003 5 * Hidetoshi Shimokawa. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * | 1/*- 2 * Copyright (c) 2004 3 * Doug Rabson 4 * Copyright (c) 2002-2003 5 * Hidetoshi Shimokawa. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * |
36 * $FreeBSD: head/sys/dev/firewire/if_fwip.c 169130 2007-04-30 13:41:40Z simokawa $ | 36 * $FreeBSD: head/sys/dev/firewire/if_fwip.c 170374 2007-06-06 14:31:36Z simokawa $ |
37 */ 38 39#ifdef HAVE_KERNEL_OPTION_HEADERS 40#include "opt_device_polling.h" 41#include "opt_inet.h" 42#endif 43 44#include <sys/param.h> --- 111 unchanged lines hidden (view full) --- 156 struct fw_hwaddr *hwaddr; 157 158 fwip = ((struct fwip_softc *)device_get_softc(dev)); 159 unit = device_get_unit(dev); 160 ifp = fwip->fw_softc.fwip_ifp = if_alloc(IFT_IEEE1394); 161 if (ifp == NULL) 162 return (ENOSPC); 163 | 37 */ 38 39#ifdef HAVE_KERNEL_OPTION_HEADERS 40#include "opt_device_polling.h" 41#include "opt_inet.h" 42#endif 43 44#include <sys/param.h> --- 111 unchanged lines hidden (view full) --- 156 struct fw_hwaddr *hwaddr; 157 158 fwip = ((struct fwip_softc *)device_get_softc(dev)); 159 unit = device_get_unit(dev); 160 ifp = fwip->fw_softc.fwip_ifp = if_alloc(IFT_IEEE1394); 161 if (ifp == NULL) 162 return (ENOSPC); 163 |
164 mtx_init(&fwip->mtx, "fwip", NULL, MTX_DEF); |
|
164 /* XXX */ 165 fwip->dma_ch = -1; 166 167 fwip->fd.fc = device_get_ivars(dev); 168 if (tx_speed < 0) 169 tx_speed = fwip->fd.fc->speed; 170 171 fwip->fd.dev = dev; --- 20 unchanged lines hidden (view full) --- 192 if_initname(ifp, device_get_name(dev), unit); 193#else 194 ifp->if_unit = unit; 195 ifp->if_name = "fwip"; 196#endif 197 ifp->if_init = fwip_init; 198 ifp->if_start = fwip_start; 199 ifp->if_ioctl = fwip_ioctl; | 165 /* XXX */ 166 fwip->dma_ch = -1; 167 168 fwip->fd.fc = device_get_ivars(dev); 169 if (tx_speed < 0) 170 tx_speed = fwip->fd.fc->speed; 171 172 fwip->fd.dev = dev; --- 20 unchanged lines hidden (view full) --- 193 if_initname(ifp, device_get_name(dev), unit); 194#else 195 ifp->if_unit = unit; 196 ifp->if_name = "fwip"; 197#endif 198 ifp->if_init = fwip_init; 199 ifp->if_start = fwip_start; 200 ifp->if_ioctl = fwip_ioctl; |
200 ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST| 201 IFF_NEEDSGIANT); | 201 ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); |
202 ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE; 203#ifdef DEVICE_POLLING 204 ifp->if_capabilities |= IFCAP_POLLING; 205#endif 206 207 s = splimp(); 208 firewire_ifattach(ifp, hwaddr); 209 splx(s); --- 67 unchanged lines hidden (view full) --- 277 ether_poll_deregister(ifp); 278#endif 279 280 s = splimp(); 281 282 fwip_stop(fwip); 283 firewire_ifdetach(ifp); 284 if_free(ifp); | 202 ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE; 203#ifdef DEVICE_POLLING 204 ifp->if_capabilities |= IFCAP_POLLING; 205#endif 206 207 s = splimp(); 208 firewire_ifattach(ifp, hwaddr); 209 splx(s); --- 67 unchanged lines hidden (view full) --- 277 ether_poll_deregister(ifp); 278#endif 279 280 s = splimp(); 281 282 fwip_stop(fwip); 283 firewire_ifdetach(ifp); 284 if_free(ifp); |
285 mtx_destroy(&fwip->mtx); |
|
285 286 splx(s); 287 return 0; 288} 289 290static void 291fwip_init(void *arg) 292{ --- 5 unchanged lines hidden (view full) --- 298 struct mbuf *m; 299 int i; 300 301 FWIPDEBUG(ifp, "initializing\n"); 302 303 fc = fwip->fd.fc; 304#define START 0 305 if (fwip->dma_ch < 0) { | 286 287 splx(s); 288 return 0; 289} 290 291static void 292fwip_init(void *arg) 293{ --- 5 unchanged lines hidden (view full) --- 299 struct mbuf *m; 300 int i; 301 302 FWIPDEBUG(ifp, "initializing\n"); 303 304 fc = fwip->fd.fc; 305#define START 0 306 if (fwip->dma_ch < 0) { |
306 for (i = START; i < fc->nisodma; i ++) { 307 xferq = fc->ir[i]; 308 if ((xferq->flag & FWXFERQ_OPEN) == 0) 309 goto found; 310 } 311 printf("no free dma channel\n"); 312 return; 313found: 314 fwip->dma_ch = i; 315 /* allocate DMA channel and init packet mode */ 316 xferq->flag |= FWXFERQ_OPEN | FWXFERQ_EXTBUF | | 307 fwip->dma_ch = fw_open_isodma(fc, /* tx */0); 308 if (fwip->dma_ch < 0) 309 return; 310 xferq = fc->ir[fwip->dma_ch]; 311 xferq->flag |= FWXFERQ_EXTBUF | |
317 FWXFERQ_HANDLER | FWXFERQ_STREAM; 318 xferq->flag &= ~0xff; 319 xferq->flag |= broadcast_channel & 0xff; 320 /* register fwip_input handler */ 321 xferq->sc = (caddr_t) fwip; 322 xferq->hand = fwip_stream_input; 323 xferq->bnchunk = rx_queue_len; 324 xferq->bnpacket = 1; --- 192 unchanged lines hidden (view full) --- 517 518static void 519fwip_output_callback(struct fw_xfer *xfer) 520{ 521 struct fwip_softc *fwip; 522 struct ifnet *ifp; 523 int s; 524 | 312 FWXFERQ_HANDLER | FWXFERQ_STREAM; 313 xferq->flag &= ~0xff; 314 xferq->flag |= broadcast_channel & 0xff; 315 /* register fwip_input handler */ 316 xferq->sc = (caddr_t) fwip; 317 xferq->hand = fwip_stream_input; 318 xferq->bnchunk = rx_queue_len; 319 xferq->bnpacket = 1; --- 192 unchanged lines hidden (view full) --- 512 513static void 514fwip_output_callback(struct fw_xfer *xfer) 515{ 516 struct fwip_softc *fwip; 517 struct ifnet *ifp; 518 int s; 519 |
525 GIANT_REQUIRED; 526 | |
527 fwip = (struct fwip_softc *)xfer->sc; 528 ifp = fwip->fw_softc.fwip_ifp; 529 /* XXX error check */ 530 FWIPDEBUG(ifp, "resp = %d\n", xfer->resp); 531 if (xfer->resp != 0) 532 ifp->if_oerrors ++; 533 534 m_freem(xfer->mbuf); 535 fw_xfer_unload(xfer); 536 537 s = splimp(); | 520 fwip = (struct fwip_softc *)xfer->sc; 521 ifp = fwip->fw_softc.fwip_ifp; 522 /* XXX error check */ 523 FWIPDEBUG(ifp, "resp = %d\n", xfer->resp); 524 if (xfer->resp != 0) 525 ifp->if_oerrors ++; 526 527 m_freem(xfer->mbuf); 528 fw_xfer_unload(xfer); 529 530 s = splimp(); |
531 FWIP_LOCK(fwip); |
|
538 STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); | 532 STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); |
533 FWIP_UNLOCK(fwip); |
|
539 splx(s); 540 541 /* for queue full */ | 534 splx(s); 535 536 /* for queue full */ |
542 if (ifp->if_snd.ifq_head != NULL) | 537 if (ifp->if_snd.ifq_head != NULL) { |
543 fwip_start(ifp); | 538 fwip_start(ifp); |
539 } |
|
544} 545 546static void 547fwip_start(struct ifnet *ifp) 548{ 549 struct fwip_softc *fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip; 550 int s; 551 | 540} 541 542static void 543fwip_start(struct ifnet *ifp) 544{ 545 struct fwip_softc *fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip; 546 int s; 547 |
552 GIANT_REQUIRED; 553 | |
554 FWIPDEBUG(ifp, "starting\n"); 555 556 if (fwip->dma_ch < 0) { 557 struct mbuf *m = NULL; 558 559 FWIPDEBUG(ifp, "not ready\n"); 560 561 s = splimp(); --- 36 unchanged lines hidden (view full) --- 598 struct fw_hwaddr *destfw; 599 struct fw_xfer *xfer; 600 struct fw_xferq *xferq; 601 struct fw_pkt *fp; 602 uint16_t nodeid; 603 int error; 604 int i = 0; 605 | 548 FWIPDEBUG(ifp, "starting\n"); 549 550 if (fwip->dma_ch < 0) { 551 struct mbuf *m = NULL; 552 553 FWIPDEBUG(ifp, "not ready\n"); 554 555 s = splimp(); --- 36 unchanged lines hidden (view full) --- 592 struct fw_hwaddr *destfw; 593 struct fw_xfer *xfer; 594 struct fw_xferq *xferq; 595 struct fw_pkt *fp; 596 uint16_t nodeid; 597 int error; 598 int i = 0; 599 |
606 GIANT_REQUIRED; 607 | |
608 xfer = NULL; | 600 xfer = NULL; |
609 xferq = fwip->fd.fc->atq; 610 while (xferq->queued < xferq->maxq - 1) { | 601 xferq = fc->atq; 602 while ((xferq->queued < xferq->maxq - 1) && 603 (ifp->if_snd.ifq_head != NULL)) { 604 FWIP_LOCK(fwip); |
611 xfer = STAILQ_FIRST(&fwip->xferlist); 612 if (xfer == NULL) { | 605 xfer = STAILQ_FIRST(&fwip->xferlist); 606 if (xfer == NULL) { |
607 FWIP_UNLOCK(fwip); 608#if 0 |
|
613 printf("if_fwip: lack of xfer\n"); | 609 printf("if_fwip: lack of xfer\n"); |
614 return; | 610#endif 611 break; |
615 } | 612 } |
613 STAILQ_REMOVE_HEAD(&fwip->xferlist, link); 614 FWIP_UNLOCK(fwip); 615 |
|
616 IF_DEQUEUE(&ifp->if_snd, m); | 616 IF_DEQUEUE(&ifp->if_snd, m); |
617 if (m == NULL) | 617 if (m == NULL) { 618 FWIP_LOCK(fwip); 619 STAILQ_INSERT_HEAD(&fwip->xferlist, xfer, link); 620 FWIP_UNLOCK(fwip); |
618 break; | 621 break; |
622 } |
|
619 620 /* 621 * Dig out the link-level address which 622 * firewire_output got via arp or neighbour 623 * discovery. If we don't have a link-level address, 624 * just stick the thing on the broadcast channel. 625 */ 626 mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 0); 627 if (mtag == NULL) 628 destfw = 0; 629 else 630 destfw = (struct fw_hwaddr *) (mtag + 1); 631 | 623 624 /* 625 * Dig out the link-level address which 626 * firewire_output got via arp or neighbour 627 * discovery. If we don't have a link-level address, 628 * just stick the thing on the broadcast channel. 629 */ 630 mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 0); 631 if (mtag == NULL) 632 destfw = 0; 633 else 634 destfw = (struct fw_hwaddr *) (mtag + 1); 635 |
632 STAILQ_REMOVE_HEAD(&fwip->xferlist, link); | |
633 634 /* 635 * We don't do any bpf stuff here - the generic code 636 * in firewire_output gives the packet to bpf before 637 * it adds the link-level encapsulation. 638 */ 639 640 /* --- 76 unchanged lines hidden (view full) --- 717 718 error = fw_asyreq(fc, -1, xfer); 719 if (error == EAGAIN) { 720 /* 721 * We ran out of tlabels - requeue the packet 722 * for later transmission. 723 */ 724 xfer->mbuf = 0; | 636 637 /* 638 * We don't do any bpf stuff here - the generic code 639 * in firewire_output gives the packet to bpf before 640 * it adds the link-level encapsulation. 641 */ 642 643 /* --- 76 unchanged lines hidden (view full) --- 720 721 error = fw_asyreq(fc, -1, xfer); 722 if (error == EAGAIN) { 723 /* 724 * We ran out of tlabels - requeue the packet 725 * for later transmission. 726 */ 727 xfer->mbuf = 0; |
728 FWIP_LOCK(fwip); |
|
725 STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); | 729 STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); |
730 FWIP_UNLOCK(fwip); |
|
726 IF_PREPEND(&ifp->if_snd, m); 727 break; 728 } 729 if (error) { 730 /* error */ 731 ifp->if_oerrors ++; 732 /* XXX set error code */ 733 fwip_output_callback(xfer); 734 continue; 735 } else { 736 ifp->if_opackets ++; 737 i++; 738 } 739 } 740#if 0 741 if (i > 1) 742 printf("%d queued\n", i); 743#endif | 731 IF_PREPEND(&ifp->if_snd, m); 732 break; 733 } 734 if (error) { 735 /* error */ 736 ifp->if_oerrors ++; 737 /* XXX set error code */ 738 fwip_output_callback(xfer); 739 continue; 740 } else { 741 ifp->if_opackets ++; 742 i++; 743 } 744 } 745#if 0 746 if (i > 1) 747 printf("%d queued\n", i); 748#endif |
744 if (i > 0) { 745#if 1 | 749 if (i > 0) |
746 xferq->start(fc); | 750 xferq->start(fc); |
747#else 748 taskqueue_enqueue(taskqueue_swi_giant, &fwip->start_send); 749#endif 750 } | |
751} 752 753static void 754fwip_start_send (void *arg, int count) 755{ 756 struct fwip_softc *fwip = arg; 757 | 751} 752 753static void 754fwip_start_send (void *arg, int count) 755{ 756 struct fwip_softc *fwip = arg; 757 |
758 GIANT_REQUIRED; | |
759 fwip->fd.fc->atq->start(fwip->fd.fc); 760} 761 762/* Async. stream output */ 763static void 764fwip_stream_input(struct fw_xferq *xferq) 765{ 766 struct mbuf *m, *m0; 767 struct m_tag *mtag; 768 struct ifnet *ifp; 769 struct fwip_softc *fwip; 770 struct fw_bulkxfer *sxfer; 771 struct fw_pkt *fp; 772 uint16_t src; 773 uint32_t *p; 774 | 758 fwip->fd.fc->atq->start(fwip->fd.fc); 759} 760 761/* Async. stream output */ 762static void 763fwip_stream_input(struct fw_xferq *xferq) 764{ 765 struct mbuf *m, *m0; 766 struct m_tag *mtag; 767 struct ifnet *ifp; 768 struct fwip_softc *fwip; 769 struct fw_bulkxfer *sxfer; 770 struct fw_pkt *fp; 771 uint16_t src; 772 uint32_t *p; 773 |
775 GIANT_REQUIRED; | |
776 777 fwip = (struct fwip_softc *)xferq->sc; 778 ifp = fwip->fw_softc.fwip_ifp; 779 780 while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) { 781 STAILQ_REMOVE_HEAD(&xferq->stvalid, link); 782 fp = mtod(sxfer->mbuf, struct fw_pkt *); 783 if (fwip->fd.fc->irx_post != NULL) --- 85 unchanged lines hidden (view full) --- 869 fwip->fd.fc->irx_enable(fwip->fd.fc, fwip->dma_ch); 870} 871 872static __inline void 873fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer) 874{ 875 struct mbuf *m; 876 | 774 775 fwip = (struct fwip_softc *)xferq->sc; 776 ifp = fwip->fw_softc.fwip_ifp; 777 778 while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) { 779 STAILQ_REMOVE_HEAD(&xferq->stvalid, link); 780 fp = mtod(sxfer->mbuf, struct fw_pkt *); 781 if (fwip->fd.fc->irx_post != NULL) --- 85 unchanged lines hidden (view full) --- 867 fwip->fd.fc->irx_enable(fwip->fd.fc, fwip->dma_ch); 868} 869 870static __inline void 871fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer) 872{ 873 struct mbuf *m; 874 |
877 GIANT_REQUIRED; 878 | |
879 /* 880 * We have finished with a unicast xfer. Allocate a new 881 * cluster and stick it on the back of the input queue. 882 */ 883 m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); 884 xfer->mbuf = m; 885 xfer->recv.payload = mtod(m, uint32_t *); 886 xfer->recv.pay_len = MCLBYTES; --- 8 unchanged lines hidden (view full) --- 895 struct mbuf *m; 896 struct m_tag *mtag; 897 struct ifnet *ifp; 898 struct fwip_softc *fwip; 899 struct fw_pkt *fp; 900 //struct fw_pkt *sfp; 901 int rtcode; 902 | 875 /* 876 * We have finished with a unicast xfer. Allocate a new 877 * cluster and stick it on the back of the input queue. 878 */ 879 m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); 880 xfer->mbuf = m; 881 xfer->recv.payload = mtod(m, uint32_t *); 882 xfer->recv.pay_len = MCLBYTES; --- 8 unchanged lines hidden (view full) --- 891 struct mbuf *m; 892 struct m_tag *mtag; 893 struct ifnet *ifp; 894 struct fwip_softc *fwip; 895 struct fw_pkt *fp; 896 //struct fw_pkt *sfp; 897 int rtcode; 898 |
903 GIANT_REQUIRED; 904 | |
905 fwip = (struct fwip_softc *)xfer->sc; 906 ifp = fwip->fw_softc.fwip_ifp; 907 m = xfer->mbuf; 908 xfer->mbuf = 0; 909 fp = &xfer->recv.hdr; 910 911 /* 912 * Check the fifo address - we only accept addresses of --- 85 unchanged lines hidden --- | 899 fwip = (struct fwip_softc *)xfer->sc; 900 ifp = fwip->fw_softc.fwip_ifp; 901 m = xfer->mbuf; 902 xfer->mbuf = 0; 903 fp = &xfer->recv.hdr; 904 905 /* 906 * Check the fifo address - we only accept addresses of --- 85 unchanged lines hidden --- |