Deleted Added
full compact
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 ---