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