1 /* $NetBSD: if_upl.c,v 1.38 2010/11/03 22:28:31 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.38 2010/11/03 22:28:31 dyoung 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 device_t sc_dev; 135 136 struct ifnet sc_if; 137 #if NRND > 0 138 rndsource_element_t sc_rnd_source; 139 #endif 140 141 struct callout 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) printf x 162 #define DPRINTFN(n,x) if (upldebug >= (n)) printf 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 int upl_match(device_t, cfdata_t, void *); 179 void upl_attach(device_t, device_t, void *); 180 int upl_detach(device_t, int); 181 int upl_activate(device_t, enum devact); 182 extern struct cfdriver upl_cd; 183 CFATTACH_DECL_NEW(upl, sizeof(struct upl_softc), upl_match, upl_attach, upl_detach, upl_activate); 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 int 207 upl_match(device_t parent, cfdata_t match, void *aux) 208 { 209 struct usb_attach_arg *uaa = aux; 210 struct upl_type *t; 211 212 for (t = sc_devs; t->upl_vid != 0; t++) 213 if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did) 214 return (UMATCH_VENDOR_PRODUCT); 215 216 return (UMATCH_NONE); 217 } 218 219 void 220 upl_attach(device_t parent, device_t self, void *aux) 221 { 222 struct upl_softc *sc = device_private(self); 223 struct usb_attach_arg *uaa = aux; 224 char *devinfop; 225 int s; 226 usbd_device_handle dev = uaa->device; 227 usbd_interface_handle iface; 228 usbd_status err; 229 struct ifnet *ifp; 230 usb_interface_descriptor_t *id; 231 usb_endpoint_descriptor_t *ed; 232 int i; 233 234 DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev)); 235 236 sc->sc_dev = self; 237 238 aprint_naive("\n"); 239 aprint_normal("\n"); 240 241 devinfop = usbd_devinfo_alloc(dev, 0); 242 aprint_normal_dev(self, "%s\n", devinfop); 243 usbd_devinfo_free(devinfop); 244 245 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1); 246 if (err) { 247 aprint_error_dev(self, "setting config no failed\n"); 248 return; 249 } 250 251 sc->sc_udev = dev; 252 sc->sc_product = uaa->product; 253 sc->sc_vendor = uaa->vendor; 254 255 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); 256 if (err) { 257 aprint_error_dev(self, "getting interface handle failed\n"); 258 return; 259 } 260 261 sc->sc_iface = iface; 262 id = usbd_get_interface_descriptor(iface); 263 264 /* Find endpoints. */ 265 for (i = 0; i < id->bNumEndpoints; i++) { 266 ed = usbd_interface2endpoint_descriptor(iface, i); 267 if (ed == NULL) { 268 aprint_error_dev(self, "couldn't get ep %d\n", i); 269 return; 270 } 271 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 272 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 273 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress; 274 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 275 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 276 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress; 277 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 278 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 279 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress; 280 } 281 } 282 283 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 || 284 sc->sc_ed[UPL_ENDPT_INTR] == 0) { 285 aprint_error_dev(self, "missing endpoint\n"); 286 return; 287 } 288 289 s = splnet(); 290 291 /* Initialize interface info.*/ 292 ifp = &sc->sc_if; 293 ifp->if_softc = sc; 294 ifp->if_mtu = UPL_BUFSZ; 295 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX; 296 ifp->if_ioctl = upl_ioctl; 297 ifp->if_start = upl_start; 298 ifp->if_watchdog = upl_watchdog; 299 strncpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 300 301 ifp->if_type = IFT_OTHER; 302 ifp->if_addrlen = 0; 303 ifp->if_hdrlen = 0; 304 ifp->if_output = upl_output; 305 ifp->if_input = upl_input; 306 ifp->if_baudrate = 12000000; 307 ifp->if_dlt = DLT_RAW; 308 IFQ_SET_READY(&ifp->if_snd); 309 310 /* Attach the interface. */ 311 if_attach(ifp); 312 if_alloc_sadl(ifp); 313 314 bpf_attach(ifp, DLT_RAW, 0); 315 #if NRND > 0 316 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 317 RND_TYPE_NET, 0); 318 #endif 319 320 sc->sc_attached = 1; 321 splx(s); 322 323 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 324 sc->sc_dev); 325 326 return; 327 } 328 329 int 330 upl_detach(device_t self, int flags) 331 { 332 struct upl_softc *sc = device_private(self); 333 struct ifnet *ifp = &sc->sc_if; 334 int s; 335 336 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 337 338 s = splusb(); 339 340 if (!sc->sc_attached) { 341 /* Detached before attached finished, so just bail out. */ 342 splx(s); 343 return (0); 344 } 345 346 if (ifp->if_flags & IFF_RUNNING) 347 upl_stop(sc); 348 349 #if NRND > 0 350 rnd_detach_source(&sc->sc_rnd_source); 351 #endif 352 bpf_detach(ifp); 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 sc->sc_dev); 368 369 return (0); 370 } 371 372 int 373 upl_activate(device_t self, enum devact act) 374 { 375 struct upl_softc *sc = device_private(self); 376 377 DPRINTFN(2,("%s: %s: enter\n", device_xname(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", device_xname(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", device_xname(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", device_xname(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", device_xname(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", device_xname(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 device_xname(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 device_xname(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 /* 545 * Handle BPF listeners. Let the BPF user see the packet, but 546 * don't pass it up to the ether_input() layer unless it's 547 * a broadcast packet, multicast packet, matches our ethernet 548 * address or the interface is in promiscuous mode. 549 */ 550 bpf_mtap(ifp, m); 551 552 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev), 553 __func__, m->m_len)); 554 555 (*(ifp)->if_input)((ifp), (m)); 556 557 done1: 558 splx(s); 559 560 done: 561 #if 1 562 /* Setup new transfer. */ 563 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 564 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 565 USBD_NO_TIMEOUT, upl_rxeof); 566 usbd_transfer(c->upl_xfer); 567 568 DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), 569 __func__)); 570 #endif 571 } 572 573 /* 574 * A frame was downloaded to the chip. It's safe for us to clean up 575 * the list buffers. 576 */ 577 Static void 578 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 579 usbd_status status) 580 { 581 struct upl_chain *c = priv; 582 struct upl_softc *sc = c->upl_sc; 583 struct ifnet *ifp = &sc->sc_if; 584 int s; 585 586 if (sc->sc_dying) 587 return; 588 589 s = splnet(); 590 591 DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev), 592 __func__, status)); 593 594 ifp->if_timer = 0; 595 ifp->if_flags &= ~IFF_OACTIVE; 596 597 if (status != USBD_NORMAL_COMPLETION) { 598 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 599 splx(s); 600 return; 601 } 602 ifp->if_oerrors++; 603 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev), 604 usbd_errstr(status)); 605 if (status == USBD_STALLED) 606 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]); 607 splx(s); 608 return; 609 } 610 611 ifp->if_opackets++; 612 613 m_freem(c->upl_mbuf); 614 c->upl_mbuf = NULL; 615 616 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 617 upl_start(ifp); 618 619 splx(s); 620 } 621 622 Static int 623 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 624 { 625 int total_len; 626 struct upl_chain *c; 627 usbd_status err; 628 629 c = &sc->sc_cdata.upl_tx_chain[idx]; 630 631 /* 632 * Copy the mbuf data into a contiguous buffer, leaving two 633 * bytes at the beginning to hold the frame length. 634 */ 635 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 636 c->upl_mbuf = m; 637 638 total_len = m->m_pkthdr.len; 639 640 DPRINTFN(10,("%s: %s: total_len=%d\n", 641 device_xname(sc->sc_dev), __func__, total_len)); 642 643 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX], 644 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, 645 upl_txeof); 646 647 /* Transmit */ 648 err = usbd_transfer(c->upl_xfer); 649 if (err != USBD_IN_PROGRESS) { 650 printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), 651 usbd_errstr(err)); 652 upl_stop(sc); 653 return (EIO); 654 } 655 656 sc->sc_cdata.upl_tx_cnt++; 657 658 return (0); 659 } 660 661 Static void 662 upl_start(struct ifnet *ifp) 663 { 664 struct upl_softc *sc = ifp->if_softc; 665 struct mbuf *m_head = NULL; 666 667 if (sc->sc_dying) 668 return; 669 670 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 671 672 if (ifp->if_flags & IFF_OACTIVE) 673 return; 674 675 IFQ_POLL(&ifp->if_snd, m_head); 676 if (m_head == NULL) 677 return; 678 679 if (upl_send(sc, m_head, 0)) { 680 ifp->if_flags |= IFF_OACTIVE; 681 return; 682 } 683 684 IFQ_DEQUEUE(&ifp->if_snd, m_head); 685 686 /* 687 * If there's a BPF listener, bounce a copy of this frame 688 * to him. 689 */ 690 bpf_mtap(ifp, m_head); 691 692 ifp->if_flags |= IFF_OACTIVE; 693 694 /* 695 * Set a timeout in case the chip goes out to lunch. 696 */ 697 ifp->if_timer = 5; 698 } 699 700 Static void 701 upl_init(void *xsc) 702 { 703 struct upl_softc *sc = xsc; 704 struct ifnet *ifp = &sc->sc_if; 705 int s; 706 707 if (sc->sc_dying) 708 return; 709 710 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 711 712 if (ifp->if_flags & IFF_RUNNING) 713 return; 714 715 s = splnet(); 716 717 /* Init TX ring. */ 718 if (upl_tx_list_init(sc) == ENOBUFS) { 719 printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); 720 splx(s); 721 return; 722 } 723 724 /* Init RX ring. */ 725 if (upl_rx_list_init(sc) == ENOBUFS) { 726 printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); 727 splx(s); 728 return; 729 } 730 731 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 732 if (upl_openpipes(sc)) { 733 splx(s); 734 return; 735 } 736 } 737 738 ifp->if_flags |= IFF_RUNNING; 739 ifp->if_flags &= ~IFF_OACTIVE; 740 741 splx(s); 742 } 743 744 Static int 745 upl_openpipes(struct upl_softc *sc) 746 { 747 struct upl_chain *c; 748 usbd_status err; 749 int i; 750 751 /* Open RX and TX pipes. */ 752 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 753 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 754 if (err) { 755 printf("%s: open rx pipe failed: %s\n", 756 device_xname(sc->sc_dev), usbd_errstr(err)); 757 return (EIO); 758 } 759 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 760 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 761 if (err) { 762 printf("%s: open tx pipe failed: %s\n", 763 device_xname(sc->sc_dev), usbd_errstr(err)); 764 return (EIO); 765 } 766 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 767 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 768 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 769 UPL_INTR_INTERVAL); 770 if (err) { 771 printf("%s: open intr pipe failed: %s\n", 772 device_xname(sc->sc_dev), usbd_errstr(err)); 773 return (EIO); 774 } 775 776 777 #if 1 778 /* Start up the receive pipe. */ 779 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 780 c = &sc->sc_cdata.upl_rx_chain[i]; 781 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 782 c, c->upl_buf, UPL_BUFSZ, 783 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 784 upl_rxeof); 785 usbd_transfer(c->upl_xfer); 786 } 787 #endif 788 789 return (0); 790 } 791 792 Static void 793 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 794 usbd_status status) 795 { 796 struct upl_softc *sc = priv; 797 struct ifnet *ifp = &sc->sc_if; 798 uByte stat; 799 800 DPRINTFN(15,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 801 802 if (sc->sc_dying) 803 return; 804 805 if (!(ifp->if_flags & IFF_RUNNING)) 806 return; 807 808 if (status != USBD_NORMAL_COMPLETION) { 809 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 810 return; 811 } 812 sc->sc_intr_errs++; 813 if (usbd_ratecheck(&sc->sc_rx_notice)) { 814 printf("%s: %u usb errors on intr: %s\n", 815 device_xname(sc->sc_dev), sc->sc_rx_errs, 816 usbd_errstr(status)); 817 sc->sc_intr_errs = 0; 818 } 819 if (status == USBD_STALLED) 820 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 821 return; 822 } 823 824 stat = sc->sc_ibuf; 825 826 if (stat == 0) 827 return; 828 829 DPRINTFN(10,("%s: %s: stat=0x%02x\n", device_xname(sc->sc_dev), 830 __func__, stat)); 831 832 } 833 834 Static int 835 upl_ioctl(struct ifnet *ifp, u_long command, void *data) 836 { 837 struct upl_softc *sc = ifp->if_softc; 838 struct ifaddr *ifa = (struct ifaddr *)data; 839 struct ifreq *ifr = (struct ifreq *)data; 840 int s, error = 0; 841 842 if (sc->sc_dying) 843 return (EIO); 844 845 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 846 device_xname(sc->sc_dev), __func__, command)); 847 848 s = splnet(); 849 850 switch(command) { 851 case SIOCINITIFADDR: 852 ifp->if_flags |= IFF_UP; 853 upl_init(sc); 854 855 switch (ifa->ifa_addr->sa_family) { 856 #ifdef INET 857 case AF_INET: 858 break; 859 #endif /* INET */ 860 } 861 break; 862 863 case SIOCSIFMTU: 864 if (ifr->ifr_mtu > UPL_BUFSZ) 865 error = EINVAL; 866 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 867 error = 0; 868 break; 869 870 case SIOCSIFFLAGS: 871 if ((error = ifioctl_common(ifp, command, data)) != 0) 872 break; 873 /* XXX re-use ether_ioctl() */ 874 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 875 case IFF_UP: 876 upl_init(sc); 877 break; 878 case IFF_RUNNING: 879 upl_stop(sc); 880 break; 881 default: 882 break; 883 } 884 break; 885 default: 886 error = ifioctl_common(ifp, command, data); 887 break; 888 } 889 890 splx(s); 891 892 return (error); 893 } 894 895 Static void 896 upl_watchdog(struct ifnet *ifp) 897 { 898 struct upl_softc *sc = ifp->if_softc; 899 900 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 901 902 if (sc->sc_dying) 903 return; 904 905 ifp->if_oerrors++; 906 printf("%s: watchdog timeout\n", device_xname(sc->sc_dev)); 907 908 upl_stop(sc); 909 upl_init(sc); 910 911 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 912 upl_start(ifp); 913 } 914 915 /* 916 * Stop the adapter and free any mbufs allocated to the 917 * RX and TX lists. 918 */ 919 Static void 920 upl_stop(struct upl_softc *sc) 921 { 922 usbd_status err; 923 struct ifnet *ifp; 924 int i; 925 926 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 927 928 ifp = &sc->sc_if; 929 ifp->if_timer = 0; 930 931 /* Stop transfers. */ 932 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 933 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 934 if (err) { 935 printf("%s: abort rx pipe failed: %s\n", 936 device_xname(sc->sc_dev), usbd_errstr(err)); 937 } 938 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 939 if (err) { 940 printf("%s: close rx pipe failed: %s\n", 941 device_xname(sc->sc_dev), usbd_errstr(err)); 942 } 943 sc->sc_ep[UPL_ENDPT_RX] = NULL; 944 } 945 946 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 947 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 948 if (err) { 949 printf("%s: abort tx pipe failed: %s\n", 950 device_xname(sc->sc_dev), usbd_errstr(err)); 951 } 952 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 953 if (err) { 954 printf("%s: close tx pipe failed: %s\n", 955 device_xname(sc->sc_dev), usbd_errstr(err)); 956 } 957 sc->sc_ep[UPL_ENDPT_TX] = NULL; 958 } 959 960 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 961 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 962 if (err) { 963 printf("%s: abort intr pipe failed: %s\n", 964 device_xname(sc->sc_dev), usbd_errstr(err)); 965 } 966 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 967 if (err) { 968 printf("%s: close intr pipe failed: %s\n", 969 device_xname(sc->sc_dev), usbd_errstr(err)); 970 } 971 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 972 } 973 974 /* Free RX resources. */ 975 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 976 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 977 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 978 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 979 } 980 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) { 981 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer); 982 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL; 983 } 984 } 985 986 /* Free TX resources. */ 987 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 988 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 989 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 990 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 991 } 992 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 993 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 994 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 995 } 996 } 997 998 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 999 } 1000 1001 Static int 1002 upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 1003 struct rtentry *rt0) 1004 { 1005 int s, len, error; 1006 ALTQ_DECL(struct altq_pktattr pktattr;) 1007 1008 DPRINTFN(10,("%s: %s: enter\n", 1009 device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev), 1010 __func__)); 1011 1012 /* 1013 * if the queueing discipline needs packet classification, 1014 * do it now. 1015 */ 1016 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); 1017 1018 len = m->m_pkthdr.len; 1019 s = splnet(); 1020 /* 1021 * Queue message on interface, and start output if interface 1022 * not yet active. 1023 */ 1024 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); 1025 if (error) { 1026 /* mbuf is already freed */ 1027 splx(s); 1028 return (error); 1029 } 1030 ifp->if_obytes += len; 1031 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1032 (*ifp->if_start)(ifp); 1033 splx(s); 1034 1035 return (0); 1036 } 1037 1038 Static void 1039 upl_input(struct ifnet *ifp, struct mbuf *m) 1040 { 1041 #ifdef INET 1042 struct ifqueue *inq; 1043 int s; 1044 1045 /* XXX Assume all traffic is IP */ 1046 1047 schednetisr(NETISR_IP); 1048 inq = &ipintrq; 1049 1050 s = splnet(); 1051 if (IF_QFULL(inq)) { 1052 IF_DROP(inq); 1053 splx(s); 1054 #if 0 1055 if (sc->sc_flags & SC_DEBUG) 1056 printf("%s: input queue full\n", ifp->if_xname); 1057 #endif 1058 ifp->if_iqdrops++; 1059 return; 1060 } 1061 IF_ENQUEUE(inq, m); 1062 splx(s); 1063 #endif 1064 ifp->if_ipackets++; 1065 ifp->if_ibytes += m->m_len; 1066 } 1067