1 /* $NetBSD: if_upl.c,v 1.44 2013/01/05 01:30:16 christos 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.44 2013/01/05 01:30:16 christos Exp $"); 38 39 #ifdef _KERNEL_OPT 40 #include "opt_inet.h" 41 #endif 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 #include <sys/rnd.h> 54 55 #include <net/if.h> 56 #include <net/if_types.h> 57 #include <net/if_dl.h> 58 #include <net/netisr.h> 59 60 #include <net/bpf.h> 61 62 #ifdef INET 63 #include <netinet/in.h> 64 #include <netinet/in_var.h> 65 #include <netinet/if_inarp.h> 66 #endif 67 68 69 #include <dev/usb/usb.h> 70 #include <dev/usb/usbdi.h> 71 #include <dev/usb/usbdi_util.h> 72 #include <dev/usb/usbdevs.h> 73 74 /* 75 * 7 6 5 4 3 2 1 0 76 * tx rx 1 0 77 * 1110 0000 rxdata 78 * 1010 0000 idle 79 * 0010 0000 tx over 80 * 0110 tx over + rxd 81 */ 82 83 #define UPL_RXDATA 0x40 84 #define UPL_TXOK 0x80 85 86 #define UPL_INTR_PKTLEN 1 87 88 #define UPL_CONFIG_NO 1 89 #define UPL_IFACE_IDX 0 90 91 /***/ 92 93 #define UPL_INTR_INTERVAL 20 94 95 #define UPL_BUFSZ 1024 96 97 #define UPL_RX_FRAMES 1 98 #define UPL_TX_FRAMES 1 99 100 #define UPL_RX_LIST_CNT 1 101 #define UPL_TX_LIST_CNT 1 102 103 #define UPL_ENDPT_RX 0x0 104 #define UPL_ENDPT_TX 0x1 105 #define UPL_ENDPT_INTR 0x2 106 #define UPL_ENDPT_MAX 0x3 107 108 struct upl_type { 109 u_int16_t upl_vid; 110 u_int16_t upl_did; 111 }; 112 113 struct upl_softc; 114 115 struct upl_chain { 116 struct upl_softc *upl_sc; 117 usbd_xfer_handle upl_xfer; 118 char *upl_buf; 119 struct mbuf *upl_mbuf; 120 int upl_idx; 121 }; 122 123 struct upl_cdata { 124 struct upl_chain upl_tx_chain[UPL_TX_LIST_CNT]; 125 struct upl_chain upl_rx_chain[UPL_RX_LIST_CNT]; 126 int upl_tx_prod; 127 int upl_tx_cons; 128 int upl_tx_cnt; 129 int upl_rx_prod; 130 }; 131 132 struct upl_softc { 133 device_t sc_dev; 134 135 struct ifnet sc_if; 136 krndsource_t sc_rnd_source; 137 138 struct callout sc_stat_ch; 139 140 usbd_device_handle sc_udev; 141 usbd_interface_handle sc_iface; 142 u_int16_t sc_vendor; 143 u_int16_t sc_product; 144 int sc_ed[UPL_ENDPT_MAX]; 145 usbd_pipe_handle sc_ep[UPL_ENDPT_MAX]; 146 struct upl_cdata sc_cdata; 147 148 uByte sc_ibuf; 149 150 char sc_dying; 151 char sc_attached; 152 u_int sc_rx_errs; 153 struct timeval sc_rx_notice; 154 u_int sc_intr_errs; 155 }; 156 157 #ifdef UPL_DEBUG 158 #define DPRINTF(x) if (upldebug) printf x 159 #define DPRINTFN(n,x) if (upldebug >= (n)) printf x 160 int upldebug = 0; 161 #else 162 #define DPRINTF(x) 163 #define DPRINTFN(n,x) 164 #endif 165 166 /* 167 * Various supported device vendors/products. 168 */ 169 Static struct upl_type sc_devs[] = { 170 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 }, 171 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 }, 172 { 0, 0 } 173 }; 174 175 int upl_match(device_t, cfdata_t, void *); 176 void upl_attach(device_t, device_t, void *); 177 int upl_detach(device_t, int); 178 int upl_activate(device_t, enum devact); 179 extern struct cfdriver upl_cd; 180 CFATTACH_DECL_NEW(upl, sizeof(struct upl_softc), upl_match, upl_attach, upl_detach, upl_activate); 181 182 Static int upl_openpipes(struct upl_softc *); 183 Static int upl_tx_list_init(struct upl_softc *); 184 Static int upl_rx_list_init(struct upl_softc *); 185 Static int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *); 186 Static int upl_send(struct upl_softc *, struct mbuf *, int); 187 Static void upl_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); 188 Static void upl_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 189 Static void upl_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 190 Static void upl_start(struct ifnet *); 191 Static int upl_ioctl(struct ifnet *, u_long, void *); 192 Static void upl_init(void *); 193 Static void upl_stop(struct upl_softc *); 194 Static void upl_watchdog(struct ifnet *); 195 196 Static int upl_output(struct ifnet *, struct mbuf *, const struct sockaddr *, 197 struct rtentry *); 198 Static void upl_input(struct ifnet *, struct mbuf *); 199 200 /* 201 * Probe for a Prolific chip. 202 */ 203 int 204 upl_match(device_t parent, cfdata_t match, void *aux) 205 { 206 struct usb_attach_arg *uaa = aux; 207 struct upl_type *t; 208 209 for (t = sc_devs; t->upl_vid != 0; t++) 210 if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did) 211 return (UMATCH_VENDOR_PRODUCT); 212 213 return (UMATCH_NONE); 214 } 215 216 void 217 upl_attach(device_t parent, device_t self, void *aux) 218 { 219 struct upl_softc *sc = device_private(self); 220 struct usb_attach_arg *uaa = aux; 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, "failed to set configuration" 245 ", err=%s\n", usbd_errstr(err)); 246 return; 247 } 248 249 sc->sc_udev = dev; 250 sc->sc_product = uaa->product; 251 sc->sc_vendor = uaa->vendor; 252 253 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); 254 if (err) { 255 aprint_error_dev(self, "getting interface handle failed\n"); 256 return; 257 } 258 259 sc->sc_iface = iface; 260 id = usbd_get_interface_descriptor(iface); 261 262 /* Find endpoints. */ 263 for (i = 0; i < id->bNumEndpoints; i++) { 264 ed = usbd_interface2endpoint_descriptor(iface, i); 265 if (ed == NULL) { 266 aprint_error_dev(self, "couldn't get ep %d\n", i); 267 return; 268 } 269 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 270 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 271 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress; 272 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 273 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 274 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress; 275 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 276 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 277 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress; 278 } 279 } 280 281 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 || 282 sc->sc_ed[UPL_ENDPT_INTR] == 0) { 283 aprint_error_dev(self, "missing endpoint\n"); 284 return; 285 } 286 287 s = splnet(); 288 289 /* Initialize interface info.*/ 290 ifp = &sc->sc_if; 291 ifp->if_softc = sc; 292 ifp->if_mtu = UPL_BUFSZ; 293 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX; 294 ifp->if_ioctl = upl_ioctl; 295 ifp->if_start = upl_start; 296 ifp->if_watchdog = upl_watchdog; 297 strncpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 298 299 ifp->if_type = IFT_OTHER; 300 ifp->if_addrlen = 0; 301 ifp->if_hdrlen = 0; 302 ifp->if_output = upl_output; 303 ifp->if_input = upl_input; 304 ifp->if_baudrate = 12000000; 305 ifp->if_dlt = DLT_RAW; 306 IFQ_SET_READY(&ifp->if_snd); 307 308 /* Attach the interface. */ 309 if_attach(ifp); 310 if_alloc_sadl(ifp); 311 312 bpf_attach(ifp, DLT_RAW, 0); 313 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 314 RND_TYPE_NET, 0); 315 316 sc->sc_attached = 1; 317 splx(s); 318 319 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 320 sc->sc_dev); 321 322 return; 323 } 324 325 int 326 upl_detach(device_t self, int flags) 327 { 328 struct upl_softc *sc = device_private(self); 329 struct ifnet *ifp = &sc->sc_if; 330 int s; 331 332 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 333 334 s = splusb(); 335 336 if (!sc->sc_attached) { 337 /* Detached before attached finished, so just bail out. */ 338 splx(s); 339 return (0); 340 } 341 342 if (ifp->if_flags & IFF_RUNNING) 343 upl_stop(sc); 344 345 rnd_detach_source(&sc->sc_rnd_source); 346 bpf_detach(ifp); 347 348 if_detach(ifp); 349 350 #ifdef DIAGNOSTIC 351 if (sc->sc_ep[UPL_ENDPT_TX] != NULL || 352 sc->sc_ep[UPL_ENDPT_RX] != NULL || 353 sc->sc_ep[UPL_ENDPT_INTR] != NULL) 354 aprint_debug_dev(self, "detach has active endpoints\n"); 355 #endif 356 357 sc->sc_attached = 0; 358 splx(s); 359 360 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 361 sc->sc_dev); 362 363 return (0); 364 } 365 366 int 367 upl_activate(device_t self, enum devact act) 368 { 369 struct upl_softc *sc = device_private(self); 370 371 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 372 373 switch (act) { 374 case DVACT_DEACTIVATE: 375 /* Deactivate the interface. */ 376 if_deactivate(&sc->sc_if); 377 sc->sc_dying = 1; 378 return 0; 379 default: 380 return EOPNOTSUPP; 381 } 382 } 383 384 /* 385 * Initialize an RX descriptor and attach an MBUF cluster. 386 */ 387 Static int 388 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) 389 { 390 struct mbuf *m_new = NULL; 391 392 DPRINTFN(8,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 393 394 if (m == NULL) { 395 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 396 if (m_new == NULL) { 397 printf("%s: no memory for rx list " 398 "-- packet dropped!\n", device_xname(sc->sc_dev)); 399 return (ENOBUFS); 400 } 401 402 MCLGET(m_new, M_DONTWAIT); 403 if (!(m_new->m_flags & M_EXT)) { 404 printf("%s: no memory for rx list " 405 "-- packet dropped!\n", device_xname(sc->sc_dev)); 406 m_freem(m_new); 407 return (ENOBUFS); 408 } 409 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 410 } else { 411 m_new = m; 412 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 413 m_new->m_data = m_new->m_ext.ext_buf; 414 } 415 416 c->upl_mbuf = m_new; 417 418 return (0); 419 } 420 421 Static int 422 upl_rx_list_init(struct upl_softc *sc) 423 { 424 struct upl_cdata *cd; 425 struct upl_chain *c; 426 int i; 427 428 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 429 430 cd = &sc->sc_cdata; 431 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 432 c = &cd->upl_rx_chain[i]; 433 c->upl_sc = sc; 434 c->upl_idx = i; 435 if (upl_newbuf(sc, c, NULL) == ENOBUFS) 436 return (ENOBUFS); 437 if (c->upl_xfer == NULL) { 438 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); 439 if (c->upl_xfer == NULL) 440 return (ENOBUFS); 441 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); 442 if (c->upl_buf == NULL) { 443 usbd_free_xfer(c->upl_xfer); 444 return (ENOBUFS); 445 } 446 } 447 } 448 449 return (0); 450 } 451 452 Static int 453 upl_tx_list_init(struct upl_softc *sc) 454 { 455 struct upl_cdata *cd; 456 struct upl_chain *c; 457 int i; 458 459 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 460 461 cd = &sc->sc_cdata; 462 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 463 c = &cd->upl_tx_chain[i]; 464 c->upl_sc = sc; 465 c->upl_idx = i; 466 c->upl_mbuf = NULL; 467 if (c->upl_xfer == NULL) { 468 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); 469 if (c->upl_xfer == NULL) 470 return (ENOBUFS); 471 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); 472 if (c->upl_buf == NULL) { 473 usbd_free_xfer(c->upl_xfer); 474 return (ENOBUFS); 475 } 476 } 477 } 478 479 return (0); 480 } 481 482 /* 483 * A frame has been uploaded: pass the resulting mbuf chain up to 484 * the higher level protocols. 485 */ 486 Static void 487 upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 488 { 489 struct upl_chain *c = priv; 490 struct upl_softc *sc = c->upl_sc; 491 struct ifnet *ifp = &sc->sc_if; 492 struct mbuf *m; 493 int total_len = 0; 494 int s; 495 496 if (sc->sc_dying) 497 return; 498 499 if (!(ifp->if_flags & IFF_RUNNING)) 500 return; 501 502 if (status != USBD_NORMAL_COMPLETION) { 503 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 504 return; 505 sc->sc_rx_errs++; 506 if (usbd_ratecheck(&sc->sc_rx_notice)) { 507 printf("%s: %u usb errors on rx: %s\n", 508 device_xname(sc->sc_dev), sc->sc_rx_errs, 509 usbd_errstr(status)); 510 sc->sc_rx_errs = 0; 511 } 512 if (status == USBD_STALLED) 513 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 514 goto done; 515 } 516 517 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 518 519 DPRINTFN(9,("%s: %s: enter status=%d length=%d\n", 520 device_xname(sc->sc_dev), __func__, status, total_len)); 521 522 m = c->upl_mbuf; 523 memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len); 524 525 ifp->if_ipackets++; 526 m->m_pkthdr.len = m->m_len = total_len; 527 528 m->m_pkthdr.rcvif = ifp; 529 530 s = splnet(); 531 532 /* XXX ugly */ 533 if (upl_newbuf(sc, c, NULL) == ENOBUFS) { 534 ifp->if_ierrors++; 535 goto done1; 536 } 537 538 /* 539 * Handle BPF listeners. Let the BPF user see the packet, but 540 * don't pass it up to the ether_input() layer unless it's 541 * a broadcast packet, multicast packet, matches our ethernet 542 * address or the interface is in promiscuous mode. 543 */ 544 bpf_mtap(ifp, m); 545 546 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev), 547 __func__, m->m_len)); 548 549 (*(ifp)->if_input)((ifp), (m)); 550 551 done1: 552 splx(s); 553 554 done: 555 #if 1 556 /* Setup new transfer. */ 557 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 558 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 559 USBD_NO_TIMEOUT, upl_rxeof); 560 usbd_transfer(c->upl_xfer); 561 562 DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), 563 __func__)); 564 #endif 565 } 566 567 /* 568 * A frame was downloaded to the chip. It's safe for us to clean up 569 * the list buffers. 570 */ 571 Static void 572 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 573 usbd_status status) 574 { 575 struct upl_chain *c = priv; 576 struct upl_softc *sc = c->upl_sc; 577 struct ifnet *ifp = &sc->sc_if; 578 int s; 579 580 if (sc->sc_dying) 581 return; 582 583 s = splnet(); 584 585 DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev), 586 __func__, status)); 587 588 ifp->if_timer = 0; 589 ifp->if_flags &= ~IFF_OACTIVE; 590 591 if (status != USBD_NORMAL_COMPLETION) { 592 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 593 splx(s); 594 return; 595 } 596 ifp->if_oerrors++; 597 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev), 598 usbd_errstr(status)); 599 if (status == USBD_STALLED) 600 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]); 601 splx(s); 602 return; 603 } 604 605 ifp->if_opackets++; 606 607 m_freem(c->upl_mbuf); 608 c->upl_mbuf = NULL; 609 610 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 611 upl_start(ifp); 612 613 splx(s); 614 } 615 616 Static int 617 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 618 { 619 int total_len; 620 struct upl_chain *c; 621 usbd_status err; 622 623 c = &sc->sc_cdata.upl_tx_chain[idx]; 624 625 /* 626 * Copy the mbuf data into a contiguous buffer, leaving two 627 * bytes at the beginning to hold the frame length. 628 */ 629 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 630 c->upl_mbuf = m; 631 632 total_len = m->m_pkthdr.len; 633 634 DPRINTFN(10,("%s: %s: total_len=%d\n", 635 device_xname(sc->sc_dev), __func__, total_len)); 636 637 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX], 638 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, 639 upl_txeof); 640 641 /* Transmit */ 642 err = usbd_transfer(c->upl_xfer); 643 if (err != USBD_IN_PROGRESS) { 644 printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), 645 usbd_errstr(err)); 646 upl_stop(sc); 647 return (EIO); 648 } 649 650 sc->sc_cdata.upl_tx_cnt++; 651 652 return (0); 653 } 654 655 Static void 656 upl_start(struct ifnet *ifp) 657 { 658 struct upl_softc *sc = ifp->if_softc; 659 struct mbuf *m_head = NULL; 660 661 if (sc->sc_dying) 662 return; 663 664 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 665 666 if (ifp->if_flags & IFF_OACTIVE) 667 return; 668 669 IFQ_POLL(&ifp->if_snd, m_head); 670 if (m_head == NULL) 671 return; 672 673 if (upl_send(sc, m_head, 0)) { 674 ifp->if_flags |= IFF_OACTIVE; 675 return; 676 } 677 678 IFQ_DEQUEUE(&ifp->if_snd, m_head); 679 680 /* 681 * If there's a BPF listener, bounce a copy of this frame 682 * to him. 683 */ 684 bpf_mtap(ifp, 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", device_xname(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", device_xname(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", device_xname(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 device_xname(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 device_xname(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 device_xname(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", device_xname(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 device_xname(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", device_xname(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 device_xname(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", device_xname(sc->sc_dev),__func__)); 895 896 if (sc->sc_dying) 897 return; 898 899 ifp->if_oerrors++; 900 printf("%s: watchdog timeout\n", device_xname(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", device_xname(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 device_xname(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 device_xname(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 device_xname(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 device_xname(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 device_xname(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 device_xname(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 device_xname(((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