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