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