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