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