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