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