Home | History | Annotate | Line # | Download | only in ieee1394
if_fwip.c revision 1.2
      1 /*	$NetBSD: if_fwip.c,v 1.2 2005/07/23 16:55:13 kiyohara Exp $	*/
      2 /*-
      3  * Copyright (c) 2004
      4  *	Doug Rabson
      5  * Copyright (c) 2002-2003
      6  * 	Hidetoshi Shimokawa. All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     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:
     18  *
     19  *	This product includes software developed by Hidetoshi Shimokawa.
     20  *
     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.
     24  *
     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
     35  * SUCH DAMAGE.
     36  *
     37  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/if_fwip.c,v 1.6 2005/01/06 01:42:41 imp Exp $
     38  */
     39 
     40 #include "opt_inet.h"
     41 
     42 #if defined(__FreeBSD__)
     43 #include <sys/param.h>
     44 #include <sys/kernel.h>
     45 #include <sys/malloc.h>
     46 #include <sys/mbuf.h>
     47 #include <sys/socket.h>
     48 #include <sys/sockio.h>
     49 #include <sys/sysctl.h>
     50 #include <sys/systm.h>
     51 #include <sys/taskqueue.h>
     52 #include <sys/module.h>
     53 #include <sys/bus.h>
     54 #include <machine/bus.h>
     55 
     56 #include <net/bpf.h>
     57 #include <net/if.h>
     58 #include <net/firewire.h>
     59 #include <net/if_arp.h>
     60 #ifdef __DragonFly__
     61 #include <bus/firewire/fw_port.h>
     62 #include <bus/firewire/firewire.h>
     63 #include <bus/firewire/firewirereg.h>
     64 #include "if_fwipvar.h"
     65 #else
     66 #include <dev/firewire/fw_port.h>
     67 #include <dev/firewire/firewire.h>
     68 #include <dev/firewire/firewirereg.h>
     69 #include <dev/firewire/iec13213.h>
     70 #include <dev/firewire/if_fwipvar.h>
     71 #endif
     72 #elif defined(__NetBSD__)
     73 #include <sys/param.h>
     74 #include <sys/device.h>
     75 #include <sys/errno.h>
     76 #include <sys/malloc.h>
     77 #include <sys/mbuf.h>
     78 #include <sys/sysctl.h>
     79 
     80 #include <machine/bus.h>
     81 
     82 #include <net/if.h>
     83 #include <net/if_ieee1394.h>
     84 
     85 #include <dev/ieee1394/fw_port.h>
     86 #include <dev/ieee1394/firewire.h>
     87 #include <dev/ieee1394/firewirereg.h>
     88 #include <dev/ieee1394/iec13213.h>
     89 #include <dev/ieee1394/if_fwipvar.h>
     90 #endif
     91 
     92 /*
     93  * We really need a mechanism for allocating regions in the FIFO
     94  * address space. We pick a address in the OHCI controller's 'middle'
     95  * address space. This means that the controller will automatically
     96  * send responses for us, which is fine since we don't have any
     97  * important information to put in the response anyway.
     98  */
     99 #define INET_FIFO	0xfffe00000000LL
    100 
    101 #if defined(__FreeBSD__)
    102 #define FWIPDEBUG	if (fwipdebug) if_printf
    103 #elif defined(__NetBSD__)
    104 #define FWIPDEBUG(ifp, fmt, ...) \
    105 	if (fwipdebug) {\
    106 		aprint_normal("%s: ", (ifp)->if_xname); \
    107 		aprint_normal((fmt) ,##__VA_ARGS__); \
    108 	}
    109 #endif
    110 #define TX_MAX_QUEUE	(FWMAXQUEUE - 1)
    111 
    112 #if defined(__NetBSD__)
    113 int fwipmatch (struct device *, struct cfdata *, void *);
    114 void fwipattach (struct device *, struct device *, void *);
    115 int fwipdetach (struct device *, int);
    116 int fwipactivate (struct device *, enum devact);
    117 
    118 #endif
    119 /* network interface */
    120 static void fwip_start (struct ifnet *);
    121 static int fwip_ioctl (struct ifnet *, u_long, caddr_t);
    122 IF_INIT(fwip);
    123 IF_STOP(fwip);
    124 
    125 static void fwip_post_busreset (void *);
    126 static void fwip_output_callback (struct fw_xfer *);
    127 static void fwip_async_output (struct fwip_softc *, struct ifnet *);
    128 #if defined(__FreeBSD__)
    129 static void fwip_start_send (void *, int);
    130 #endif
    131 static void fwip_stream_input (struct fw_xferq *);
    132 static void fwip_unicast_input(struct fw_xfer *);
    133 
    134 static int fwipdebug = 0;
    135 static int broadcast_channel = 0xc0 | 0x1f; /*  tag | channel(XXX) */
    136 static int tx_speed = 2;
    137 static int rx_queue_len = FWMAXQUEUE;
    138 
    139 #if defined(__FreeBSD__)
    140 MALLOC_DEFINE(M_FWIP, "if_fwip", "IP over FireWire interface");
    141 SYSCTL_INT(_debug, OID_AUTO, if_fwip_debug, CTLFLAG_RW, &fwipdebug, 0, "");
    142 SYSCTL_DECL(_hw_firewire);
    143 SYSCTL_NODE(_hw_firewire, OID_AUTO, fwip, CTLFLAG_RD, 0,
    144 	"Firewire ip subsystem");
    145 SYSCTL_INT(_hw_firewire_fwip, OID_AUTO, rx_queue_len, CTLFLAG_RW, &rx_queue_len,
    146 	0, "Length of the receive queue");
    147 
    148 TUNABLE_INT("hw.firewire.fwip.rx_queue_len", &rx_queue_len);
    149 #elif defined(__NetBSD__)
    150 MALLOC_DEFINE(M_FWIP, "if_fwip", "IP over IEEE1394 interface");
    151 /*
    152  * Setup sysctl(3) MIB, hw.fwip.*
    153  *
    154  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
    155  */
    156 SYSCTL_SETUP(sysctl_fwip, "sysctl fwip(4) subtree setup")
    157 {
    158 	int rc, fwip_node_num;
    159 	const struct sysctlnode *node;
    160 
    161 	if ((rc = sysctl_createv(clog, 0, NULL, NULL,
    162 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    163 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
    164 		goto err;
    165 	}
    166 
    167 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    168 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "fwip",
    169 	    SYSCTL_DESCR("fwip controls"),
    170 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
    171 		goto err;
    172 	}
    173 	fwip_node_num = node->sysctl_num;
    174 
    175 	/* fwip RX queue length */
    176 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    177 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
    178 	    "rx_queue_len", SYSCTL_DESCR("Length of the receive queue"),
    179 	    NULL, 0, &rx_queue_len,
    180 	    0, CTL_HW, fwip_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    181 		goto err;
    182 	}
    183 
    184 	/* fwip RX queue length */
    185 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
    186 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
    187 	    "if_fwip_debug", SYSCTL_DESCR("fwip driver debug flag"),
    188 	    NULL, 0, &fwipdebug,
    189 	    0, CTL_HW, fwip_node_num, CTL_CREATE, CTL_EOL)) != 0) {
    190 		goto err;
    191 	}
    192 
    193 	return;
    194 
    195 err:
    196 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    197 }
    198 #endif
    199 
    200 #ifdef DEVICE_POLLING
    201 #define FWIP_POLL_REGISTER(func, fwip, ifp)			\
    202 	if (ether_poll_register(func, ifp)) {			\
    203 		struct firewire_comm *fc = (fwip)->fd.fc;	\
    204 		fc->set_intr(fc, 0);				\
    205 	}
    206 
    207 #define FWIP_POLL_DEREGISTER(fwip, ifp)				\
    208 	do {							\
    209 		struct firewire_comm *fc = (fwip)->fd.fc;	\
    210 		ether_poll_deregister(ifp);			\
    211 		fc->set_intr(fc, 1);				\
    212 	} while(0)						\
    213 
    214 static poll_handler_t fwip_poll;
    215 
    216 static void
    217 fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
    218 {
    219 	struct fwip_softc *fwip;
    220 	struct firewire_comm *fc;
    221 
    222 	fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
    223 	fc = fwip->fd.fc;
    224 	if (cmd == POLL_DEREGISTER) {
    225 		/* enable interrupts */
    226 		fc->set_intr(fc, 1);
    227 		return;
    228 	}
    229 	fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
    230 }
    231 #else
    232 #define FWIP_POLL_REGISTER(func, fwip, ifp)
    233 #define FWIP_POLL_DEREGISTER(fwip, ifp)
    234 #endif
    235 #if defined(__FreeBSD__)
    236 static void
    237 fwip_identify(driver_t *driver, device_t parent)
    238 {
    239 	BUS_ADD_CHILD(parent, 0, "fwip", device_get_unit(parent));
    240 }
    241 
    242 static int
    243 fwip_probe(device_t dev)
    244 {
    245 	device_t pa;
    246 
    247 	pa = device_get_parent(dev);
    248 	if(device_get_unit(dev) != device_get_unit(pa)){
    249 		return(ENXIO);
    250 	}
    251 
    252 	device_set_desc(dev, "IP over FireWire");
    253 	return (0);
    254 }
    255 #elif defined(__NetBSD__)
    256 int
    257 fwipmatch(struct device *parent, struct cfdata *cf, void *aux)
    258 {
    259 	struct fw_attach_args *fwa = aux;
    260 
    261 	if (strcmp(fwa->name, "fwip") == 0)
    262 		return (1);
    263 	return (0);
    264 }
    265 #endif
    266 
    267 FW_ATTACH(fwip)
    268 {
    269 	FW_ATTACH_START(fwip, fwip, fwa);
    270 	FWIP_ATTACH_START;
    271 	struct ifnet *ifp;
    272 	int s;
    273 
    274 	FWIP_ATTACH_SETUP;
    275 
    276 	/* XXX */
    277 	fwip->dma_ch = -1;
    278 
    279 	fwip->fd.fc = fwa->fc;
    280 	if (tx_speed < 0)
    281 		tx_speed = fwip->fd.fc->speed;
    282 
    283 	fwip->fd.post_explore = NULL;
    284 	fwip->fd.post_busreset = fwip_post_busreset;
    285 	fwip->fw_softc.fwip = fwip;
    286 	TASK_INIT(&fwip->start_send, 0, fwip_start_send, fwip);
    287 
    288 	/*
    289 	 * Encode our hardware the way that arp likes it.
    290 	 */
    291 	hwaddr->sender_unique_ID_hi = htonl(fwip->fd.fc->eui.hi);
    292 	hwaddr->sender_unique_ID_lo = htonl(fwip->fd.fc->eui.lo);
    293 	hwaddr->sender_max_rec = fwip->fd.fc->maxrec;
    294 	hwaddr->sspd = fwip->fd.fc->speed;
    295 	hwaddr->sender_unicast_FIFO_hi = htons((uint16_t)(INET_FIFO >> 32));
    296 	hwaddr->sender_unicast_FIFO_lo = htonl((uint32_t)INET_FIFO);
    297 
    298 	/* fill the rest and attach interface */
    299 	ifp = &fwip->fwip_if;
    300 	ifp->if_softc = &fwip->fw_softc;
    301 
    302 #if __FreeBSD_version >= 501113 || defined(__DragonFly__) || defined(__NetBSD__)
    303 	IF_INITNAME(ifp, dev, unit);
    304 #else
    305 	ifp->if_unit = unit;
    306 	ifp->if_name = "fwip";
    307 #endif
    308 #if defined(__NetBSD__)
    309 	IFQ_SET_READY(&ifp->if_snd);
    310 #endif
    311 	SET_IFFUNC(ifp, fwip_start, fwip_ioctl, fwip_init, fwip_stop);
    312 	ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|
    313 	    IFF_NEEDSGIANT);
    314 	ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
    315 
    316 	s = splfwnet();
    317 	FIREWIRE_IFATTACH(ifp, hwaddr);
    318 	splx(s);
    319 
    320 	FWIPDEBUG(ifp, "interface created\n");
    321 	FW_ATTACH_RETURN(0);
    322 }
    323 
    324 IF_STOP(fwip)
    325 {
    326 	IF_STOP_START(fwip, ifp, fwip);
    327 	struct firewire_comm *fc;
    328 	struct fw_xferq *xferq;
    329 	struct fw_xfer *xfer, *next;
    330 	int i;
    331 
    332 	fc = fwip->fd.fc;
    333 
    334 	FWIP_POLL_DEREGISTER(fwip, ifp);
    335 
    336 	if (fwip->dma_ch >= 0) {
    337 		xferq = fc->ir[fwip->dma_ch];
    338 
    339 		if (xferq->flag & FWXFERQ_RUNNING)
    340 			fc->irx_disable(fc, fwip->dma_ch);
    341 		xferq->flag &=
    342 			~(FWXFERQ_MODEMASK | FWXFERQ_OPEN | FWXFERQ_STREAM |
    343 			FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_CHTAGMASK);
    344 		xferq->hand =  NULL;
    345 
    346 		for (i = 0; i < xferq->bnchunk; i ++)
    347 			m_freem(xferq->bulkxfer[i].mbuf);
    348 		free(xferq->bulkxfer, M_FWIP);
    349 
    350 		fw_bindremove(fc, &fwip->fwb);
    351 		for (xfer = STAILQ_FIRST(&fwip->fwb.xferlist); xfer != NULL;
    352 					xfer = next) {
    353 			next = STAILQ_NEXT(xfer, link);
    354 			fw_xfer_free(xfer);
    355 		}
    356 
    357 		for (xfer = STAILQ_FIRST(&fwip->xferlist); xfer != NULL;
    358 					xfer = next) {
    359 			next = STAILQ_NEXT(xfer, link);
    360 			fw_xfer_free(xfer);
    361 		}
    362 		STAILQ_INIT(&fwip->xferlist);
    363 
    364 		xferq->bulkxfer =  NULL;
    365 		fwip->dma_ch = -1;
    366 	}
    367 
    368 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
    369 }
    370 
    371 FW_DETACH(fwip)
    372 {
    373 	IF_DETACH_START(fwip, fwip);
    374 	int s;
    375 
    376 	s = splfwnet();
    377 
    378 	FWIP_STOP(fwip);
    379 	FIREWIRE_IFDETACH(&fwip->fwip_if);
    380 
    381 	splx(s);
    382 	return 0;
    383 }
    384 
    385 #if defined(__NetBSD__)
    386 int
    387 fwipactivate(struct device *self, enum devact act)
    388 {
    389 	struct fwip_softc *fwip = (struct fwip_softc *)self;
    390 	int s, error = 0;
    391 
    392 	s = splfwnet();
    393 	switch (act) {
    394 	case DVACT_ACTIVATE:
    395 		error = EOPNOTSUPP;
    396 		break;
    397 
    398 	case DVACT_DEACTIVATE:
    399 		if_deactivate(&fwip->fwip_if);
    400 			break;
    401 	}
    402 	splx(s);
    403 
    404 	return (error);
    405 }
    406 
    407 #endif
    408 IF_INIT(fwip)
    409 {
    410 	IF_INIT_START(fwip, fwip, ifp);
    411 	struct firewire_comm *fc;
    412 	struct fw_xferq *xferq;
    413 	struct fw_xfer *xfer;
    414 	struct mbuf *m;
    415 	int i;
    416 
    417 	FWIPDEBUG(ifp, "initializing\n");
    418 
    419 	fc = fwip->fd.fc;
    420 #define START 0
    421 	if (fwip->dma_ch < 0) {
    422 		for (i = START; i < fc->nisodma; i ++) {
    423 			xferq = fc->ir[i];
    424 			if ((xferq->flag & FWXFERQ_OPEN) == 0)
    425 				goto found;
    426 		}
    427 		printf("no free dma channel\n");
    428 		IF_INIT_RETURN(ENXIO);
    429 found:
    430 		fwip->dma_ch = i;
    431 		/* allocate DMA channel and init packet mode */
    432 		xferq->flag |= FWXFERQ_OPEN | FWXFERQ_EXTBUF |
    433 				FWXFERQ_HANDLER | FWXFERQ_STREAM;
    434 		xferq->flag &= ~0xff;
    435 		xferq->flag |= broadcast_channel & 0xff;
    436 		/* register fwip_input handler */
    437 		xferq->sc = (caddr_t) fwip;
    438 		xferq->hand = fwip_stream_input;
    439 		xferq->bnchunk = rx_queue_len;
    440 		xferq->bnpacket = 1;
    441 		xferq->psize = MCLBYTES;
    442 		xferq->queued = 0;
    443 		xferq->buf = NULL;
    444 		xferq->bulkxfer = (struct fw_bulkxfer *) malloc(
    445 			sizeof(struct fw_bulkxfer) * xferq->bnchunk,
    446 							M_FWIP, M_WAITOK);
    447 		if (xferq->bulkxfer == NULL) {
    448 			printf("if_fwip: malloc failed\n");
    449 			IF_INIT_RETURN(ENOMEM);
    450 		}
    451 		STAILQ_INIT(&xferq->stvalid);
    452 		STAILQ_INIT(&xferq->stfree);
    453 		STAILQ_INIT(&xferq->stdma);
    454 		xferq->stproc = NULL;
    455 		for (i = 0; i < xferq->bnchunk; i ++) {
    456 			m =
    457 #if defined(__DragonFly__) || __FreeBSD_version < 500000
    458 				m_getcl(M_WAIT, MT_DATA, M_PKTHDR);
    459 #else
    460 				m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR);
    461 #endif
    462 			xferq->bulkxfer[i].mbuf = m;
    463 			if (m != NULL) {
    464 				m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
    465 				STAILQ_INSERT_TAIL(&xferq->stfree,
    466 						&xferq->bulkxfer[i], link);
    467 			} else
    468 				printf("fwip_as_input: m_getcl failed\n");
    469 		}
    470 
    471 		fwip->fwb.start = INET_FIFO;
    472 		fwip->fwb.end = INET_FIFO + 16384; /* S3200 packet size */
    473 
    474 		/* pre-allocate xfer */
    475 		STAILQ_INIT(&fwip->fwb.xferlist);
    476 		for (i = 0; i < rx_queue_len; i ++) {
    477 			xfer = fw_xfer_alloc(M_FWIP);
    478 			if (xfer == NULL)
    479 				break;
    480 			m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR);
    481 			xfer->recv.payload = mtod(m, uint32_t *);
    482 			xfer->recv.pay_len = MCLBYTES;
    483 			xfer->hand = fwip_unicast_input;
    484 			xfer->fc = fc;
    485 			xfer->sc = (caddr_t)fwip;
    486 			xfer->mbuf = m;
    487 			STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link);
    488 		}
    489 		fw_bindadd(fc, &fwip->fwb);
    490 
    491 		STAILQ_INIT(&fwip->xferlist);
    492 		for (i = 0; i < TX_MAX_QUEUE; i++) {
    493 			xfer = fw_xfer_alloc(M_FWIP);
    494 			if (xfer == NULL)
    495 				break;
    496 			xfer->send.spd = tx_speed;
    497 			xfer->fc = fwip->fd.fc;
    498 			xfer->sc = (caddr_t)fwip;
    499 			xfer->hand = fwip_output_callback;
    500 			STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
    501 		}
    502 	} else
    503 		xferq = fc->ir[fwip->dma_ch];
    504 
    505 	fwip->last_dest.hi = 0;
    506 	fwip->last_dest.lo = 0;
    507 
    508 	/* start dma */
    509 	if ((xferq->flag & FWXFERQ_RUNNING) == 0)
    510 		fc->irx_enable(fc, fwip->dma_ch);
    511 
    512 	ifp->if_flags |= IFF_RUNNING;
    513 	ifp->if_flags &= ~IFF_OACTIVE;
    514 
    515 	FWIP_POLL_REGISTER(fwip_poll, fwip, ifp);
    516 #if 0
    517 	/* attempt to start output */
    518 	fwip_start(ifp);
    519 #endif
    520 	IF_INIT_RETURN(0);
    521 }
    522 
    523 static int
    524 fwip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    525 {
    526 	IF_IOCTL_START(fwip, fwip);
    527 	int s, error;
    528 
    529 	switch (cmd) {
    530 	case SIOCSIFFLAGS:
    531 		s = splfwnet();
    532 		if (ifp->if_flags & IFF_UP) {
    533 			if (!(ifp->if_flags & IFF_RUNNING))
    534 				FWIP_INIT(fwip);
    535 		} else {
    536 			if (ifp->if_flags & IFF_RUNNING)
    537 				FWIP_STOP(fwip);
    538 		}
    539 		splx(s);
    540 		break;
    541 	case SIOCADDMULTI:
    542 	case SIOCDELMULTI:
    543 		break;
    544 
    545 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__NetBSD__)
    546 	default:
    547 #else
    548 	case SIOCSIFADDR:
    549 	case SIOCGIFADDR:
    550 	case SIOCSIFMTU:
    551 #endif
    552 		s = splfwnet();
    553 		error = FIREWIRE_IOCTL(ifp, cmd, data);
    554 		splx(s);
    555 		return (error);
    556 #if defined(__DragonFly__) || \
    557     (defined(__FreeBSD__) && __FreeBSD_version < 500000)
    558 	default:
    559 		return (EINVAL);
    560 #endif
    561 	}
    562 
    563 	return (0);
    564 }
    565 
    566 static void
    567 fwip_post_busreset(void *arg)
    568 {
    569 	struct fwip_softc *fwip = arg;
    570 	struct crom_src *src;
    571 	struct crom_chunk *root;
    572 
    573 	src = fwip->fd.fc->crom_src;
    574 	root = fwip->fd.fc->crom_root;
    575 
    576 	/* RFC2734 IPv4 over IEEE1394 */
    577 	bzero(&fwip->unit4, sizeof(struct crom_chunk));
    578 	crom_add_chunk(src, root, &fwip->unit4, CROM_UDIR);
    579 	crom_add_entry(&fwip->unit4, CSRKEY_SPEC, CSRVAL_IETF);
    580 	crom_add_simple_text(src, &fwip->unit4, &fwip->spec4, "IANA");
    581 	crom_add_entry(&fwip->unit4, CSRKEY_VER, 1);
    582 	crom_add_simple_text(src, &fwip->unit4, &fwip->ver4, "IPv4");
    583 
    584 	/* RFC3146 IPv6 over IEEE1394 */
    585 	bzero(&fwip->unit6, sizeof(struct crom_chunk));
    586 	crom_add_chunk(src, root, &fwip->unit6, CROM_UDIR);
    587 	crom_add_entry(&fwip->unit6, CSRKEY_SPEC, CSRVAL_IETF);
    588 	crom_add_simple_text(src, &fwip->unit6, &fwip->spec6, "IANA");
    589 	crom_add_entry(&fwip->unit6, CSRKEY_VER, 2);
    590 	crom_add_simple_text(src, &fwip->unit6, &fwip->ver6, "IPv6");
    591 
    592 	fwip->last_dest.hi = 0;
    593 	fwip->last_dest.lo = 0;
    594 	FIREWIRE_BUSRESET(&fwip->fwip_if);
    595 }
    596 
    597 static void
    598 fwip_output_callback(struct fw_xfer *xfer)
    599 {
    600 	struct fwip_softc *fwip;
    601 	struct ifnet *ifp;
    602 	int s;
    603 
    604 	GIANT_REQUIRED;
    605 
    606 	fwip = (struct fwip_softc *)xfer->sc;
    607 	ifp = &fwip->fwip_if;
    608 	/* XXX error check */
    609 	FWIPDEBUG(ifp, "resp = %d\n", xfer->resp);
    610 	if (xfer->resp != 0)
    611 		ifp->if_oerrors ++;
    612 
    613 	m_freem(xfer->mbuf);
    614 	fw_xfer_unload(xfer);
    615 
    616 	s = splfwnet();
    617 	STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
    618 	splx(s);
    619 
    620 	/* for queue full */
    621 	if (ifp->if_snd.ifq_head != NULL)
    622 		fwip_start(ifp);
    623 }
    624 
    625 static void
    626 fwip_start(struct ifnet *ifp)
    627 {
    628 	struct fwip_softc *fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
    629 	int s;
    630 
    631 	GIANT_REQUIRED;
    632 
    633 	FWIPDEBUG(ifp, "starting\n");
    634 
    635 	if (fwip->dma_ch < 0) {
    636 		struct mbuf	*m = NULL;
    637 
    638 		FWIPDEBUG(ifp, "not ready\n");
    639 
    640 		s = splfwnet();
    641 		do {
    642 			IF_DEQUEUE(&ifp->if_snd, m);
    643 			if (m != NULL)
    644 				m_freem(m);
    645 			ifp->if_oerrors ++;
    646 		} while (m != NULL);
    647 		splx(s);
    648 
    649 		return;
    650 	}
    651 
    652 	s = splfwnet();
    653 	ifp->if_flags |= IFF_OACTIVE;
    654 
    655 	if (ifp->if_snd.ifq_len != 0)
    656 		fwip_async_output(fwip, ifp);
    657 
    658 	ifp->if_flags &= ~IFF_OACTIVE;
    659 	splx(s);
    660 }
    661 
    662 /* Async. stream output */
    663 static void
    664 fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
    665 {
    666 	struct firewire_comm *fc = fwip->fd.fc;
    667 	struct mbuf *m;
    668 	struct m_tag *mtag;
    669 	struct fw_hwaddr *destfw;
    670 	struct fw_xfer *xfer;
    671 	struct fw_xferq *xferq;
    672 	struct fw_pkt *fp;
    673 	uint16_t nodeid;
    674 	int error;
    675 	int i = 0;
    676 
    677 	GIANT_REQUIRED;
    678 
    679 	xfer = NULL;
    680 	xferq = fwip->fd.fc->atq;
    681 	while (xferq->queued < xferq->maxq - 1) {
    682 		xfer = STAILQ_FIRST(&fwip->xferlist);
    683 		if (xfer == NULL) {
    684 			printf("if_fwip: lack of xfer\n");
    685 			return;
    686 		}
    687 		IF_DEQUEUE(&ifp->if_snd, m);
    688 		if (m == NULL)
    689 			break;
    690 
    691 		/*
    692 		 * Dig out the link-level address which
    693 		 * firewire_output got via arp or neighbour
    694 		 * discovery. If we don't have a link-level address,
    695 		 * just stick the thing on the broadcast channel.
    696 		 */
    697 		mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 0);
    698 		if (mtag == NULL)
    699 			destfw = 0;
    700 		else
    701 			destfw = (struct fw_hwaddr *) (mtag + 1);
    702 
    703 		STAILQ_REMOVE_HEAD(&fwip->xferlist, link);
    704 
    705 		/*
    706 		 * We don't do any bpf stuff here - the generic code
    707 		 * in firewire_output gives the packet to bpf before
    708 		 * it adds the link-level encapsulation.
    709 		 */
    710 
    711 		/*
    712 		 * Put the mbuf in the xfer early in case we hit an
    713 		 * error case below - fwip_output_callback will free
    714 		 * the mbuf.
    715 		 */
    716 		xfer->mbuf = m;
    717 
    718 		/*
    719 		 * We use the arp result (if any) to add a suitable firewire
    720 		 * packet header before handing off to the bus.
    721 		 */
    722 		fp = &xfer->send.hdr;
    723 		nodeid = FWLOCALBUS | fc->nodeid;
    724 		if ((m->m_flags & M_BCAST) || !destfw) {
    725 			/*
    726 			 * Broadcast packets are sent as GASP packets with
    727 			 * specifier ID 0x00005e, version 1 on the broadcast
    728 			 * channel. To be conservative, we send at the
    729 			 * slowest possible speed.
    730 			 */
    731 			uint32_t *p;
    732 
    733 			M_PREPEND(m, 2*sizeof(uint32_t), M_DONTWAIT);
    734 			p = mtod(m, uint32_t *);
    735 			fp->mode.stream.len = m->m_pkthdr.len;
    736 			fp->mode.stream.chtag = broadcast_channel;
    737 			fp->mode.stream.tcode = FWTCODE_STREAM;
    738 			fp->mode.stream.sy = 0;
    739 			xfer->send.spd = 0;
    740 			p[0] = htonl(nodeid << 16);
    741 			p[1] = htonl((0x5e << 24) | 1);
    742 		} else {
    743 			/*
    744 			 * Unicast packets are sent as block writes to the
    745 			 * target's unicast fifo address. If we can't
    746 			 * find the node address, we just give up. We
    747 			 * could broadcast it but that might overflow
    748 			 * the packet size limitations due to the
    749 			 * extra GASP header. Note: the hardware
    750 			 * address is stored in network byte order to
    751 			 * make life easier for ARP.
    752 			 */
    753 			struct fw_device *fd;
    754 			struct fw_eui64 eui;
    755 
    756 			eui.hi = ntohl(destfw->sender_unique_ID_hi);
    757 			eui.lo = ntohl(destfw->sender_unique_ID_lo);
    758 			if (fwip->last_dest.hi != eui.hi ||
    759 			    fwip->last_dest.lo != eui.lo) {
    760 				fd = fw_noderesolve_eui64(fc, &eui);
    761 				if (!fd) {
    762 					/* error */
    763 					ifp->if_oerrors ++;
    764 					/* XXX set error code */
    765 					fwip_output_callback(xfer);
    766 					continue;
    767 
    768 				}
    769 				fwip->last_hdr.mode.wreqb.dst = FWLOCALBUS | fd->dst;
    770 				fwip->last_hdr.mode.wreqb.tlrt = 0;
    771 				fwip->last_hdr.mode.wreqb.tcode = FWTCODE_WREQB;
    772 				fwip->last_hdr.mode.wreqb.pri = 0;
    773 				fwip->last_hdr.mode.wreqb.src = nodeid;
    774 				fwip->last_hdr.mode.wreqb.dest_hi =
    775 					ntohs(destfw->sender_unicast_FIFO_hi);
    776 				fwip->last_hdr.mode.wreqb.dest_lo =
    777 					ntohl(destfw->sender_unicast_FIFO_lo);
    778 				fwip->last_hdr.mode.wreqb.extcode = 0;
    779 				fwip->last_dest = eui;
    780 			}
    781 
    782 			fp->mode.wreqb = fwip->last_hdr.mode.wreqb;
    783 			fp->mode.wreqb.len = m->m_pkthdr.len;
    784 			xfer->send.spd = min(destfw->sspd, fc->speed);
    785 		}
    786 
    787 		xfer->send.pay_len = m->m_pkthdr.len;
    788 
    789 		error = fw_asyreq(fc, -1, xfer);
    790 		if (error == EAGAIN) {
    791 			/*
    792 			 * We ran out of tlabels - requeue the packet
    793 			 * for later transmission.
    794 			 */
    795 			xfer->mbuf = 0;
    796 			STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
    797 			IF_PREPEND(&ifp->if_snd, m);
    798 			break;
    799 		}
    800 		if (error) {
    801 			/* error */
    802 			ifp->if_oerrors ++;
    803 			/* XXX set error code */
    804 			fwip_output_callback(xfer);
    805 			continue;
    806 		} else {
    807 			ifp->if_opackets ++;
    808 			i++;
    809 		}
    810 	}
    811 #if 0
    812 	if (i > 1)
    813 		printf("%d queued\n", i);
    814 #endif
    815 	if (i > 0) {
    816 #if 1
    817 		xferq->start(fc);
    818 #else
    819 		taskqueue_enqueue(taskqueue_swi_giant, &fwip->start_send);
    820 #endif
    821 	}
    822 }
    823 
    824 #if defined(__FreeBSD__)
    825 static void
    826 fwip_start_send (void *arg, int count)
    827 {
    828 	struct fwip_softc *fwip = arg;
    829 
    830 	GIANT_REQUIRED;
    831 	fwip->fd.fc->atq->start(fwip->fd.fc);
    832 }
    833 #endif
    834 
    835 /* Async. stream output */
    836 static void
    837 fwip_stream_input(struct fw_xferq *xferq)
    838 {
    839 	struct mbuf *m, *m0;
    840 	struct m_tag *mtag;
    841 	struct ifnet *ifp;
    842 	struct fwip_softc *fwip;
    843 	struct fw_bulkxfer *sxfer;
    844 	struct fw_pkt *fp;
    845 	uint16_t src;
    846 	uint32_t *p;
    847 
    848 	GIANT_REQUIRED;
    849 
    850 	fwip = (struct fwip_softc *)xferq->sc;
    851 	ifp = &fwip->fwip_if;
    852 #if 0
    853 	FWIP_POLL_REGISTER(fwip_poll, fwip, ifp);
    854 #endif
    855 	while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) {
    856 		STAILQ_REMOVE_HEAD(&xferq->stvalid, link);
    857 		fp = mtod(sxfer->mbuf, struct fw_pkt *);
    858 		if (fwip->fd.fc->irx_post != NULL)
    859 			fwip->fd.fc->irx_post(fwip->fd.fc, fp->mode.ld);
    860 		m = sxfer->mbuf;
    861 
    862 		/* insert new rbuf */
    863 		sxfer->mbuf = m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    864 		if (m0 != NULL) {
    865 			m0->m_len = m0->m_pkthdr.len = m0->m_ext.ext_size;
    866 			STAILQ_INSERT_TAIL(&xferq->stfree, sxfer, link);
    867 		} else
    868 			printf("fwip_as_input: m_getcl failed\n");
    869 
    870 		/*
    871 		 * We must have a GASP header - leave the
    872 		 * encapsulation sanity checks to the generic
    873 		 * code. Remeber that we also have the firewire async
    874 		 * stream header even though that isn't accounted for
    875 		 * in mode.stream.len.
    876 		 */
    877 		if (sxfer->resp != 0 || fp->mode.stream.len <
    878 		    2*sizeof(uint32_t)) {
    879 			m_freem(m);
    880 			ifp->if_ierrors ++;
    881 			continue;
    882 		}
    883 		m->m_len = m->m_pkthdr.len = fp->mode.stream.len
    884 			+ sizeof(fp->mode.stream);
    885 
    886 		/*
    887 		 * If we received the packet on the broadcast channel,
    888 		 * mark it as broadcast, otherwise we assume it must
    889 		 * be multicast.
    890 		 */
    891 		if (fp->mode.stream.chtag == broadcast_channel)
    892 			m->m_flags |= M_BCAST;
    893 		else
    894 			m->m_flags |= M_MCAST;
    895 
    896 		/*
    897 		 * Make sure we recognise the GASP specifier and
    898 		 * version.
    899 		 */
    900 		p = mtod(m, uint32_t *);
    901 		if ((((ntohl(p[1]) & 0xffff) << 8) | ntohl(p[2]) >> 24) != 0x00005e
    902 		    || (ntohl(p[2]) & 0xffffff) != 1) {
    903 			FWIPDEBUG(ifp, "Unrecognised GASP header %#08x %#08x\n",
    904 			    ntohl(p[1]), ntohl(p[2]));
    905 			m_freem(m);
    906 			ifp->if_ierrors ++;
    907 			continue;
    908 		}
    909 
    910 		/*
    911 		 * Record the sender ID for possible BPF usage.
    912 		 */
    913 		src = ntohl(p[1]) >> 16;
    914 		if (ifp->if_bpf) {
    915 			mtag = m_tag_alloc(MTAG_FIREWIRE,
    916 			    MTAG_FIREWIRE_SENDER_EUID,
    917 			    2*sizeof(uint32_t), M_NOWAIT);
    918 			if (mtag) {
    919 				/* bpf wants it in network byte order */
    920 				struct fw_device *fd;
    921 				uint32_t *p2 = (uint32_t *) (mtag + 1);
    922 				fd = fw_noderesolve_nodeid(fwip->fd.fc,
    923 				    src & 0x3f);
    924 				if (fd) {
    925 					p2[0] = htonl(fd->eui.hi);
    926 					p2[1] = htonl(fd->eui.lo);
    927 				} else {
    928 					p2[0] = 0;
    929 					p2[1] = 0;
    930 				}
    931 				m_tag_prepend(m, mtag);
    932 			}
    933 		}
    934 
    935 		/*
    936 		 * Trim off the GASP header
    937 		 */
    938 		m_adj(m, 3*sizeof(uint32_t));
    939 		m->m_pkthdr.rcvif = ifp;
    940 		FIREWIRE_INPUT(ifp, m, src);
    941 		ifp->if_ipackets ++;
    942 	}
    943 	if (STAILQ_FIRST(&xferq->stfree) != NULL)
    944 		fwip->fd.fc->irx_enable(fwip->fd.fc, fwip->dma_ch);
    945 }
    946 
    947 static __inline void
    948 fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer)
    949 {
    950 	struct mbuf *m;
    951 
    952 	GIANT_REQUIRED;
    953 
    954 	/*
    955 	 * We have finished with a unicast xfer. Allocate a new
    956 	 * cluster and stick it on the back of the input queue.
    957 	 */
    958 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
    959 	if (m == NULL)
    960 		printf("fwip_unicast_input_recycle: m_getcl failed\n");
    961 	xfer->mbuf = m;
    962 	xfer->recv.payload = mtod(m, uint32_t *);
    963 	xfer->recv.pay_len = MCLBYTES;
    964 	xfer->mbuf = m;
    965 	STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link);
    966 }
    967 
    968 static void
    969 fwip_unicast_input(struct fw_xfer *xfer)
    970 {
    971 	uint64_t address;
    972 	struct mbuf *m;
    973 	struct m_tag *mtag;
    974 	struct ifnet *ifp;
    975 	struct fwip_softc *fwip;
    976 	struct fw_pkt *fp;
    977 	//struct fw_pkt *sfp;
    978 	int rtcode;
    979 
    980 	GIANT_REQUIRED;
    981 
    982 	fwip = (struct fwip_softc *)xfer->sc;
    983 	ifp = &fwip->fwip_if;
    984 	m = xfer->mbuf;
    985 	xfer->mbuf = 0;
    986 	fp = &xfer->recv.hdr;
    987 
    988 	/*
    989 	 * Check the fifo address - we only accept addresses of
    990 	 * exactly INET_FIFO.
    991 	 */
    992 	address = ((uint64_t)fp->mode.wreqb.dest_hi << 32)
    993 		| fp->mode.wreqb.dest_lo;
    994 	if (fp->mode.wreqb.tcode != FWTCODE_WREQB) {
    995 		rtcode = FWRCODE_ER_TYPE;
    996 	} else if (address != INET_FIFO) {
    997 		rtcode = FWRCODE_ER_ADDR;
    998 	} else {
    999 		rtcode = FWRCODE_COMPLETE;
   1000 	}
   1001 
   1002 	/*
   1003 	 * Pick up a new mbuf and stick it on the back of the receive
   1004 	 * queue.
   1005 	 */
   1006 	fwip_unicast_input_recycle(fwip, xfer);
   1007 
   1008 	/*
   1009 	 * If we've already rejected the packet, give up now.
   1010 	 */
   1011 	if (rtcode != FWRCODE_COMPLETE) {
   1012 		m_freem(m);
   1013 		ifp->if_ierrors ++;
   1014 		return;
   1015 	}
   1016 
   1017 	if (ifp->if_bpf) {
   1018 		/*
   1019 		 * Record the sender ID for possible BPF usage.
   1020 		 */
   1021 		mtag = m_tag_alloc(MTAG_FIREWIRE, MTAG_FIREWIRE_SENDER_EUID,
   1022 		    2*sizeof(uint32_t), M_NOWAIT);
   1023 		if (mtag) {
   1024 			/* bpf wants it in network byte order */
   1025 			struct fw_device *fd;
   1026 			uint32_t *p = (uint32_t *) (mtag + 1);
   1027 			fd = fw_noderesolve_nodeid(fwip->fd.fc,
   1028 			    fp->mode.wreqb.src & 0x3f);
   1029 			if (fd) {
   1030 				p[0] = htonl(fd->eui.hi);
   1031 				p[1] = htonl(fd->eui.lo);
   1032 			} else {
   1033 				p[0] = 0;
   1034 				p[1] = 0;
   1035 			}
   1036 			m_tag_prepend(m, mtag);
   1037 		}
   1038 	}
   1039 
   1040 	/*
   1041 	 * Hand off to the generic encapsulation code. We don't use
   1042 	 * ifp->if_input so that we can pass the source nodeid as an
   1043 	 * argument to facilitate link-level fragment reassembly.
   1044 	 */
   1045 	m->m_len = m->m_pkthdr.len = fp->mode.wreqb.len;
   1046 	m->m_pkthdr.rcvif = ifp;
   1047 	FIREWIRE_INPUT(ifp, m, fp->mode.wreqb.src);
   1048 	ifp->if_ipackets ++;
   1049 }
   1050 
   1051 #if defined(__FreeBSD__)
   1052 static devclass_t fwip_devclass;
   1053 
   1054 static device_method_t fwip_methods[] = {
   1055 	/* device interface */
   1056 	DEVMETHOD(device_identify,	fwip_identify),
   1057 	DEVMETHOD(device_probe,		fwip_probe),
   1058 	DEVMETHOD(device_attach,	fwip_attach),
   1059 	DEVMETHOD(device_detach,	fwip_detach),
   1060 	{ 0, 0 }
   1061 };
   1062 
   1063 static driver_t fwip_driver = {
   1064         "fwip",
   1065 	fwip_methods,
   1066 	sizeof(struct fwip_softc),
   1067 };
   1068 
   1069 
   1070 #ifdef __DragonFly__
   1071 DECLARE_DUMMY_MODULE(fwip);
   1072 #endif
   1073 DRIVER_MODULE(fwip, firewire, fwip_driver, fwip_devclass, 0, 0);
   1074 MODULE_VERSION(fwip, 1);
   1075 MODULE_DEPEND(fwip, firewire, 1, 1, 1);
   1076 #elif defined(__NetBSD__)
   1077 CFATTACH_DECL(fwip, sizeof (struct fwip_softc),
   1078     fwipmatch, fwipattach, fwipdetach, NULL);
   1079 #endif
   1080