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