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