1 /* $NetBSD: if_upl.c,v 1.42 2012/02/02 19:43:07 tls 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.42 2012/02/02 19:43:07 tls Exp $"); 38 39 #include "opt_inet.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/callout.h> 44 #include <sys/sockio.h> 45 #include <sys/mbuf.h> 46 #include <sys/malloc.h> 47 #include <sys/kernel.h> 48 #include <sys/socket.h> 49 50 #include <sys/device.h> 51 #include <sys/rnd.h> 52 53 #include <net/if.h> 54 #include <net/if_types.h> 55 #include <net/if_dl.h> 56 #include <net/netisr.h> 57 58 #include <net/bpf.h> 59 60 #ifdef INET 61 #include <netinet/in.h> 62 #include <netinet/in_var.h> 63 #include <netinet/if_inarp.h> 64 #endif 65 66 67 #include <dev/usb/usb.h> 68 #include <dev/usb/usbdi.h> 69 #include <dev/usb/usbdi_util.h> 70 #include <dev/usb/usbdevs.h> 71 72 /* 73 * 7 6 5 4 3 2 1 0 74 * tx rx 1 0 75 * 1110 0000 rxdata 76 * 1010 0000 idle 77 * 0010 0000 tx over 78 * 0110 tx over + rxd 79 */ 80 81 #define UPL_RXDATA 0x40 82 #define UPL_TXOK 0x80 83 84 #define UPL_INTR_PKTLEN 1 85 86 #define UPL_CONFIG_NO 1 87 #define UPL_IFACE_IDX 0 88 89 /***/ 90 91 #define UPL_INTR_INTERVAL 20 92 93 #define UPL_BUFSZ 1024 94 95 #define UPL_RX_FRAMES 1 96 #define UPL_TX_FRAMES 1 97 98 #define UPL_RX_LIST_CNT 1 99 #define UPL_TX_LIST_CNT 1 100 101 #define UPL_ENDPT_RX 0x0 102 #define UPL_ENDPT_TX 0x1 103 #define UPL_ENDPT_INTR 0x2 104 #define UPL_ENDPT_MAX 0x3 105 106 struct upl_type { 107 u_int16_t upl_vid; 108 u_int16_t upl_did; 109 }; 110 111 struct upl_softc; 112 113 struct upl_chain { 114 struct upl_softc *upl_sc; 115 usbd_xfer_handle upl_xfer; 116 char *upl_buf; 117 struct mbuf *upl_mbuf; 118 int upl_idx; 119 }; 120 121 struct upl_cdata { 122 struct upl_chain upl_tx_chain[UPL_TX_LIST_CNT]; 123 struct upl_chain upl_rx_chain[UPL_RX_LIST_CNT]; 124 int upl_tx_prod; 125 int upl_tx_cons; 126 int upl_tx_cnt; 127 int upl_rx_prod; 128 }; 129 130 struct upl_softc { 131 device_t sc_dev; 132 133 struct ifnet sc_if; 134 krndsource_t sc_rnd_source; 135 136 struct callout sc_stat_ch; 137 138 usbd_device_handle sc_udev; 139 usbd_interface_handle sc_iface; 140 u_int16_t sc_vendor; 141 u_int16_t sc_product; 142 int sc_ed[UPL_ENDPT_MAX]; 143 usbd_pipe_handle sc_ep[UPL_ENDPT_MAX]; 144 struct upl_cdata sc_cdata; 145 146 uByte sc_ibuf; 147 148 char sc_dying; 149 char sc_attached; 150 u_int sc_rx_errs; 151 struct timeval sc_rx_notice; 152 u_int sc_intr_errs; 153 }; 154 155 #ifdef UPL_DEBUG 156 #define DPRINTF(x) if (upldebug) printf x 157 #define DPRINTFN(n,x) if (upldebug >= (n)) printf x 158 int upldebug = 0; 159 #else 160 #define DPRINTF(x) 161 #define DPRINTFN(n,x) 162 #endif 163 164 /* 165 * Various supported device vendors/products. 166 */ 167 Static struct upl_type sc_devs[] = { 168 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 }, 169 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 }, 170 { 0, 0 } 171 }; 172 173 int upl_match(device_t, cfdata_t, void *); 174 void upl_attach(device_t, device_t, void *); 175 int upl_detach(device_t, int); 176 int upl_activate(device_t, enum devact); 177 extern struct cfdriver upl_cd; 178 CFATTACH_DECL_NEW(upl, sizeof(struct upl_softc), upl_match, upl_attach, upl_detach, upl_activate); 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 int 202 upl_match(device_t parent, cfdata_t match, void *aux) 203 { 204 struct usb_attach_arg *uaa = aux; 205 struct upl_type *t; 206 207 for (t = sc_devs; t->upl_vid != 0; t++) 208 if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did) 209 return (UMATCH_VENDOR_PRODUCT); 210 211 return (UMATCH_NONE); 212 } 213 214 void 215 upl_attach(device_t parent, device_t self, void *aux) 216 { 217 struct upl_softc *sc = device_private(self); 218 struct usb_attach_arg *uaa = aux; 219 char *devinfop; 220 int s; 221 usbd_device_handle dev = uaa->device; 222 usbd_interface_handle iface; 223 usbd_status err; 224 struct ifnet *ifp; 225 usb_interface_descriptor_t *id; 226 usb_endpoint_descriptor_t *ed; 227 int i; 228 229 DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev)); 230 231 sc->sc_dev = self; 232 233 aprint_naive("\n"); 234 aprint_normal("\n"); 235 236 devinfop = usbd_devinfo_alloc(dev, 0); 237 aprint_normal_dev(self, "%s\n", devinfop); 238 usbd_devinfo_free(devinfop); 239 240 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1); 241 if (err) { 242 aprint_error_dev(self, "setting config no failed\n"); 243 return; 244 } 245 246 sc->sc_udev = dev; 247 sc->sc_product = uaa->product; 248 sc->sc_vendor = uaa->vendor; 249 250 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); 251 if (err) { 252 aprint_error_dev(self, "getting interface handle failed\n"); 253 return; 254 } 255 256 sc->sc_iface = iface; 257 id = usbd_get_interface_descriptor(iface); 258 259 /* Find endpoints. */ 260 for (i = 0; i < id->bNumEndpoints; i++) { 261 ed = usbd_interface2endpoint_descriptor(iface, i); 262 if (ed == NULL) { 263 aprint_error_dev(self, "couldn't get ep %d\n", i); 264 return; 265 } 266 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 267 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 268 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress; 269 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 270 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 271 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress; 272 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 273 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 274 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress; 275 } 276 } 277 278 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 || 279 sc->sc_ed[UPL_ENDPT_INTR] == 0) { 280 aprint_error_dev(self, "missing endpoint\n"); 281 return; 282 } 283 284 s = splnet(); 285 286 /* Initialize interface info.*/ 287 ifp = &sc->sc_if; 288 ifp->if_softc = sc; 289 ifp->if_mtu = UPL_BUFSZ; 290 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX; 291 ifp->if_ioctl = upl_ioctl; 292 ifp->if_start = upl_start; 293 ifp->if_watchdog = upl_watchdog; 294 strncpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 295 296 ifp->if_type = IFT_OTHER; 297 ifp->if_addrlen = 0; 298 ifp->if_hdrlen = 0; 299 ifp->if_output = upl_output; 300 ifp->if_input = upl_input; 301 ifp->if_baudrate = 12000000; 302 ifp->if_dlt = DLT_RAW; 303 IFQ_SET_READY(&ifp->if_snd); 304 305 /* Attach the interface. */ 306 if_attach(ifp); 307 if_alloc_sadl(ifp); 308 309 bpf_attach(ifp, DLT_RAW, 0); 310 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 311 RND_TYPE_NET, 0); 312 313 sc->sc_attached = 1; 314 splx(s); 315 316 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 317 sc->sc_dev); 318 319 return; 320 } 321 322 int 323 upl_detach(device_t self, int flags) 324 { 325 struct upl_softc *sc = device_private(self); 326 struct ifnet *ifp = &sc->sc_if; 327 int s; 328 329 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 330 331 s = splusb(); 332 333 if (!sc->sc_attached) { 334 /* Detached before attached finished, so just bail out. */ 335 splx(s); 336 return (0); 337 } 338 339 if (ifp->if_flags & IFF_RUNNING) 340 upl_stop(sc); 341 342 rnd_detach_source(&sc->sc_rnd_source); 343 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 sc->sc_dev); 359 360 return (0); 361 } 362 363 int 364 upl_activate(device_t self, enum devact act) 365 { 366 struct upl_softc *sc = device_private(self); 367 368 DPRINTFN(2,("%s: %s: enter\n", device_xname(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", device_xname(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", device_xname(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", device_xname(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", device_xname(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", device_xname(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 device_xname(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 device_xname(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 bpf_mtap(ifp, m); 542 543 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev), 544 __func__, m->m_len)); 545 546 (*(ifp)->if_input)((ifp), (m)); 547 548 done1: 549 splx(s); 550 551 done: 552 #if 1 553 /* Setup new transfer. */ 554 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 555 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 556 USBD_NO_TIMEOUT, upl_rxeof); 557 usbd_transfer(c->upl_xfer); 558 559 DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), 560 __func__)); 561 #endif 562 } 563 564 /* 565 * A frame was downloaded to the chip. It's safe for us to clean up 566 * the list buffers. 567 */ 568 Static void 569 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 570 usbd_status status) 571 { 572 struct upl_chain *c = priv; 573 struct upl_softc *sc = c->upl_sc; 574 struct ifnet *ifp = &sc->sc_if; 575 int s; 576 577 if (sc->sc_dying) 578 return; 579 580 s = splnet(); 581 582 DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev), 583 __func__, status)); 584 585 ifp->if_timer = 0; 586 ifp->if_flags &= ~IFF_OACTIVE; 587 588 if (status != USBD_NORMAL_COMPLETION) { 589 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 590 splx(s); 591 return; 592 } 593 ifp->if_oerrors++; 594 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev), 595 usbd_errstr(status)); 596 if (status == USBD_STALLED) 597 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]); 598 splx(s); 599 return; 600 } 601 602 ifp->if_opackets++; 603 604 m_freem(c->upl_mbuf); 605 c->upl_mbuf = NULL; 606 607 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 608 upl_start(ifp); 609 610 splx(s); 611 } 612 613 Static int 614 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 615 { 616 int total_len; 617 struct upl_chain *c; 618 usbd_status err; 619 620 c = &sc->sc_cdata.upl_tx_chain[idx]; 621 622 /* 623 * Copy the mbuf data into a contiguous buffer, leaving two 624 * bytes at the beginning to hold the frame length. 625 */ 626 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 627 c->upl_mbuf = m; 628 629 total_len = m->m_pkthdr.len; 630 631 DPRINTFN(10,("%s: %s: total_len=%d\n", 632 device_xname(sc->sc_dev), __func__, total_len)); 633 634 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX], 635 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, 636 upl_txeof); 637 638 /* Transmit */ 639 err = usbd_transfer(c->upl_xfer); 640 if (err != USBD_IN_PROGRESS) { 641 printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), 642 usbd_errstr(err)); 643 upl_stop(sc); 644 return (EIO); 645 } 646 647 sc->sc_cdata.upl_tx_cnt++; 648 649 return (0); 650 } 651 652 Static void 653 upl_start(struct ifnet *ifp) 654 { 655 struct upl_softc *sc = ifp->if_softc; 656 struct mbuf *m_head = NULL; 657 658 if (sc->sc_dying) 659 return; 660 661 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 662 663 if (ifp->if_flags & IFF_OACTIVE) 664 return; 665 666 IFQ_POLL(&ifp->if_snd, m_head); 667 if (m_head == NULL) 668 return; 669 670 if (upl_send(sc, m_head, 0)) { 671 ifp->if_flags |= IFF_OACTIVE; 672 return; 673 } 674 675 IFQ_DEQUEUE(&ifp->if_snd, m_head); 676 677 /* 678 * If there's a BPF listener, bounce a copy of this frame 679 * to him. 680 */ 681 bpf_mtap(ifp, m_head); 682 683 ifp->if_flags |= IFF_OACTIVE; 684 685 /* 686 * Set a timeout in case the chip goes out to lunch. 687 */ 688 ifp->if_timer = 5; 689 } 690 691 Static void 692 upl_init(void *xsc) 693 { 694 struct upl_softc *sc = xsc; 695 struct ifnet *ifp = &sc->sc_if; 696 int s; 697 698 if (sc->sc_dying) 699 return; 700 701 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 702 703 if (ifp->if_flags & IFF_RUNNING) 704 return; 705 706 s = splnet(); 707 708 /* Init TX ring. */ 709 if (upl_tx_list_init(sc) == ENOBUFS) { 710 printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); 711 splx(s); 712 return; 713 } 714 715 /* Init RX ring. */ 716 if (upl_rx_list_init(sc) == ENOBUFS) { 717 printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); 718 splx(s); 719 return; 720 } 721 722 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 723 if (upl_openpipes(sc)) { 724 splx(s); 725 return; 726 } 727 } 728 729 ifp->if_flags |= IFF_RUNNING; 730 ifp->if_flags &= ~IFF_OACTIVE; 731 732 splx(s); 733 } 734 735 Static int 736 upl_openpipes(struct upl_softc *sc) 737 { 738 struct upl_chain *c; 739 usbd_status err; 740 int i; 741 742 /* Open RX and TX pipes. */ 743 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 744 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 745 if (err) { 746 printf("%s: open rx pipe failed: %s\n", 747 device_xname(sc->sc_dev), usbd_errstr(err)); 748 return (EIO); 749 } 750 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 751 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 752 if (err) { 753 printf("%s: open tx pipe failed: %s\n", 754 device_xname(sc->sc_dev), usbd_errstr(err)); 755 return (EIO); 756 } 757 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 758 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 759 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 760 UPL_INTR_INTERVAL); 761 if (err) { 762 printf("%s: open intr pipe failed: %s\n", 763 device_xname(sc->sc_dev), usbd_errstr(err)); 764 return (EIO); 765 } 766 767 768 #if 1 769 /* Start up the receive pipe. */ 770 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 771 c = &sc->sc_cdata.upl_rx_chain[i]; 772 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 773 c, c->upl_buf, UPL_BUFSZ, 774 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 775 upl_rxeof); 776 usbd_transfer(c->upl_xfer); 777 } 778 #endif 779 780 return (0); 781 } 782 783 Static void 784 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 785 usbd_status status) 786 { 787 struct upl_softc *sc = priv; 788 struct ifnet *ifp = &sc->sc_if; 789 uByte stat; 790 791 DPRINTFN(15,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 792 793 if (sc->sc_dying) 794 return; 795 796 if (!(ifp->if_flags & IFF_RUNNING)) 797 return; 798 799 if (status != USBD_NORMAL_COMPLETION) { 800 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 801 return; 802 } 803 sc->sc_intr_errs++; 804 if (usbd_ratecheck(&sc->sc_rx_notice)) { 805 printf("%s: %u usb errors on intr: %s\n", 806 device_xname(sc->sc_dev), sc->sc_rx_errs, 807 usbd_errstr(status)); 808 sc->sc_intr_errs = 0; 809 } 810 if (status == USBD_STALLED) 811 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 812 return; 813 } 814 815 stat = sc->sc_ibuf; 816 817 if (stat == 0) 818 return; 819 820 DPRINTFN(10,("%s: %s: stat=0x%02x\n", device_xname(sc->sc_dev), 821 __func__, stat)); 822 823 } 824 825 Static int 826 upl_ioctl(struct ifnet *ifp, u_long command, void *data) 827 { 828 struct upl_softc *sc = ifp->if_softc; 829 struct ifaddr *ifa = (struct ifaddr *)data; 830 struct ifreq *ifr = (struct ifreq *)data; 831 int s, error = 0; 832 833 if (sc->sc_dying) 834 return (EIO); 835 836 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 837 device_xname(sc->sc_dev), __func__, command)); 838 839 s = splnet(); 840 841 switch(command) { 842 case SIOCINITIFADDR: 843 ifp->if_flags |= IFF_UP; 844 upl_init(sc); 845 846 switch (ifa->ifa_addr->sa_family) { 847 #ifdef INET 848 case AF_INET: 849 break; 850 #endif /* INET */ 851 } 852 break; 853 854 case SIOCSIFMTU: 855 if (ifr->ifr_mtu > UPL_BUFSZ) 856 error = EINVAL; 857 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 858 error = 0; 859 break; 860 861 case SIOCSIFFLAGS: 862 if ((error = ifioctl_common(ifp, command, data)) != 0) 863 break; 864 /* XXX re-use ether_ioctl() */ 865 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 866 case IFF_UP: 867 upl_init(sc); 868 break; 869 case IFF_RUNNING: 870 upl_stop(sc); 871 break; 872 default: 873 break; 874 } 875 break; 876 default: 877 error = ifioctl_common(ifp, command, data); 878 break; 879 } 880 881 splx(s); 882 883 return (error); 884 } 885 886 Static void 887 upl_watchdog(struct ifnet *ifp) 888 { 889 struct upl_softc *sc = ifp->if_softc; 890 891 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 892 893 if (sc->sc_dying) 894 return; 895 896 ifp->if_oerrors++; 897 printf("%s: watchdog timeout\n", device_xname(sc->sc_dev)); 898 899 upl_stop(sc); 900 upl_init(sc); 901 902 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 903 upl_start(ifp); 904 } 905 906 /* 907 * Stop the adapter and free any mbufs allocated to the 908 * RX and TX lists. 909 */ 910 Static void 911 upl_stop(struct upl_softc *sc) 912 { 913 usbd_status err; 914 struct ifnet *ifp; 915 int i; 916 917 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 918 919 ifp = &sc->sc_if; 920 ifp->if_timer = 0; 921 922 /* Stop transfers. */ 923 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 924 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 925 if (err) { 926 printf("%s: abort rx pipe failed: %s\n", 927 device_xname(sc->sc_dev), usbd_errstr(err)); 928 } 929 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 930 if (err) { 931 printf("%s: close rx pipe failed: %s\n", 932 device_xname(sc->sc_dev), usbd_errstr(err)); 933 } 934 sc->sc_ep[UPL_ENDPT_RX] = NULL; 935 } 936 937 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 938 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 939 if (err) { 940 printf("%s: abort tx pipe failed: %s\n", 941 device_xname(sc->sc_dev), usbd_errstr(err)); 942 } 943 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 944 if (err) { 945 printf("%s: close tx pipe failed: %s\n", 946 device_xname(sc->sc_dev), usbd_errstr(err)); 947 } 948 sc->sc_ep[UPL_ENDPT_TX] = NULL; 949 } 950 951 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 952 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 953 if (err) { 954 printf("%s: abort intr pipe failed: %s\n", 955 device_xname(sc->sc_dev), usbd_errstr(err)); 956 } 957 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 958 if (err) { 959 printf("%s: close intr pipe failed: %s\n", 960 device_xname(sc->sc_dev), usbd_errstr(err)); 961 } 962 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 963 } 964 965 /* Free RX resources. */ 966 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 967 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 968 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 969 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 970 } 971 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) { 972 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer); 973 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL; 974 } 975 } 976 977 /* Free TX resources. */ 978 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 979 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 980 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 981 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 982 } 983 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 984 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 985 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 986 } 987 } 988 989 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 990 } 991 992 Static int 993 upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 994 struct rtentry *rt0) 995 { 996 int s, len, error; 997 ALTQ_DECL(struct altq_pktattr pktattr;) 998 999 DPRINTFN(10,("%s: %s: enter\n", 1000 device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev), 1001 __func__)); 1002 1003 /* 1004 * if the queueing discipline needs packet classification, 1005 * do it now. 1006 */ 1007 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); 1008 1009 len = m->m_pkthdr.len; 1010 s = splnet(); 1011 /* 1012 * Queue message on interface, and start output if interface 1013 * not yet active. 1014 */ 1015 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); 1016 if (error) { 1017 /* mbuf is already freed */ 1018 splx(s); 1019 return (error); 1020 } 1021 ifp->if_obytes += len; 1022 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1023 (*ifp->if_start)(ifp); 1024 splx(s); 1025 1026 return (0); 1027 } 1028 1029 Static void 1030 upl_input(struct ifnet *ifp, struct mbuf *m) 1031 { 1032 #ifdef INET 1033 struct ifqueue *inq; 1034 int s; 1035 1036 /* XXX Assume all traffic is IP */ 1037 1038 schednetisr(NETISR_IP); 1039 inq = &ipintrq; 1040 1041 s = splnet(); 1042 if (IF_QFULL(inq)) { 1043 IF_DROP(inq); 1044 splx(s); 1045 #if 0 1046 if (sc->sc_flags & SC_DEBUG) 1047 printf("%s: input queue full\n", ifp->if_xname); 1048 #endif 1049 ifp->if_iqdrops++; 1050 return; 1051 } 1052 IF_ENQUEUE(inq, m); 1053 splx(s); 1054 #endif 1055 ifp->if_ipackets++; 1056 ifp->if_ibytes += m->m_len; 1057 } 1058