1 /* $NetBSD: if_fwip.c,v 1.19 2009/05/12 12:16:55 cegger Exp $ */
5 * Copyright (c) 2002-2003
6 * Hidetoshi Shimokawa. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
19 * This product includes software developed by Hidetoshi Shimokawa.
21 * 4. Neither the name of the author nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * $FreeBSD: src/sys/dev/firewire/if_fwip.c,v 1.16 2007/06/06 14:31:36 simokawa Exp $
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: if_fwip.c,v 1.19 2009/05/12 12:16:55 cegger Exp $");
43 #ifdef HAVE_KERNEL_OPTION_HEADERS
44 #include "opt_device_polling.h"
48 #if defined(__FreeBSD__)
49 #include <sys/param.h>
50 #include <sys/kernel.h>
51 #include <sys/malloc.h>
53 #include <sys/socket.h>
54 #include <sys/sockio.h>
55 #include <sys/sysctl.h>
56 #include <sys/systm.h>
57 #include <sys/taskqueue.h>
58 #include <sys/module.h>
64 #include <net/firewire.h>
65 #include <net/if_arp.h>
66 #include <net/if_types.h>
68 #include <bus/firewire/fw_port.h>
69 #include <bus/firewire/firewire.h>
70 #include <bus/firewire/firewirereg.h>
71 #include "if_fwipvar.h"
73 #include <dev/firewire/fw_port.h>
74 #include <dev/firewire/firewire.h>
75 #include <dev/firewire/firewirereg.h>
76 #include <dev/firewire/iec13213.h>
77 #include <dev/firewire/if_fwipvar.h>
79 #elif defined(__NetBSD__)
80 #include <sys/param.h>
81 #include <sys/device.h>
82 #include <sys/errno.h>
83 #include <sys/malloc.h>
85 #include <sys/sysctl.h>
90 #include <net/if_ieee1394.h>
91 #include <net/if_types.h>
93 #include <dev/ieee1394/fw_port.h>
94 #include <dev/ieee1394/firewire.h>
95 #include <dev/ieee1394/firewirereg.h>
96 #include <dev/ieee1394/iec13213.h>
97 #include <dev/ieee1394/if_fwipvar.h>
101 * We really need a mechanism for allocating regions in the FIFO
102 * address space. We pick a address in the OHCI controller's 'middle'
103 * address space. This means that the controller will automatically
104 * send responses for us, which is fine since we don't have any
105 * important information to put in the response anyway.
107 #define INET_FIFO 0xfffe00000000LL
109 #if defined(__FreeBSD__)
110 #define FWIPDEBUG if (fwipdebug) if_printf
111 #elif defined(__NetBSD__)
112 #define FWIPDEBUG if (fwipdebug) aprint_debug_ifnet
114 #define TX_MAX_QUEUE (FWMAXQUEUE - 1)
116 #if defined(__NetBSD__)
117 int fwipmatch (device_t
, cfdata_t
, void *);
118 void fwipattach (device_t
, device_t
, void *);
119 int fwipdetach (device_t
, int);
120 int fwipactivate (device_t
, enum devact
);
123 /* network interface */
124 static void fwip_start (struct ifnet
*);
125 static int fwip_ioctl (struct ifnet
*, u_long
, void *);
126 #if defined(__FreeBSD__)
127 static void fwip_init(void *);
128 static void fwip_stop(struct fwip_softc
*);
129 #elif defined(__NetBSD__)
130 static int fwip_init(struct ifnet
*);
131 static void fwip_stop(struct ifnet
*, int);
134 static void fwip_post_busreset (void *);
135 static void fwip_output_callback (struct fw_xfer
*);
136 static void fwip_async_output (struct fwip_softc
*, struct ifnet
*);
137 static void fwip_start_send (void *, int);
138 static void fwip_stream_input (struct fw_xferq
*);
139 static void fwip_unicast_input(struct fw_xfer
*);
141 static int fwipdebug
= 0;
142 static int broadcast_channel
= 0xc0 | 0x1f; /* tag | channel(XXX) */
143 static int tx_speed
= 2;
144 static int rx_queue_len
= FWMAXQUEUE
;
146 #if defined(__FreeBSD__)
147 MALLOC_DEFINE(M_FWIP
, "if_fwip", "IP over FireWire interface");
148 SYSCTL_INT(_debug
, OID_AUTO
, if_fwip_debug
, CTLFLAG_RW
, &fwipdebug
, 0, "");
149 SYSCTL_DECL(_hw_firewire
);
150 SYSCTL_NODE(_hw_firewire
, OID_AUTO
, fwip
, CTLFLAG_RD
, 0,
151 "Firewire ip subsystem");
152 SYSCTL_INT(_hw_firewire_fwip
, OID_AUTO
, rx_queue_len
, CTLFLAG_RW
, &rx_queue_len
,
153 0, "Length of the receive queue");
155 TUNABLE_INT("hw.firewire.fwip.rx_queue_len", &rx_queue_len
);
156 #elif defined(__NetBSD__)
157 MALLOC_DEFINE(M_FWIP
, "if_fwip", "IP over IEEE1394 interface");
159 * Setup sysctl(3) MIB, hw.fwip.*
161 * TBD condition CTLFLAG_PERMANENT on being a module or not
163 SYSCTL_SETUP(sysctl_fwip
, "sysctl fwip(4) subtree setup")
165 int rc
, fwip_node_num
;
166 const struct sysctlnode
*node
;
168 if ((rc
= sysctl_createv(clog
, 0, NULL
, NULL
,
169 CTLFLAG_PERMANENT
, CTLTYPE_NODE
, "hw", NULL
,
170 NULL
, 0, NULL
, 0, CTL_HW
, CTL_EOL
)) != 0) {
174 if ((rc
= sysctl_createv(clog
, 0, NULL
, &node
,
175 CTLFLAG_PERMANENT
, CTLTYPE_NODE
, "fwip",
176 SYSCTL_DESCR("fwip controls"),
177 NULL
, 0, NULL
, 0, CTL_HW
, CTL_CREATE
, CTL_EOL
)) != 0) {
180 fwip_node_num
= node
->sysctl_num
;
182 /* fwip RX queue length */
183 if ((rc
= sysctl_createv(clog
, 0, NULL
, &node
,
184 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
, CTLTYPE_INT
,
185 "rx_queue_len", SYSCTL_DESCR("Length of the receive queue"),
186 NULL
, 0, &rx_queue_len
,
187 0, CTL_HW
, fwip_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
191 /* fwip RX queue length */
192 if ((rc
= sysctl_createv(clog
, 0, NULL
, &node
,
193 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
, CTLTYPE_INT
,
194 "if_fwip_debug", SYSCTL_DESCR("fwip driver debug flag"),
196 0, CTL_HW
, fwip_node_num
, CTL_CREATE
, CTL_EOL
)) != 0) {
203 printf("%s: sysctl_createv failed (rc = %d)\n", __func__
, rc
);
207 #ifdef DEVICE_POLLING
208 static poll_handler_t fwip_poll
;
211 fwip_poll(struct ifnet
*ifp
, enum poll_cmd cmd
, int count
)
213 struct fwip_softc
*fwip
;
214 struct firewire_comm
*fc
;
216 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
219 fwip
= ((struct fwip_eth_softc
*)ifp
->if_softc
)->fwip
;
221 fc
->poll(fc
, (cmd
== POLL_AND_CHECK_STATUS
)?0:1, count
);
223 #endif /* DEVICE_POLLING */
224 #if defined(__FreeBSD__)
226 fwip_identify(driver_t
*driver
, device_t parent
)
228 BUS_ADD_CHILD(parent
, 0, "fwip", fw_get_unit(parent
));
232 fwip_probe(device_t dev
)
236 pa
= device_get_parent(dev
);
237 if(fw_get_unit(dev
) != fw_get_unit(pa
)){
241 device_set_desc(dev
, "IP over FireWire");
244 #elif defined(__NetBSD__)
246 fwipmatch(device_t parent
, cfdata_t cf
, void *aux
)
248 struct fw_attach_args
*fwa
= aux
;
250 if (strcmp(fwa
->name
, "fwip") == 0)
258 FW_ATTACH_START(fwip
, fwip
, fwa
);
265 ifp
= fwip
->fw_softc
.fwip_ifp
;
267 FW_ATTACH_RETURN(ENOSPC
);
269 fw_mtx_init(&fwip
->mtx
, "fwip", NULL
, MTX_DEF
);
273 fwip
->fd
.fc
= fwa
->fc
;
275 tx_speed
= fwip
->fd
.fc
->speed
;
277 fwip
->fd
.post_explore
= NULL
;
278 fwip
->fd
.post_busreset
= fwip_post_busreset
;
279 fwip
->fw_softc
.fwip
= fwip
;
280 FW_TASK_INIT(&fwip
->start_send
, 0, fwip_start_send
, fwip
);
283 * Encode our hardware the way that arp likes it.
285 hwaddr
->sender_unique_ID_hi
= htonl(fwip
->fd
.fc
->eui
.hi
);
286 hwaddr
->sender_unique_ID_lo
= htonl(fwip
->fd
.fc
->eui
.lo
);
287 hwaddr
->sender_max_rec
= fwip
->fd
.fc
->maxrec
;
288 hwaddr
->sspd
= fwip
->fd
.fc
->speed
;
289 hwaddr
->sender_unicast_FIFO_hi
= htons((uint16_t)(INET_FIFO
>> 32));
290 hwaddr
->sender_unicast_FIFO_lo
= htonl((uint32_t)INET_FIFO
);
292 /* fill the rest and attach interface */
293 ifp
->if_softc
= &fwip
->fw_softc
;
295 #if __FreeBSD_version >= 501113 || defined(__DragonFly__) || defined(__NetBSD__)
296 IF_INITNAME(ifp
, dev
, unit
);
299 ifp
->if_name
= "fwip";
301 #if defined(__NetBSD__)
302 IFQ_SET_READY(&ifp
->if_snd
);
304 SET_IFFUNC(ifp
, fwip_start
, fwip_ioctl
, fwip_init
, fwip_stop
);
305 ifp
->if_flags
= (IFF_BROADCAST
|IFF_SIMPLEX
|IFF_MULTICAST
);
306 ifp
->if_snd
.ifq_maxlen
= TX_MAX_QUEUE
;
307 #ifdef DEVICE_POLLING
308 ifp
->if_capabilities
|= IFCAP_POLLING
;
312 FIREWIRE_IFATTACH(ifp
, hwaddr
);
315 #if defined(__NetBSD__)
316 if (!pmf_device_register(self
, NULL
, NULL
))
317 aprint_error_dev(self
, "couldn't establish power handler\n");
319 pmf_class_network_register(self
, ifp
);
322 FWIPDEBUG(ifp
, "interface created\n");
328 IF_STOP_START(fwip
, ifp
, fwip
);
329 struct firewire_comm
*fc
;
330 struct fw_xferq
*xferq
;
331 struct fw_xfer
*xfer
, *next
;
336 if (fwip
->dma_ch
>= 0) {
337 xferq
= fc
->ir
[fwip
->dma_ch
];
339 if (xferq
->flag
& FWXFERQ_RUNNING
)
340 fc
->irx_disable(fc
, fwip
->dma_ch
);
342 ~(FWXFERQ_MODEMASK
| FWXFERQ_OPEN
| FWXFERQ_STREAM
|
343 FWXFERQ_EXTBUF
| FWXFERQ_HANDLER
| FWXFERQ_CHTAGMASK
);
346 for (i
= 0; i
< xferq
->bnchunk
; i
++)
347 m_freem(xferq
->bulkxfer
[i
].mbuf
);
348 free(xferq
->bulkxfer
, M_FWIP
);
350 fw_bindremove(fc
, &fwip
->fwb
);
351 for (xfer
= STAILQ_FIRST(&fwip
->fwb
.xferlist
); xfer
!= NULL
;
353 next
= STAILQ_NEXT(xfer
, link
);
357 for (xfer
= STAILQ_FIRST(&fwip
->xferlist
); xfer
!= NULL
;
359 next
= STAILQ_NEXT(xfer
, link
);
362 STAILQ_INIT(&fwip
->xferlist
);
364 xferq
->bulkxfer
= NULL
;
368 #if defined(__FreeBSD__)
369 ifp
->if_drv_flags
&= ~(IFF_DRV_RUNNING
| IFF_DRV_OACTIVE
);
370 #elif defined(__NetBSD__)
371 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
377 IF_DETACH_START(fwip
, fwip
);
381 ifp
= fwip
->fw_softc
.fwip_ifp
;
383 #ifdef DEVICE_POLLING
384 if (ifp
->if_capenable
& IFCAP_POLLING
)
385 ether_poll_deregister(ifp
);
391 FIREWIRE_IFDETACH(ifp
);
392 fw_mtx_destroy(&fwip
->mtx
);
399 fwipactivate(device_t self
, enum devact act
)
401 struct fwip_softc
*fwip
= device_private(self
);
404 case DVACT_DEACTIVATE
:
405 if_deactivate(fwip
->fw_softc
.fwip_ifp
);
414 IF_INIT_START(fwip
, fwip
, ifp
);
415 struct firewire_comm
*fc
;
416 struct fw_xferq
*xferq
;
417 struct fw_xfer
*xfer
;
421 FWIPDEBUG(ifp
, "initializing\n");
425 if (fwip
->dma_ch
< 0) {
426 fwip
->dma_ch
= fw_open_isodma(fc
, /* tx */0);
427 if (fwip
->dma_ch
< 0)
428 IF_INIT_RETURN(ENXIO
);
429 xferq
= fc
->ir
[fwip
->dma_ch
];
431 FWXFERQ_EXTBUF
| FWXFERQ_HANDLER
| FWXFERQ_STREAM
;
432 xferq
->flag
&= ~0xff;
433 xferq
->flag
|= broadcast_channel
& 0xff;
434 /* register fwip_input handler */
435 xferq
->sc
= (void *) fwip
;
436 xferq
->hand
= fwip_stream_input
;
437 xferq
->bnchunk
= rx_queue_len
;
439 xferq
->psize
= MCLBYTES
;
442 xferq
->bulkxfer
= (struct fw_bulkxfer
*) malloc(
443 sizeof(struct fw_bulkxfer
) * xferq
->bnchunk
,
445 if (xferq
->bulkxfer
== NULL
) {
446 printf("if_fwip: malloc failed\n");
447 IF_INIT_RETURN(ENOMEM
);
449 STAILQ_INIT(&xferq
->stvalid
);
450 STAILQ_INIT(&xferq
->stfree
);
451 STAILQ_INIT(&xferq
->stdma
);
452 xferq
->stproc
= NULL
;
453 for (i
= 0; i
< xferq
->bnchunk
; i
++) {
455 #if defined(__DragonFly__) || __FreeBSD_version < 500000
456 m_getcl(M_WAIT
, MT_DATA
, M_PKTHDR
);
458 m_getcl(M_TRYWAIT
, MT_DATA
, M_PKTHDR
);
460 xferq
->bulkxfer
[i
].mbuf
= m
;
462 m
->m_len
= m
->m_pkthdr
.len
= m
->m_ext
.ext_size
;
463 STAILQ_INSERT_TAIL(&xferq
->stfree
,
464 &xferq
->bulkxfer
[i
], link
);
466 printf("fwip_as_input: m_getcl failed\n");
469 fwip
->fwb
.start
= INET_FIFO
;
470 fwip
->fwb
.end
= INET_FIFO
+ 16384; /* S3200 packet size */
472 /* pre-allocate xfer */
473 STAILQ_INIT(&fwip
->fwb
.xferlist
);
474 for (i
= 0; i
< rx_queue_len
; i
++) {
475 xfer
= fw_xfer_alloc(M_FWIP
);
478 m
= m_getcl(M_TRYWAIT
, MT_DATA
, M_PKTHDR
);
479 xfer
->recv
.payload
= mtod(m
, uint32_t *);
480 xfer
->recv
.pay_len
= MCLBYTES
;
481 xfer
->hand
= fwip_unicast_input
;
483 xfer
->sc
= (void *)fwip
;
485 STAILQ_INSERT_TAIL(&fwip
->fwb
.xferlist
, xfer
, link
);
487 fw_bindadd(fc
, &fwip
->fwb
);
489 STAILQ_INIT(&fwip
->xferlist
);
490 for (i
= 0; i
< TX_MAX_QUEUE
; i
++) {
491 xfer
= fw_xfer_alloc(M_FWIP
);
494 xfer
->send
.spd
= tx_speed
;
495 xfer
->fc
= fwip
->fd
.fc
;
496 xfer
->sc
= (void *)fwip
;
497 xfer
->hand
= fwip_output_callback
;
498 STAILQ_INSERT_TAIL(&fwip
->xferlist
, xfer
, link
);
501 xferq
= fc
->ir
[fwip
->dma_ch
];
503 fwip
->last_dest
.hi
= 0;
504 fwip
->last_dest
.lo
= 0;
507 if ((xferq
->flag
& FWXFERQ_RUNNING
) == 0)
508 fc
->irx_enable(fc
, fwip
->dma_ch
);
510 #if defined(__FreeBSD__)
511 ifp
->if_drv_flags
|= IFF_DRV_RUNNING
;
512 ifp
->if_drv_flags
&= ~IFF_DRV_OACTIVE
;
513 #elif defined(__NetBSD__)
514 ifp
->if_flags
|= IFF_RUNNING
;
515 ifp
->if_flags
&= ~IFF_OACTIVE
;
519 /* attempt to start output */
526 fwip_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
528 IF_IOCTL_START(fwip
, fwip
);
534 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
536 else if (ifp
->if_flags
& IFF_UP
) {
537 if (!(ifp
->if_flags
& IFF_RUNNING
))
540 if (ifp
->if_flags
& IFF_RUNNING
)
549 if ((error
= FIREWIRE_IOCTL(ifp
, cmd
, data
)) != ENETRESET
)
552 #ifdef DEVICE_POLLING
554 struct ifreq
*ifr
= (struct ifreq
*) data
;
555 struct firewire_comm
*fc
= fc
= fwip
->fd
.fc
;
557 if (ifr
->ifr_reqcap
& IFCAP_POLLING
&&
558 !(ifp
->if_capenable
& IFCAP_POLLING
)) {
559 error
= ether_poll_register(fwip_poll
, ifp
);
562 /* Disable interrupts */
564 ifp
->if_capenable
|= IFCAP_POLLING
;
568 if (!(ifr
->ifr_reqcap
& IFCAP_POLLING
) &&
569 ifp
->if_capenable
& IFCAP_POLLING
) {
570 error
= ether_poll_deregister(ifp
);
571 /* Enable interrupts. */
573 ifp
->if_capenable
&= ~IFCAP_POLLING
;
577 #endif /* DEVICE_POLLING */
582 error
= FIREWIRE_IOCTL(ifp
, cmd
, data
);
591 fwip_post_busreset(void *arg
)
593 struct fwip_softc
*fwip
= arg
;
594 struct crom_src
*src
;
595 struct crom_chunk
*root
;
597 src
= fwip
->fd
.fc
->crom_src
;
598 root
= fwip
->fd
.fc
->crom_root
;
600 /* RFC2734 IPv4 over IEEE1394 */
601 memset(&fwip
->unit4
, 0, sizeof(struct crom_chunk
));
602 crom_add_chunk(src
, root
, &fwip
->unit4
, CROM_UDIR
);
603 crom_add_entry(&fwip
->unit4
, CSRKEY_SPEC
, CSRVAL_IETF
);
604 crom_add_simple_text(src
, &fwip
->unit4
, &fwip
->spec4
, "IANA");
605 crom_add_entry(&fwip
->unit4
, CSRKEY_VER
, 1);
606 crom_add_simple_text(src
, &fwip
->unit4
, &fwip
->ver4
, "IPv4");
608 /* RFC3146 IPv6 over IEEE1394 */
609 memset(&fwip
->unit6
, 0, sizeof(struct crom_chunk
));
610 crom_add_chunk(src
, root
, &fwip
->unit6
, CROM_UDIR
);
611 crom_add_entry(&fwip
->unit6
, CSRKEY_SPEC
, CSRVAL_IETF
);
612 crom_add_simple_text(src
, &fwip
->unit6
, &fwip
->spec6
, "IANA");
613 crom_add_entry(&fwip
->unit6
, CSRKEY_VER
, 2);
614 crom_add_simple_text(src
, &fwip
->unit6
, &fwip
->ver6
, "IPv6");
616 fwip
->last_dest
.hi
= 0;
617 fwip
->last_dest
.lo
= 0;
618 FIREWIRE_BUSRESET(fwip
->fw_softc
.fwip_ifp
);
622 fwip_output_callback(struct fw_xfer
*xfer
)
624 struct fwip_softc
*fwip
;
628 fwip
= (struct fwip_softc
*)xfer
->sc
;
629 ifp
= fwip
->fw_softc
.fwip_ifp
;
630 /* XXX error check */
631 FWIPDEBUG(ifp
, "resp = %d\n", xfer
->resp
);
636 fw_xfer_unload(xfer
);
640 STAILQ_INSERT_TAIL(&fwip
->xferlist
, xfer
, link
);
645 if (ifp
->if_snd
.ifq_head
!= NULL
) {
651 fwip_start(struct ifnet
*ifp
)
653 struct fwip_softc
*fwip
=
654 ((struct fwip_eth_softc
*)ifp
->if_softc
)->fwip
;
657 FWIPDEBUG(ifp
, "starting\n");
659 if (fwip
->dma_ch
< 0) {
660 struct mbuf
*m
= NULL
;
662 FWIPDEBUG(ifp
, "not ready\n");
666 IF_DEQUEUE(&ifp
->if_snd
, m
);
677 #if defined(__FreeBSD__)
678 ifp
->if_drv_flags
|= IFF_DRV_OACTIVE
;
679 #elif defined(__NetBSD__)
680 ifp
->if_flags
|= IFF_OACTIVE
;
683 if (ifp
->if_snd
.ifq_len
!= 0)
684 fwip_async_output(fwip
, ifp
);
686 #if defined(__FreeBSD__)
687 ifp
->if_drv_flags
&= ~IFF_DRV_OACTIVE
;
688 #elif defined(__NetBSD__)
689 ifp
->if_flags
&= ~IFF_OACTIVE
;
694 /* Async. stream output */
696 fwip_async_output(struct fwip_softc
*fwip
, struct ifnet
*ifp
)
698 struct firewire_comm
*fc
= fwip
->fd
.fc
;
701 struct fw_hwaddr
*destfw
;
702 struct fw_xfer
*xfer
;
703 struct fw_xferq
*xferq
;
711 while ((xferq
->queued
< xferq
->maxq
- 1) &&
712 (ifp
->if_snd
.ifq_head
!= NULL
)) {
714 xfer
= STAILQ_FIRST(&fwip
->xferlist
);
718 printf("if_fwip: lack of xfer\n");
722 STAILQ_REMOVE_HEAD(&fwip
->xferlist
, link
);
725 IF_DEQUEUE(&ifp
->if_snd
, m
);
728 STAILQ_INSERT_HEAD(&fwip
->xferlist
, xfer
, link
);
734 * Dig out the link-level address which
735 * firewire_output got via arp or neighbour
736 * discovery. If we don't have a link-level address,
737 * just stick the thing on the broadcast channel.
739 mtag
= m_tag_locate(m
, MTAG_FIREWIRE
, MTAG_FIREWIRE_HWADDR
, 0);
743 destfw
= (struct fw_hwaddr
*) (mtag
+ 1);
746 * We don't do any bpf stuff here - the generic code
747 * in firewire_output gives the packet to bpf before
748 * it adds the link-level encapsulation.
752 * Put the mbuf in the xfer early in case we hit an
753 * error case below - fwip_output_callback will free
759 * We use the arp result (if any) to add a suitable firewire
760 * packet header before handing off to the bus.
762 fp
= &xfer
->send
.hdr
;
763 nodeid
= FWLOCALBUS
| fc
->nodeid
;
764 if ((m
->m_flags
& M_BCAST
) || !destfw
) {
766 * Broadcast packets are sent as GASP packets with
767 * specifier ID 0x00005e, version 1 on the broadcast
768 * channel. To be conservative, we send at the
769 * slowest possible speed.
773 M_PREPEND(m
, 2*sizeof(uint32_t), M_DONTWAIT
);
774 p
= mtod(m
, uint32_t *);
775 fp
->mode
.stream
.len
= m
->m_pkthdr
.len
;
776 fp
->mode
.stream
.chtag
= broadcast_channel
;
777 fp
->mode
.stream
.tcode
= FWTCODE_STREAM
;
778 fp
->mode
.stream
.sy
= 0;
780 p
[0] = htonl(nodeid
<< 16);
781 p
[1] = htonl((0x5e << 24) | 1);
784 * Unicast packets are sent as block writes to the
785 * target's unicast fifo address. If we can't
786 * find the node address, we just give up. We
787 * could broadcast it but that might overflow
788 * the packet size limitations due to the
789 * extra GASP header. Note: the hardware
790 * address is stored in network byte order to
791 * make life easier for ARP.
793 struct fw_device
*fd
;
796 eui
.hi
= ntohl(destfw
->sender_unique_ID_hi
);
797 eui
.lo
= ntohl(destfw
->sender_unique_ID_lo
);
798 if (fwip
->last_dest
.hi
!= eui
.hi
||
799 fwip
->last_dest
.lo
!= eui
.lo
) {
800 fd
= fw_noderesolve_eui64(fc
, &eui
);
804 /* XXX set error code */
805 fwip_output_callback(xfer
);
809 fwip
->last_hdr
.mode
.wreqb
.dst
= FWLOCALBUS
| fd
->dst
;
810 fwip
->last_hdr
.mode
.wreqb
.tlrt
= 0;
811 fwip
->last_hdr
.mode
.wreqb
.tcode
= FWTCODE_WREQB
;
812 fwip
->last_hdr
.mode
.wreqb
.pri
= 0;
813 fwip
->last_hdr
.mode
.wreqb
.src
= nodeid
;
814 fwip
->last_hdr
.mode
.wreqb
.dest_hi
=
815 ntohs(destfw
->sender_unicast_FIFO_hi
);
816 fwip
->last_hdr
.mode
.wreqb
.dest_lo
=
817 ntohl(destfw
->sender_unicast_FIFO_lo
);
818 fwip
->last_hdr
.mode
.wreqb
.extcode
= 0;
819 fwip
->last_dest
= eui
;
822 fp
->mode
.wreqb
= fwip
->last_hdr
.mode
.wreqb
;
823 fp
->mode
.wreqb
.len
= m
->m_pkthdr
.len
;
824 xfer
->send
.spd
= min(destfw
->sspd
, fc
->speed
);
827 xfer
->send
.pay_len
= m
->m_pkthdr
.len
;
829 error
= fw_asyreq(fc
, -1, xfer
);
830 if (error
== EAGAIN
) {
832 * We ran out of tlabels - requeue the packet
833 * for later transmission.
837 STAILQ_INSERT_TAIL(&fwip
->xferlist
, xfer
, link
);
839 IF_PREPEND(&ifp
->if_snd
, m
);
845 /* XXX set error code */
846 fwip_output_callback(xfer
);
855 printf("%d queued\n", i
);
862 fwip_start_send (void *arg
, int count
)
864 struct fwip_softc
*fwip
= arg
;
866 fwip
->fd
.fc
->atq
->start(fwip
->fd
.fc
);
869 /* Async. stream output */
871 fwip_stream_input(struct fw_xferq
*xferq
)
876 struct fwip_softc
*fwip
;
877 struct fw_bulkxfer
*sxfer
;
882 fwip
= (struct fwip_softc
*)xferq
->sc
;
883 ifp
= fwip
->fw_softc
.fwip_ifp
;
884 while ((sxfer
= STAILQ_FIRST(&xferq
->stvalid
)) != NULL
) {
885 STAILQ_REMOVE_HEAD(&xferq
->stvalid
, link
);
886 fp
= mtod(sxfer
->mbuf
, struct fw_pkt
*);
887 if (fwip
->fd
.fc
->irx_post
!= NULL
)
888 fwip
->fd
.fc
->irx_post(fwip
->fd
.fc
, fp
->mode
.ld
);
891 /* insert new rbuf */
892 sxfer
->mbuf
= m0
= m_getcl(M_DONTWAIT
, MT_DATA
, M_PKTHDR
);
894 m0
->m_len
= m0
->m_pkthdr
.len
= m0
->m_ext
.ext_size
;
895 STAILQ_INSERT_TAIL(&xferq
->stfree
, sxfer
, link
);
897 printf("fwip_as_input: m_getcl failed\n");
900 * We must have a GASP header - leave the
901 * encapsulation sanity checks to the generic
902 * code. Remeber that we also have the firewire async
903 * stream header even though that isn't accounted for
904 * in mode.stream.len.
906 if (sxfer
->resp
!= 0 || fp
->mode
.stream
.len
<
907 2*sizeof(uint32_t)) {
912 m
->m_len
= m
->m_pkthdr
.len
= fp
->mode
.stream
.len
913 + sizeof(fp
->mode
.stream
);
916 * If we received the packet on the broadcast channel,
917 * mark it as broadcast, otherwise we assume it must
920 if (fp
->mode
.stream
.chtag
== broadcast_channel
)
921 m
->m_flags
|= M_BCAST
;
923 m
->m_flags
|= M_MCAST
;
926 * Make sure we recognise the GASP specifier and
929 p
= mtod(m
, uint32_t *);
930 if ((((ntohl(p
[1]) & 0xffff) << 8) | ntohl(p
[2]) >> 24) != 0x00005e
931 || (ntohl(p
[2]) & 0xffffff) != 1) {
932 FWIPDEBUG(ifp
, "Unrecognised GASP header %#08x %#08x\n",
933 ntohl(p
[1]), ntohl(p
[2]));
940 * Record the sender ID for possible BPF usage.
942 src
= ntohl(p
[1]) >> 16;
943 if (bpf_peers_present(ifp
->if_bpf
)) {
944 mtag
= m_tag_alloc(MTAG_FIREWIRE
,
945 MTAG_FIREWIRE_SENDER_EUID
,
946 2*sizeof(uint32_t), M_NOWAIT
);
948 /* bpf wants it in network byte order */
949 struct fw_device
*fd
;
950 uint32_t *p2
= (uint32_t *) (mtag
+ 1);
951 fd
= fw_noderesolve_nodeid(fwip
->fd
.fc
,
954 p2
[0] = htonl(fd
->eui
.hi
);
955 p2
[1] = htonl(fd
->eui
.lo
);
960 m_tag_prepend(m
, mtag
);
965 * Trim off the GASP header
967 m_adj(m
, 3*sizeof(uint32_t));
968 m
->m_pkthdr
.rcvif
= ifp
;
969 FIREWIRE_INPUT(ifp
, m
, src
);
972 if (STAILQ_FIRST(&xferq
->stfree
) != NULL
)
973 fwip
->fd
.fc
->irx_enable(fwip
->fd
.fc
, fwip
->dma_ch
);
977 fwip_unicast_input_recycle(struct fwip_softc
*fwip
, struct fw_xfer
*xfer
)
982 * We have finished with a unicast xfer. Allocate a new
983 * cluster and stick it on the back of the input queue.
985 m
= m_getcl(M_DONTWAIT
, MT_DATA
, M_PKTHDR
);
987 printf("fwip_unicast_input_recycle: m_getcl failed\n");
989 xfer
->recv
.payload
= mtod(m
, uint32_t *);
990 xfer
->recv
.pay_len
= MCLBYTES
;
992 STAILQ_INSERT_TAIL(&fwip
->fwb
.xferlist
, xfer
, link
);
996 fwip_unicast_input(struct fw_xfer
*xfer
)
1002 struct fwip_softc
*fwip
;
1004 //struct fw_pkt *sfp;
1007 fwip
= (struct fwip_softc
*)xfer
->sc
;
1008 ifp
= fwip
->fw_softc
.fwip_ifp
;
1011 fp
= &xfer
->recv
.hdr
;
1014 * Check the fifo address - we only accept addresses of
1015 * exactly INET_FIFO.
1017 address
= ((uint64_t)fp
->mode
.wreqb
.dest_hi
<< 32)
1018 | fp
->mode
.wreqb
.dest_lo
;
1019 if (fp
->mode
.wreqb
.tcode
!= FWTCODE_WREQB
) {
1020 rtcode
= FWRCODE_ER_TYPE
;
1021 } else if (address
!= INET_FIFO
) {
1022 rtcode
= FWRCODE_ER_ADDR
;
1024 rtcode
= FWRCODE_COMPLETE
;
1028 * Pick up a new mbuf and stick it on the back of the receive
1031 fwip_unicast_input_recycle(fwip
, xfer
);
1034 * If we've already rejected the packet, give up now.
1036 if (rtcode
!= FWRCODE_COMPLETE
) {
1042 if (bpf_peers_present(ifp
->if_bpf
)) {
1044 * Record the sender ID for possible BPF usage.
1046 mtag
= m_tag_alloc(MTAG_FIREWIRE
, MTAG_FIREWIRE_SENDER_EUID
,
1047 2*sizeof(uint32_t), M_NOWAIT
);
1049 /* bpf wants it in network byte order */
1050 struct fw_device
*fd
;
1051 uint32_t *p
= (uint32_t *) (mtag
+ 1);
1052 fd
= fw_noderesolve_nodeid(fwip
->fd
.fc
,
1053 fp
->mode
.wreqb
.src
& 0x3f);
1055 p
[0] = htonl(fd
->eui
.hi
);
1056 p
[1] = htonl(fd
->eui
.lo
);
1061 m_tag_prepend(m
, mtag
);
1066 * Hand off to the generic encapsulation code. We don't use
1067 * ifp->if_input so that we can pass the source nodeid as an
1068 * argument to facilitate link-level fragment reassembly.
1070 m
->m_len
= m
->m_pkthdr
.len
= fp
->mode
.wreqb
.len
;
1071 m
->m_pkthdr
.rcvif
= ifp
;
1072 FIREWIRE_INPUT(ifp
, m
, fp
->mode
.wreqb
.src
);
1073 ifp
->if_ipackets
++;
1076 #if defined(__FreeBSD__)
1077 static devclass_t fwip_devclass
;
1079 static device_method_t fwip_methods
[] = {
1080 /* device interface */
1081 DEVMETHOD(device_identify
, fwip_identify
),
1082 DEVMETHOD(device_probe
, fwip_probe
),
1083 DEVMETHOD(device_attach
, fwip_attach
),
1084 DEVMETHOD(device_detach
, fwip_detach
),
1088 static driver_t fwip_driver
= {
1091 sizeof(struct fwip_softc
),
1095 #ifdef __DragonFly__
1096 DECLARE_DUMMY_MODULE(fwip
);
1098 DRIVER_MODULE(fwip
, firewire
, fwip_driver
, fwip_devclass
, 0, 0);
1099 MODULE_VERSION(fwip
, 1);
1100 MODULE_DEPEND(fwip
, firewire
, 1, 1, 1);
1101 #elif defined(__NetBSD__)
1102 CFATTACH_DECL_NEW(fwip
, sizeof(struct fwip_softc
),
1103 fwipmatch
, fwipattach
, fwipdetach
, NULL
);