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