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