1 /* $OpenBSD: if_upl.c,v 1.14 2003/05/07 04:33:33 deraadt Exp $ */ 2 /* $NetBSD: if_upl.c,v 1.19 2002/07/11 21:14:26 augustss Exp $ */ 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Prolific PL2301/PL2302 driver 42 */ 43 44 #if defined(__NetBSD__) 45 #include "opt_inet.h" 46 #include "opt_ns.h" 47 #include "rnd.h" 48 #endif 49 50 #include "bpfilter.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #if defined(__NetBSD__) || defined(__FreeBSD__) 55 #include <sys/callout.h> 56 #else 57 #include <sys/timeout.h> 58 #endif 59 #include <sys/sockio.h> 60 #include <sys/mbuf.h> 61 #include <sys/malloc.h> 62 #include <sys/kernel.h> 63 #include <sys/socket.h> 64 65 #include <sys/device.h> 66 #if NRND > 0 67 #include <sys/rnd.h> 68 #endif 69 70 #include <net/if.h> 71 #include <net/if_types.h> 72 #include <net/if_dl.h> 73 #include <net/netisr.h> 74 75 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) 76 77 #if NBPFILTER > 0 78 #include <net/bpf.h> 79 #endif 80 81 #ifdef INET 82 #include <netinet/in.h> 83 #include <netinet/in_var.h> 84 #if defined(__NetBSD__) 85 #include <netinet/if_inarp.h> 86 #elif defined(__OpenBSD__) 87 #include <netinet/in_systm.h> 88 #include <netinet/ip.h> 89 #include <netinet/if_ether.h> 90 #endif 91 #else 92 #error upl without INET? 93 #endif 94 95 #ifdef NS 96 #include <netns/ns.h> 97 #include <netns/ns_if.h> 98 #endif 99 100 #include <dev/usb/usb.h> 101 #include <dev/usb/usbdi.h> 102 #include <dev/usb/usbdi_util.h> 103 #include <dev/usb/usbdevs.h> 104 105 /* 106 * 7 6 5 4 3 2 1 0 107 * tx rx 1 0 108 * 1110 0000 rxdata 109 * 1010 0000 idle 110 * 0010 0000 tx over 111 * 0110 tx over + rxd 112 */ 113 114 #define UPL_RXDATA 0x40 115 #define UPL_TXOK 0x80 116 117 #define UPL_INTR_PKTLEN 1 118 119 #define UPL_CONFIG_NO 1 120 #define UPL_IFACE_IDX 0 121 122 /***/ 123 124 #define UPL_INTR_INTERVAL 20 125 126 #define UPL_BUFSZ 1024 127 128 #define UPL_RX_FRAMES 1 129 #define UPL_TX_FRAMES 1 130 131 #define UPL_RX_LIST_CNT 1 132 #define UPL_TX_LIST_CNT 1 133 134 #define UPL_ENDPT_RX 0x0 135 #define UPL_ENDPT_TX 0x1 136 #define UPL_ENDPT_INTR 0x2 137 #define UPL_ENDPT_MAX 0x3 138 139 struct upl_type { 140 u_int16_t upl_vid; 141 u_int16_t upl_did; 142 }; 143 144 struct upl_softc; 145 146 struct upl_chain { 147 struct upl_softc *upl_sc; 148 usbd_xfer_handle upl_xfer; 149 char *upl_buf; 150 struct mbuf *upl_mbuf; 151 int upl_idx; 152 }; 153 154 struct upl_cdata { 155 struct upl_chain upl_tx_chain[UPL_TX_LIST_CNT]; 156 struct upl_chain upl_rx_chain[UPL_RX_LIST_CNT]; 157 int upl_tx_prod; 158 int upl_tx_cons; 159 int upl_tx_cnt; 160 int upl_rx_prod; 161 }; 162 163 struct upl_softc { 164 USBBASEDEVICE sc_dev; 165 166 struct ifnet sc_if; 167 #if NRND > 0 168 rndsource_element_t sc_rnd_source; 169 #endif 170 171 usb_callout_t sc_stat_ch; 172 173 usbd_device_handle sc_udev; 174 usbd_interface_handle sc_iface; 175 u_int16_t sc_vendor; 176 u_int16_t sc_product; 177 int sc_ed[UPL_ENDPT_MAX]; 178 usbd_pipe_handle sc_ep[UPL_ENDPT_MAX]; 179 struct upl_cdata sc_cdata; 180 181 uByte sc_ibuf; 182 183 char sc_dying; 184 char sc_attached; 185 u_int sc_rx_errs; 186 struct timeval sc_rx_notice; 187 u_int sc_intr_errs; 188 }; 189 190 #ifdef UPL_DEBUG 191 #define DPRINTF(x) if (upldebug) logprintf x 192 #define DPRINTFN(n,x) if (upldebug >= (n)) logprintf x 193 int upldebug = 0; 194 #else 195 #define DPRINTF(x) 196 #define DPRINTFN(n,x) 197 #endif 198 199 /* 200 * Various supported device vendors/products. 201 */ 202 Static struct upl_type sc_devs[] = { 203 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 }, 204 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 }, 205 { 0, 0 } 206 }; 207 208 USB_DECLARE_DRIVER(upl); 209 210 Static int upl_openpipes(struct upl_softc *); 211 Static int upl_tx_list_init(struct upl_softc *); 212 Static int upl_rx_list_init(struct upl_softc *); 213 Static int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *); 214 Static int upl_send(struct upl_softc *, struct mbuf *, int); 215 Static void upl_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); 216 Static void upl_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 217 Static void upl_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 218 Static void upl_start(struct ifnet *); 219 Static int upl_ioctl(struct ifnet *, u_long, caddr_t); 220 Static void upl_init(void *); 221 Static void upl_stop(struct upl_softc *); 222 Static void upl_watchdog(struct ifnet *); 223 224 Static int upl_output(struct ifnet *, struct mbuf *, struct sockaddr *, 225 struct rtentry *); 226 Static void upl_input(struct ifnet *, struct mbuf *); 227 228 /* 229 * Probe for a Prolific chip. 230 */ 231 USB_MATCH(upl) 232 { 233 USB_MATCH_START(upl, uaa); 234 struct upl_type *t; 235 236 if (uaa->iface != NULL) 237 return (UMATCH_NONE); 238 239 for (t = sc_devs; t->upl_vid != 0; t++) 240 if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did) 241 return (UMATCH_VENDOR_PRODUCT); 242 243 return (UMATCH_NONE); 244 } 245 246 USB_ATTACH(upl) 247 { 248 USB_ATTACH_START(upl, sc, uaa); 249 char devinfo[1024]; 250 int s; 251 usbd_device_handle dev = uaa->device; 252 usbd_interface_handle iface; 253 usbd_status err; 254 struct ifnet *ifp; 255 usb_interface_descriptor_t *id; 256 usb_endpoint_descriptor_t *ed; 257 int i; 258 259 DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev)); 260 261 usbd_devinfo(dev, 0, devinfo, sizeof devinfo); 262 USB_ATTACH_SETUP; 263 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); 264 265 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1); 266 if (err) { 267 printf("%s: setting config no failed\n", 268 USBDEVNAME(sc->sc_dev)); 269 USB_ATTACH_ERROR_RETURN; 270 } 271 272 sc->sc_udev = dev; 273 sc->sc_product = uaa->product; 274 sc->sc_vendor = uaa->vendor; 275 276 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); 277 if (err) { 278 printf("%s: getting interface handle failed\n", 279 USBDEVNAME(sc->sc_dev)); 280 USB_ATTACH_ERROR_RETURN; 281 } 282 283 sc->sc_iface = iface; 284 id = usbd_get_interface_descriptor(iface); 285 286 /* Find endpoints. */ 287 for (i = 0; i < id->bNumEndpoints; i++) { 288 ed = usbd_interface2endpoint_descriptor(iface, i); 289 if (ed == NULL) { 290 printf("%s: couldn't get ep %d\n", 291 USBDEVNAME(sc->sc_dev), i); 292 USB_ATTACH_ERROR_RETURN; 293 } 294 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 295 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 296 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress; 297 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 298 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 299 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress; 300 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 301 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 302 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress; 303 } 304 } 305 306 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 || 307 sc->sc_ed[UPL_ENDPT_INTR] == 0) { 308 printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev)); 309 USB_ATTACH_ERROR_RETURN; 310 } 311 312 s = splnet(); 313 314 /* Initialize interface info.*/ 315 ifp = &sc->sc_if; 316 ifp->if_softc = sc; 317 ifp->if_mtu = UPL_BUFSZ; 318 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX; 319 ifp->if_ioctl = upl_ioctl; 320 ifp->if_start = upl_start; 321 ifp->if_watchdog = upl_watchdog; 322 strncpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ); 323 324 ifp->if_type = IFT_OTHER; 325 ifp->if_addrlen = 0; 326 ifp->if_hdrlen = 0; 327 ifp->if_output = upl_output; 328 ifp->if_baudrate = 12000000; 329 #if defined(__NetBSD__) 330 ifp->if_input = upl_input; 331 ifp->if_dlt = DLT_RAW; 332 #endif 333 IFQ_SET_READY(&ifp->if_snd); 334 335 /* Attach the interface. */ 336 if_attach(ifp); 337 if_alloc_sadl(ifp); 338 339 #if defined(__NetBSD__) && NBPFILTER > 0 340 bpfattach(ifp, DLT_RAW, 0); 341 #endif 342 #if NRND > 0 343 rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev), 344 RND_TYPE_NET, 0); 345 #endif 346 347 sc->sc_attached = 1; 348 splx(s); 349 350 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 351 USBDEV(sc->sc_dev)); 352 353 USB_ATTACH_SUCCESS_RETURN; 354 } 355 356 USB_DETACH(upl) 357 { 358 USB_DETACH_START(upl, sc); 359 struct ifnet *ifp = &sc->sc_if; 360 int s; 361 362 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 363 364 s = splusb(); 365 366 if (!sc->sc_attached) { 367 /* Detached before attached finished, so just bail out. */ 368 splx(s); 369 return (0); 370 } 371 372 if (ifp->if_flags & IFF_RUNNING) 373 upl_stop(sc); 374 375 #if NRND > 0 376 rnd_detach_source(&sc->sc_rnd_source); 377 #endif 378 #if NBPFILTER > 0 379 bpfdetach(ifp); 380 #endif 381 382 if_detach(ifp); 383 384 #ifdef DIAGNOSTIC 385 if (sc->sc_ep[UPL_ENDPT_TX] != NULL || 386 sc->sc_ep[UPL_ENDPT_RX] != NULL || 387 sc->sc_ep[UPL_ENDPT_INTR] != NULL) 388 printf("%s: detach has active endpoints\n", 389 USBDEVNAME(sc->sc_dev)); 390 #endif 391 392 sc->sc_attached = 0; 393 splx(s); 394 395 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 396 USBDEV(sc->sc_dev)); 397 398 return (0); 399 } 400 401 int 402 upl_activate(device_ptr_t self, enum devact act) 403 { 404 struct upl_softc *sc = (struct upl_softc *)self; 405 406 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 407 408 switch (act) { 409 case DVACT_ACTIVATE: 410 return (EOPNOTSUPP); 411 break; 412 413 case DVACT_DEACTIVATE: 414 /* Deactivate the interface. */ 415 if_deactivate(&sc->sc_if); 416 sc->sc_dying = 1; 417 break; 418 } 419 return (0); 420 } 421 422 /* 423 * Initialize an RX descriptor and attach an MBUF cluster. 424 */ 425 Static int 426 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) 427 { 428 struct mbuf *m_new = NULL; 429 430 DPRINTFN(8,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 431 432 if (m == NULL) { 433 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 434 if (m_new == NULL) { 435 printf("%s: no memory for rx list " 436 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev)); 437 return (ENOBUFS); 438 } 439 440 MCLGET(m_new, M_DONTWAIT); 441 if (!(m_new->m_flags & M_EXT)) { 442 printf("%s: no memory for rx list " 443 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev)); 444 m_freem(m_new); 445 return (ENOBUFS); 446 } 447 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 448 } else { 449 m_new = m; 450 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 451 m_new->m_data = m_new->m_ext.ext_buf; 452 } 453 454 c->upl_mbuf = m_new; 455 456 return (0); 457 } 458 459 Static int 460 upl_rx_list_init(struct upl_softc *sc) 461 { 462 struct upl_cdata *cd; 463 struct upl_chain *c; 464 int i; 465 466 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 467 468 cd = &sc->sc_cdata; 469 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 470 c = &cd->upl_rx_chain[i]; 471 c->upl_sc = sc; 472 c->upl_idx = i; 473 if (upl_newbuf(sc, c, NULL) == ENOBUFS) 474 return (ENOBUFS); 475 if (c->upl_xfer == NULL) { 476 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); 477 if (c->upl_xfer == NULL) 478 return (ENOBUFS); 479 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); 480 if (c->upl_buf == NULL) { 481 usbd_free_xfer(c->upl_xfer); 482 return (ENOBUFS); 483 } 484 } 485 } 486 487 return (0); 488 } 489 490 Static int 491 upl_tx_list_init(struct upl_softc *sc) 492 { 493 struct upl_cdata *cd; 494 struct upl_chain *c; 495 int i; 496 497 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 498 499 cd = &sc->sc_cdata; 500 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 501 c = &cd->upl_tx_chain[i]; 502 c->upl_sc = sc; 503 c->upl_idx = i; 504 c->upl_mbuf = NULL; 505 if (c->upl_xfer == NULL) { 506 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); 507 if (c->upl_xfer == NULL) 508 return (ENOBUFS); 509 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); 510 if (c->upl_buf == NULL) { 511 usbd_free_xfer(c->upl_xfer); 512 return (ENOBUFS); 513 } 514 } 515 } 516 517 return (0); 518 } 519 520 /* 521 * A frame has been uploaded: pass the resulting mbuf chain up to 522 * the higher level protocols. 523 */ 524 Static void 525 upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 526 { 527 struct upl_chain *c = priv; 528 struct upl_softc *sc = c->upl_sc; 529 struct ifnet *ifp = &sc->sc_if; 530 struct mbuf *m; 531 int total_len = 0; 532 int s; 533 534 if (sc->sc_dying) 535 return; 536 537 if (!(ifp->if_flags & IFF_RUNNING)) 538 return; 539 540 if (status != USBD_NORMAL_COMPLETION) { 541 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 542 return; 543 sc->sc_rx_errs++; 544 if (usbd_ratecheck(&sc->sc_rx_notice)) { 545 printf("%s: %u usb errors on rx: %s\n", 546 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs, 547 usbd_errstr(status)); 548 sc->sc_rx_errs = 0; 549 } 550 if (status == USBD_STALLED) 551 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]); 552 goto done; 553 } 554 555 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 556 557 DPRINTFN(9,("%s: %s: enter status=%d length=%d\n", 558 USBDEVNAME(sc->sc_dev), __func__, status, total_len)); 559 560 m = c->upl_mbuf; 561 memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len); 562 563 ifp->if_ipackets++; 564 m->m_pkthdr.len = m->m_len = total_len; 565 566 m->m_pkthdr.rcvif = ifp; 567 568 s = splnet(); 569 570 /* XXX ugly */ 571 if (upl_newbuf(sc, c, NULL) == ENOBUFS) { 572 ifp->if_ierrors++; 573 goto done1; 574 } 575 576 #if NBPFILTER > 0 577 /* 578 * Handle BPF listeners. Let the BPF user see the packet, but 579 * don't pass it up to the ether_input() layer unless it's 580 * a broadcast packet, multicast packet, matches our ethernet 581 * address or the interface is in promiscuous mode. 582 */ 583 if (ifp->if_bpf) { 584 BPF_MTAP(ifp, m); 585 } 586 #endif 587 588 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev), 589 __func__, m->m_len)); 590 591 #if defined(__NetBSD__) || defined(__OpenBSD__) 592 IF_INPUT(ifp, m); 593 #else 594 upl_input(ifp, m); 595 #endif 596 597 done1: 598 splx(s); 599 600 done: 601 #if 1 602 /* Setup new transfer. */ 603 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 604 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 605 USBD_NO_TIMEOUT, upl_rxeof); 606 usbd_transfer(c->upl_xfer); 607 608 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), 609 __func__)); 610 #endif 611 } 612 613 /* 614 * A frame was downloaded to the chip. It's safe for us to clean up 615 * the list buffers. 616 */ 617 Static void 618 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 619 { 620 struct upl_chain *c = priv; 621 struct upl_softc *sc = c->upl_sc; 622 struct ifnet *ifp = &sc->sc_if; 623 int s; 624 625 if (sc->sc_dying) 626 return; 627 628 s = splnet(); 629 630 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->sc_dev), 631 __func__, status)); 632 633 ifp->if_timer = 0; 634 ifp->if_flags &= ~IFF_OACTIVE; 635 636 if (status != USBD_NORMAL_COMPLETION) { 637 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 638 splx(s); 639 return; 640 } 641 ifp->if_oerrors++; 642 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev), 643 usbd_errstr(status)); 644 if (status == USBD_STALLED) 645 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_TX]); 646 splx(s); 647 return; 648 } 649 650 ifp->if_opackets++; 651 652 m_freem(c->upl_mbuf); 653 c->upl_mbuf = NULL; 654 655 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 656 upl_start(ifp); 657 658 splx(s); 659 } 660 661 Static int 662 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 663 { 664 int total_len; 665 struct upl_chain *c; 666 usbd_status err; 667 668 c = &sc->sc_cdata.upl_tx_chain[idx]; 669 670 /* 671 * Copy the mbuf data into a contiguous buffer, leaving two 672 * bytes at the beginning to hold the frame length. 673 */ 674 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 675 c->upl_mbuf = m; 676 677 total_len = m->m_pkthdr.len; 678 679 DPRINTFN(10,("%s: %s: total_len=%d\n", 680 USBDEVNAME(sc->sc_dev), __func__, total_len)); 681 682 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX], 683 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, 684 upl_txeof); 685 686 /* Transmit */ 687 err = usbd_transfer(c->upl_xfer); 688 if (err != USBD_IN_PROGRESS) { 689 printf("%s: upl_send error=%s\n", USBDEVNAME(sc->sc_dev), 690 usbd_errstr(err)); 691 upl_stop(sc); 692 return (EIO); 693 } 694 695 sc->sc_cdata.upl_tx_cnt++; 696 697 return (0); 698 } 699 700 Static void 701 upl_start(struct ifnet *ifp) 702 { 703 struct upl_softc *sc = ifp->if_softc; 704 struct mbuf *m_head = NULL; 705 706 if (sc->sc_dying) 707 return; 708 709 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 710 711 if (ifp->if_flags & IFF_OACTIVE) 712 return; 713 714 IFQ_POLL(&ifp->if_snd, m_head); 715 if (m_head == NULL) 716 return; 717 718 if (upl_send(sc, m_head, 0)) { 719 ifp->if_flags |= IFF_OACTIVE; 720 return; 721 } 722 723 IFQ_DEQUEUE(&ifp->if_snd, m_head); 724 725 #if NBPFILTER > 0 726 /* 727 * If there's a BPF listener, bounce a copy of this frame 728 * to him. 729 */ 730 if (ifp->if_bpf) 731 BPF_MTAP(ifp, m_head); 732 #endif 733 734 ifp->if_flags |= IFF_OACTIVE; 735 736 /* 737 * Set a timeout in case the chip goes out to lunch. 738 */ 739 ifp->if_timer = 5; 740 } 741 742 Static void 743 upl_init(void *xsc) 744 { 745 struct upl_softc *sc = xsc; 746 struct ifnet *ifp = &sc->sc_if; 747 int s; 748 749 if (sc->sc_dying) 750 return; 751 752 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 753 754 if (ifp->if_flags & IFF_RUNNING) 755 return; 756 757 s = splnet(); 758 759 /* Init TX ring. */ 760 if (upl_tx_list_init(sc) == ENOBUFS) { 761 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev)); 762 splx(s); 763 return; 764 } 765 766 /* Init RX ring. */ 767 if (upl_rx_list_init(sc) == ENOBUFS) { 768 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev)); 769 splx(s); 770 return; 771 } 772 773 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 774 if (upl_openpipes(sc)) { 775 splx(s); 776 return; 777 } 778 } 779 780 ifp->if_flags |= IFF_RUNNING; 781 ifp->if_flags &= ~IFF_OACTIVE; 782 783 splx(s); 784 } 785 786 Static int 787 upl_openpipes(struct upl_softc *sc) 788 { 789 struct upl_chain *c; 790 usbd_status err; 791 int i; 792 793 /* Open RX and TX pipes. */ 794 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 795 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 796 if (err) { 797 printf("%s: open rx pipe failed: %s\n", 798 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 799 return (EIO); 800 } 801 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 802 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 803 if (err) { 804 printf("%s: open tx pipe failed: %s\n", 805 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 806 return (EIO); 807 } 808 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 809 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 810 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 811 UPL_INTR_INTERVAL); 812 if (err) { 813 printf("%s: open intr pipe failed: %s\n", 814 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 815 return (EIO); 816 } 817 818 819 #if 1 820 /* Start up the receive pipe. */ 821 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 822 c = &sc->sc_cdata.upl_rx_chain[i]; 823 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 824 c, c->upl_buf, UPL_BUFSZ, 825 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 826 upl_rxeof); 827 usbd_transfer(c->upl_xfer); 828 } 829 #endif 830 831 return (0); 832 } 833 834 Static void 835 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 836 { 837 struct upl_softc *sc = priv; 838 struct ifnet *ifp = &sc->sc_if; 839 uByte stat; 840 841 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 842 843 if (sc->sc_dying) 844 return; 845 846 if (!(ifp->if_flags & IFF_RUNNING)) 847 return; 848 849 if (status != USBD_NORMAL_COMPLETION) { 850 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 851 return; 852 } 853 sc->sc_intr_errs++; 854 if (usbd_ratecheck(&sc->sc_rx_notice)) { 855 printf("%s: %u usb errors on intr: %s\n", 856 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs, 857 usbd_errstr(status)); 858 sc->sc_intr_errs = 0; 859 } 860 if (status == USBD_STALLED) 861 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]); 862 return; 863 } 864 865 stat = sc->sc_ibuf; 866 867 if (stat == 0) 868 return; 869 870 DPRINTFN(10,("%s: %s: stat=0x%02x\n", USBDEVNAME(sc->sc_dev), 871 __func__, stat)); 872 873 } 874 875 Static int 876 upl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 877 { 878 struct upl_softc *sc = ifp->if_softc; 879 struct ifaddr *ifa = (struct ifaddr *)data; 880 struct ifreq *ifr = (struct ifreq *)data; 881 int s, error = 0; 882 883 if (sc->sc_dying) 884 return (EIO); 885 886 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 887 USBDEVNAME(sc->sc_dev), __func__, command)); 888 889 s = splnet(); 890 891 switch(command) { 892 case SIOCSIFADDR: 893 ifp->if_flags |= IFF_UP; 894 upl_init(sc); 895 896 switch (ifa->ifa_addr->sa_family) { 897 #ifdef INET 898 case AF_INET: 899 break; 900 #endif /* INET */ 901 #ifdef NS 902 case AF_NS: 903 { 904 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 905 906 if (ns_nullhost(*ina)) 907 ina->x_host = *(union ns_host *) 908 LLADDR(ifp->if_sadl); 909 else 910 memcpy(LLADDR(ifp->if_sadl), 911 ina->x_host.c_host, 912 ifp->if_addrlen); 913 break; 914 } 915 #endif /* NS */ 916 } 917 break; 918 919 case SIOCSIFMTU: 920 if (ifr->ifr_mtu > UPL_BUFSZ) 921 error = EINVAL; 922 else 923 ifp->if_mtu = ifr->ifr_mtu; 924 break; 925 926 case SIOCSIFFLAGS: 927 if (ifp->if_flags & IFF_UP) { 928 if (!(ifp->if_flags & IFF_RUNNING)) 929 upl_init(sc); 930 } else { 931 if (ifp->if_flags & IFF_RUNNING) 932 upl_stop(sc); 933 } 934 error = 0; 935 break; 936 default: 937 error = EINVAL; 938 break; 939 } 940 941 splx(s); 942 943 return (error); 944 } 945 946 Static void 947 upl_watchdog(struct ifnet *ifp) 948 { 949 struct upl_softc *sc = ifp->if_softc; 950 951 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 952 953 if (sc->sc_dying) 954 return; 955 956 ifp->if_oerrors++; 957 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev)); 958 959 upl_stop(sc); 960 upl_init(sc); 961 962 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 963 upl_start(ifp); 964 } 965 966 /* 967 * Stop the adapter and free any mbufs allocated to the 968 * RX and TX lists. 969 */ 970 Static void 971 upl_stop(struct upl_softc *sc) 972 { 973 usbd_status err; 974 struct ifnet *ifp; 975 int i; 976 977 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 978 979 ifp = &sc->sc_if; 980 ifp->if_timer = 0; 981 982 /* Stop transfers. */ 983 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 984 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 985 if (err) { 986 printf("%s: abort rx pipe failed: %s\n", 987 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 988 } 989 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 990 if (err) { 991 printf("%s: close rx pipe failed: %s\n", 992 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 993 } 994 sc->sc_ep[UPL_ENDPT_RX] = NULL; 995 } 996 997 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 998 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 999 if (err) { 1000 printf("%s: abort tx pipe failed: %s\n", 1001 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1002 } 1003 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 1004 if (err) { 1005 printf("%s: close tx pipe failed: %s\n", 1006 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1007 } 1008 sc->sc_ep[UPL_ENDPT_TX] = NULL; 1009 } 1010 1011 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 1012 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 1013 if (err) { 1014 printf("%s: abort intr pipe failed: %s\n", 1015 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1016 } 1017 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 1018 if (err) { 1019 printf("%s: close intr pipe failed: %s\n", 1020 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1021 } 1022 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 1023 } 1024 1025 /* Free RX resources. */ 1026 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 1027 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 1028 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 1029 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 1030 } 1031 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) { 1032 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer); 1033 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL; 1034 } 1035 } 1036 1037 /* Free TX resources. */ 1038 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 1039 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 1040 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 1041 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 1042 } 1043 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 1044 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 1045 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 1046 } 1047 } 1048 1049 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1050 } 1051 1052 Static int 1053 upl_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 1054 struct rtentry *rt0) 1055 { 1056 int s, len, error; 1057 1058 DPRINTFN(10,("%s: %s: enter\n", 1059 USBDEVNAME(((struct upl_softc *)ifp->if_softc)->sc_dev), 1060 __func__)); 1061 1062 len = m->m_pkthdr.len; 1063 s = splnet(); 1064 /* 1065 * Queue message on interface, and start output if interface 1066 * not yet active. 1067 */ 1068 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); 1069 if (error) { 1070 /* mbuf is already freed */ 1071 splx(s); 1072 return (error); 1073 } 1074 ifp->if_obytes += len; 1075 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1076 (*ifp->if_start)(ifp); 1077 splx(s); 1078 1079 return (0); 1080 } 1081 1082 Static void 1083 upl_input(struct ifnet *ifp, struct mbuf *m) 1084 { 1085 struct ifqueue *inq; 1086 int s; 1087 1088 /* XXX Assume all traffic is IP */ 1089 1090 schednetisr(NETISR_IP); 1091 inq = &ipintrq; 1092 1093 s = splnet(); 1094 if (IF_QFULL(inq)) { 1095 IF_DROP(inq); 1096 splx(s); 1097 #if 0 1098 if (sc->sc_flags & SC_DEBUG) 1099 printf("%s: input queue full\n", ifp->if_xname); 1100 #endif 1101 ifp->if_iqdrops++; 1102 return; 1103 } 1104 IF_ENQUEUE(inq, m); 1105 splx(s); 1106 ifp->if_ipackets++; 1107 ifp->if_ibytes += m->m_len; 1108 } 1109