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