1 /* $NetBSD: if_upl.c,v 1.16 2001/11/13 06:24:54 lukem 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.16 2001/11/13 06:24:54 lukem 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 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), __FUNCTION__)); 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), __FUNCTION__)); 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), __FUNCTION__)); 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), __FUNCTION__)); 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), __FUNCTION__)); 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(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), __FUNCTION__, 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 __FUNCTION__, 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 __FUNCTION__)); 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 __FUNCTION__, 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(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 (ifp->if_snd.ifq_head != NULL) 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), __FUNCTION__, 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),__FUNCTION__)); 692 693 if (ifp->if_flags & IFF_OACTIVE) 694 return; 695 696 IF_DEQUEUE(&ifp->if_snd, m_head); 697 if (m_head == NULL) 698 return; 699 700 if (upl_send(sc, m_head, 0)) { 701 IF_PREPEND(&ifp->if_snd, m_head); 702 ifp->if_flags |= IFF_OACTIVE; 703 return; 704 } 705 706 #if NBPFILTER > 0 707 /* 708 * If there's a BPF listener, bounce a copy of this frame 709 * to him. 710 */ 711 if (ifp->if_bpf) 712 BPF_MTAP(ifp, m_head); 713 #endif 714 715 ifp->if_flags |= IFF_OACTIVE; 716 717 /* 718 * Set a timeout in case the chip goes out to lunch. 719 */ 720 ifp->if_timer = 5; 721 } 722 723 Static void 724 upl_init(void *xsc) 725 { 726 struct upl_softc *sc = xsc; 727 struct ifnet *ifp = &sc->sc_if; 728 int s; 729 730 if (sc->sc_dying) 731 return; 732 733 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__)); 734 735 if (ifp->if_flags & IFF_RUNNING) 736 return; 737 738 s = splnet(); 739 740 /* Init TX ring. */ 741 if (upl_tx_list_init(sc) == ENOBUFS) { 742 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev)); 743 splx(s); 744 return; 745 } 746 747 /* Init RX ring. */ 748 if (upl_rx_list_init(sc) == ENOBUFS) { 749 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev)); 750 splx(s); 751 return; 752 } 753 754 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 755 if (upl_openpipes(sc)) { 756 splx(s); 757 return; 758 } 759 } 760 761 ifp->if_flags |= IFF_RUNNING; 762 ifp->if_flags &= ~IFF_OACTIVE; 763 764 splx(s); 765 } 766 767 Static int 768 upl_openpipes(struct upl_softc *sc) 769 { 770 struct upl_chain *c; 771 usbd_status err; 772 int i; 773 774 /* Open RX and TX pipes. */ 775 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 776 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 777 if (err) { 778 printf("%s: open rx pipe failed: %s\n", 779 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 780 return (EIO); 781 } 782 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 783 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 784 if (err) { 785 printf("%s: open tx pipe failed: %s\n", 786 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 787 return (EIO); 788 } 789 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 790 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 791 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 792 UPL_INTR_INTERVAL); 793 if (err) { 794 printf("%s: open intr pipe failed: %s\n", 795 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 796 return (EIO); 797 } 798 799 800 #if 1 801 /* Start up the receive pipe. */ 802 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 803 c = &sc->sc_cdata.upl_rx_chain[i]; 804 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], 805 c, c->upl_buf, UPL_BUFSZ, 806 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 807 upl_rxeof); 808 usbd_transfer(c->upl_xfer); 809 } 810 #endif 811 812 return (0); 813 } 814 815 Static void 816 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 817 { 818 struct upl_softc *sc = priv; 819 struct ifnet *ifp = &sc->sc_if; 820 uByte stat; 821 822 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__)); 823 824 if (sc->sc_dying) 825 return; 826 827 if (!(ifp->if_flags & IFF_RUNNING)) 828 return; 829 830 if (status != USBD_NORMAL_COMPLETION) { 831 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 832 return; 833 } 834 sc->sc_intr_errs++; 835 if (usbd_ratecheck(&sc->sc_rx_notice)) { 836 printf("%s: %u usb errors on intr: %s\n", 837 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs, 838 usbd_errstr(status)); 839 sc->sc_intr_errs = 0; 840 } 841 if (status == USBD_STALLED) 842 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]); 843 return; 844 } 845 846 stat = sc->sc_ibuf; 847 848 if (stat == 0) 849 return; 850 851 DPRINTFN(10,("%s: %s: stat=0x%02x\n", USBDEVNAME(sc->sc_dev), 852 __FUNCTION__, stat)); 853 854 } 855 856 Static int 857 upl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 858 { 859 struct upl_softc *sc = ifp->if_softc; 860 struct ifaddr *ifa = (struct ifaddr *)data; 861 struct ifreq *ifr = (struct ifreq *)data; 862 int s, error = 0; 863 864 if (sc->sc_dying) 865 return (EIO); 866 867 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 868 USBDEVNAME(sc->sc_dev), __FUNCTION__, command)); 869 870 s = splnet(); 871 872 switch(command) { 873 case SIOCSIFADDR: 874 ifp->if_flags |= IFF_UP; 875 upl_init(sc); 876 877 switch (ifa->ifa_addr->sa_family) { 878 #ifdef INET 879 case AF_INET: 880 break; 881 #endif /* INET */ 882 #ifdef NS 883 case AF_NS: 884 { 885 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 886 887 if (ns_nullhost(*ina)) 888 ina->x_host = *(union ns_host *) 889 LLADDR(ifp->if_sadl); 890 else 891 memcpy(LLADDR(ifp->if_sadl), 892 ina->x_host.c_host, 893 ifp->if_addrlen); 894 break; 895 } 896 #endif /* NS */ 897 } 898 break; 899 900 case SIOCSIFMTU: 901 if (ifr->ifr_mtu > UPL_BUFSZ) 902 error = EINVAL; 903 else 904 ifp->if_mtu = ifr->ifr_mtu; 905 break; 906 907 case SIOCSIFFLAGS: 908 if (ifp->if_flags & IFF_UP) { 909 if (!(ifp->if_flags & IFF_RUNNING)) 910 upl_init(sc); 911 } else { 912 if (ifp->if_flags & IFF_RUNNING) 913 upl_stop(sc); 914 } 915 error = 0; 916 break; 917 default: 918 error = EINVAL; 919 break; 920 } 921 922 splx(s); 923 924 return (error); 925 } 926 927 Static void 928 upl_watchdog(struct ifnet *ifp) 929 { 930 struct upl_softc *sc = ifp->if_softc; 931 932 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__)); 933 934 if (sc->sc_dying) 935 return; 936 937 ifp->if_oerrors++; 938 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev)); 939 940 upl_stop(sc); 941 upl_init(sc); 942 943 if (ifp->if_snd.ifq_head != NULL) 944 upl_start(ifp); 945 } 946 947 /* 948 * Stop the adapter and free any mbufs allocated to the 949 * RX and TX lists. 950 */ 951 Static void 952 upl_stop(struct upl_softc *sc) 953 { 954 usbd_status err; 955 struct ifnet *ifp; 956 int i; 957 958 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__)); 959 960 ifp = &sc->sc_if; 961 ifp->if_timer = 0; 962 963 /* Stop transfers. */ 964 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 965 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 966 if (err) { 967 printf("%s: abort rx pipe failed: %s\n", 968 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 969 } 970 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 971 if (err) { 972 printf("%s: close rx pipe failed: %s\n", 973 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 974 } 975 sc->sc_ep[UPL_ENDPT_RX] = NULL; 976 } 977 978 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 979 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 980 if (err) { 981 printf("%s: abort tx pipe failed: %s\n", 982 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 983 } 984 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 985 if (err) { 986 printf("%s: close tx pipe failed: %s\n", 987 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 988 } 989 sc->sc_ep[UPL_ENDPT_TX] = NULL; 990 } 991 992 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 993 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 994 if (err) { 995 printf("%s: abort intr pipe failed: %s\n", 996 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 997 } 998 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 999 if (err) { 1000 printf("%s: close intr pipe failed: %s\n", 1001 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1002 } 1003 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 1004 } 1005 1006 /* Free RX resources. */ 1007 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 1008 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 1009 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 1010 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 1011 } 1012 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) { 1013 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer); 1014 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL; 1015 } 1016 } 1017 1018 /* Free TX resources. */ 1019 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 1020 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 1021 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 1022 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 1023 } 1024 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 1025 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 1026 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 1027 } 1028 } 1029 1030 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1031 } 1032 1033 Static int 1034 upl_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 1035 struct rtentry *rt0) 1036 { 1037 int s; 1038 1039 DPRINTFN(10,("%s: %s: enter\n", 1040 USBDEVNAME(((struct upl_softc *)ifp->if_softc)->sc_dev), 1041 __FUNCTION__)); 1042 1043 s = splnet(); 1044 /* 1045 * Queue message on interface, and start output if interface 1046 * not yet active. 1047 */ 1048 if (IF_QFULL(&ifp->if_snd)) { 1049 IF_DROP(&ifp->if_snd); 1050 splx(s); 1051 return (ENOBUFS); 1052 } 1053 ifp->if_obytes += m->m_pkthdr.len; 1054 IF_ENQUEUE(&ifp->if_snd, m); 1055 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1056 (*ifp->if_start)(ifp); 1057 splx(s); 1058 1059 return (0); 1060 } 1061 1062 Static void 1063 upl_input(struct ifnet *ifp, struct mbuf *m) 1064 { 1065 struct ifqueue *inq; 1066 int s; 1067 1068 /* XXX Assume all traffic is IP */ 1069 1070 schednetisr(NETISR_IP); 1071 inq = &ipintrq; 1072 1073 s = splnet(); 1074 if (IF_QFULL(inq)) { 1075 IF_DROP(inq); 1076 splx(s); 1077 #if 0 1078 if (sc->sc_flags & SC_DEBUG) 1079 printf("%s: input queue full\n", ifp->if_xname); 1080 #endif 1081 ifp->if_iqdrops++; 1082 return; 1083 } 1084 IF_ENQUEUE(inq, m); 1085 splx(s); 1086 ifp->if_ipackets++; 1087 ifp->if_ibytes += m->m_len; 1088 } 1089