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