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