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