1 /* $NetBSD: if_upl.c,v 1.62 2018/06/26 06:48:02 msaitoh 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.62 2018/06/26 06:48:02 msaitoh 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 int rv; 232 233 DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev)); 234 235 sc->sc_dev = self; 236 237 aprint_naive("\n"); 238 aprint_normal("\n"); 239 240 devinfop = usbd_devinfo_alloc(dev, 0); 241 aprint_normal_dev(self, "%s\n", devinfop); 242 usbd_devinfo_free(devinfop); 243 244 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1); 245 if (err) { 246 aprint_error_dev(self, "failed to set configuration" 247 ", err=%s\n", usbd_errstr(err)); 248 return; 249 } 250 251 sc->sc_udev = dev; 252 sc->sc_product = uaa->uaa_product; 253 sc->sc_vendor = uaa->uaa_vendor; 254 255 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); 256 if (err) { 257 aprint_error_dev(self, "getting interface handle failed\n"); 258 return; 259 } 260 261 sc->sc_iface = iface; 262 id = usbd_get_interface_descriptor(iface); 263 264 /* Find endpoints. */ 265 for (i = 0; i < id->bNumEndpoints; i++) { 266 ed = usbd_interface2endpoint_descriptor(iface, i); 267 if (ed == NULL) { 268 aprint_error_dev(self, "couldn't get ep %d\n", i); 269 return; 270 } 271 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 272 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 273 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress; 274 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 275 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 276 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress; 277 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 278 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 279 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress; 280 } 281 } 282 283 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 || 284 sc->sc_ed[UPL_ENDPT_INTR] == 0) { 285 aprint_error_dev(self, "missing endpoint\n"); 286 return; 287 } 288 289 s = splnet(); 290 291 /* Initialize interface info.*/ 292 ifp = &sc->sc_if; 293 ifp->if_softc = sc; 294 ifp->if_mtu = UPL_BUFSZ; 295 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX; 296 ifp->if_ioctl = upl_ioctl; 297 ifp->if_start = upl_start; 298 ifp->if_watchdog = upl_watchdog; 299 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 300 301 ifp->if_type = IFT_OTHER; 302 ifp->if_addrlen = 0; 303 ifp->if_hdrlen = 0; 304 ifp->if_output = upl_output; 305 ifp->_if_input = upl_input; 306 ifp->if_baudrate = 12000000; 307 ifp->if_dlt = DLT_RAW; 308 IFQ_SET_READY(&ifp->if_snd); 309 310 /* Attach the interface. */ 311 rv = if_initialize(ifp); 312 if (rv != 0) { 313 aprint_error_dev(self, "if_initialize failed(%d)\n", rv); 314 splx(s); 315 return; 316 } 317 if_register(ifp); 318 if_alloc_sadl(ifp); 319 320 bpf_attach(ifp, DLT_RAW, 0); 321 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 322 RND_TYPE_NET, RND_FLAG_DEFAULT); 323 324 sc->sc_attached = 1; 325 splx(s); 326 327 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 328 329 return; 330 } 331 332 int 333 upl_detach(device_t self, int flags) 334 { 335 struct upl_softc *sc = device_private(self); 336 struct ifnet *ifp = &sc->sc_if; 337 int s; 338 339 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 340 341 s = splusb(); 342 343 if (!sc->sc_attached) { 344 /* Detached before attached finished, so just bail out. */ 345 splx(s); 346 return 0; 347 } 348 349 if (ifp->if_flags & IFF_RUNNING) 350 upl_stop(sc); 351 352 rnd_detach_source(&sc->sc_rnd_source); 353 bpf_detach(ifp); 354 355 if_detach(ifp); 356 357 #ifdef DIAGNOSTIC 358 if (sc->sc_ep[UPL_ENDPT_TX] != NULL || 359 sc->sc_ep[UPL_ENDPT_RX] != NULL || 360 sc->sc_ep[UPL_ENDPT_INTR] != NULL) 361 aprint_debug_dev(self, "detach has active endpoints\n"); 362 #endif 363 364 sc->sc_attached = 0; 365 splx(s); 366 367 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 368 369 return 0; 370 } 371 372 int 373 upl_activate(device_t self, enum devact act) 374 { 375 struct upl_softc *sc = device_private(self); 376 377 DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 378 379 switch (act) { 380 case DVACT_DEACTIVATE: 381 /* Deactivate the interface. */ 382 if_deactivate(&sc->sc_if); 383 sc->sc_dying = 1; 384 return 0; 385 default: 386 return EOPNOTSUPP; 387 } 388 } 389 390 /* 391 * Initialize an RX descriptor and attach an MBUF cluster. 392 */ 393 Static int 394 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) 395 { 396 struct mbuf *m_new = NULL; 397 398 DPRINTFN(8,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 399 400 if (m == NULL) { 401 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 402 if (m_new == NULL) { 403 printf("%s: no memory for rx list " 404 "-- packet dropped!\n", device_xname(sc->sc_dev)); 405 return ENOBUFS; 406 } 407 408 MCLGET(m_new, M_DONTWAIT); 409 if (!(m_new->m_flags & M_EXT)) { 410 printf("%s: no memory for rx list " 411 "-- packet dropped!\n", device_xname(sc->sc_dev)); 412 m_freem(m_new); 413 return ENOBUFS; 414 } 415 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 416 } else { 417 m_new = m; 418 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 419 m_new->m_data = m_new->m_ext.ext_buf; 420 } 421 422 c->upl_mbuf = m_new; 423 424 return 0; 425 } 426 427 Static int 428 upl_rx_list_init(struct upl_softc *sc) 429 { 430 struct upl_cdata *cd; 431 struct upl_chain *c; 432 int i; 433 434 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 435 436 cd = &sc->sc_cdata; 437 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 438 c = &cd->upl_rx_chain[i]; 439 c->upl_sc = sc; 440 c->upl_idx = i; 441 if (upl_newbuf(sc, c, NULL) == ENOBUFS) 442 return ENOBUFS; 443 if (c->upl_xfer == NULL) { 444 int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_RX], 445 UPL_BUFSZ, 0, 0, &c->upl_xfer); 446 if (error) 447 return error; 448 c->upl_buf = usbd_get_buffer(c->upl_xfer); 449 } 450 } 451 452 return 0; 453 } 454 455 Static int 456 upl_tx_list_init(struct upl_softc *sc) 457 { 458 struct upl_cdata *cd; 459 struct upl_chain *c; 460 int i; 461 462 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); 463 464 cd = &sc->sc_cdata; 465 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 466 c = &cd->upl_tx_chain[i]; 467 c->upl_sc = sc; 468 c->upl_idx = i; 469 c->upl_mbuf = NULL; 470 if (c->upl_xfer == NULL) { 471 int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_TX], 472 UPL_BUFSZ, 0, 0, &c->upl_xfer); 473 if (error) 474 return error; 475 c->upl_buf = usbd_get_buffer(c->upl_xfer); 476 } 477 } 478 479 return 0; 480 } 481 482 /* 483 * A frame has been uploaded: pass the resulting mbuf chain up to 484 * the higher level protocols. 485 */ 486 Static void 487 upl_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 488 { 489 struct upl_chain *c = priv; 490 struct upl_softc *sc = c->upl_sc; 491 struct ifnet *ifp = &sc->sc_if; 492 struct mbuf *m; 493 int total_len = 0; 494 int s; 495 496 if (sc->sc_dying) 497 return; 498 499 if (!(ifp->if_flags & IFF_RUNNING)) 500 return; 501 502 if (status != USBD_NORMAL_COMPLETION) { 503 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 504 return; 505 sc->sc_rx_errs++; 506 if (usbd_ratecheck(&sc->sc_rx_notice)) { 507 printf("%s: %u usb errors on rx: %s\n", 508 device_xname(sc->sc_dev), sc->sc_rx_errs, 509 usbd_errstr(status)); 510 sc->sc_rx_errs = 0; 511 } 512 if (status == USBD_STALLED) 513 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 514 goto done; 515 } 516 517 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 518 519 DPRINTFN(9,("%s: %s: enter status=%d length=%d\n", 520 device_xname(sc->sc_dev), __func__, status, total_len)); 521 522 m = c->upl_mbuf; 523 memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len); 524 525 m->m_pkthdr.len = m->m_len = total_len; 526 527 m_set_rcvif(m, ifp); 528 529 s = splnet(); 530 531 /* XXX ugly */ 532 if (upl_newbuf(sc, c, NULL) == ENOBUFS) { 533 ifp->if_ierrors++; 534 goto done1; 535 } 536 537 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev), 538 __func__, m->m_len)); 539 540 if_input((ifp), (m)); 541 542 done1: 543 splx(s); 544 545 done: 546 #if 1 547 /* Setup new transfer. */ 548 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, 549 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upl_rxeof); 550 usbd_transfer(c->upl_xfer); 551 552 DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), 553 __func__)); 554 #endif 555 } 556 557 /* 558 * A frame was downloaded to the chip. It's safe for us to clean up 559 * the list buffers. 560 */ 561 Static void 562 upl_txeof(struct usbd_xfer *xfer, void *priv, 563 usbd_status status) 564 { 565 struct upl_chain *c = priv; 566 struct upl_softc *sc = c->upl_sc; 567 struct ifnet *ifp = &sc->sc_if; 568 int s; 569 570 if (sc->sc_dying) 571 return; 572 573 s = splnet(); 574 575 DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev), 576 __func__, status)); 577 578 ifp->if_timer = 0; 579 ifp->if_flags &= ~IFF_OACTIVE; 580 581 if (status != USBD_NORMAL_COMPLETION) { 582 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 583 splx(s); 584 return; 585 } 586 ifp->if_oerrors++; 587 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev), 588 usbd_errstr(status)); 589 if (status == USBD_STALLED) 590 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]); 591 splx(s); 592 return; 593 } 594 595 ifp->if_opackets++; 596 597 m_freem(c->upl_mbuf); 598 c->upl_mbuf = NULL; 599 600 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 601 upl_start(ifp); 602 603 splx(s); 604 } 605 606 Static int 607 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 608 { 609 int total_len; 610 struct upl_chain *c; 611 usbd_status err; 612 613 c = &sc->sc_cdata.upl_tx_chain[idx]; 614 615 /* 616 * Copy the mbuf data into a contiguous buffer, leaving two 617 * bytes at the beginning to hold the frame length. 618 */ 619 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 620 c->upl_mbuf = m; 621 622 total_len = m->m_pkthdr.len; 623 624 DPRINTFN(10,("%s: %s: total_len=%d\n", 625 device_xname(sc->sc_dev), __func__, total_len)); 626 627 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, total_len, 0, 628 USBD_DEFAULT_TIMEOUT, upl_txeof); 629 630 /* Transmit */ 631 err = usbd_transfer(c->upl_xfer); 632 if (err != USBD_IN_PROGRESS) { 633 printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), 634 usbd_errstr(err)); 635 upl_stop(sc); 636 return EIO; 637 } 638 639 sc->sc_cdata.upl_tx_cnt++; 640 641 return 0; 642 } 643 644 Static void 645 upl_start(struct ifnet *ifp) 646 { 647 struct upl_softc *sc = ifp->if_softc; 648 struct mbuf *m_head = NULL; 649 650 if (sc->sc_dying) 651 return; 652 653 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 654 655 if (ifp->if_flags & IFF_OACTIVE) 656 return; 657 658 IFQ_POLL(&ifp->if_snd, m_head); 659 if (m_head == NULL) 660 return; 661 662 if (upl_send(sc, m_head, 0)) { 663 ifp->if_flags |= IFF_OACTIVE; 664 return; 665 } 666 667 IFQ_DEQUEUE(&ifp->if_snd, m_head); 668 669 /* 670 * If there's a BPF listener, bounce a copy of this frame 671 * to him. 672 */ 673 bpf_mtap(ifp, m_head, BPF_D_OUT); 674 675 ifp->if_flags |= IFF_OACTIVE; 676 677 /* 678 * Set a timeout in case the chip goes out to lunch. 679 */ 680 ifp->if_timer = 5; 681 } 682 683 Static void 684 upl_init(void *xsc) 685 { 686 struct upl_softc *sc = xsc; 687 struct ifnet *ifp = &sc->sc_if; 688 int s; 689 690 if (sc->sc_dying) 691 return; 692 693 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 694 695 if (ifp->if_flags & IFF_RUNNING) 696 return; 697 698 s = splnet(); 699 700 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 701 if (upl_openpipes(sc)) { 702 splx(s); 703 return; 704 } 705 } 706 /* Init TX ring. */ 707 if (upl_tx_list_init(sc)) { 708 printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); 709 splx(s); 710 return; 711 } 712 713 /* Init RX ring. */ 714 if (upl_rx_list_init(sc)) { 715 printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); 716 splx(s); 717 return; 718 } 719 720 /* Start up the receive pipe. */ 721 for (int i = 0; i < UPL_RX_LIST_CNT; i++) { 722 struct upl_chain *c = &sc->sc_cdata.upl_rx_chain[i]; 723 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, 724 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 725 upl_rxeof); 726 usbd_transfer(c->upl_xfer); 727 } 728 729 ifp->if_flags |= IFF_RUNNING; 730 ifp->if_flags &= ~IFF_OACTIVE; 731 732 splx(s); 733 } 734 735 Static int 736 upl_openpipes(struct upl_softc *sc) 737 { 738 usbd_status err; 739 740 /* Open RX and TX pipes. */ 741 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 742 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 743 if (err) { 744 printf("%s: open rx pipe failed: %s\n", 745 device_xname(sc->sc_dev), usbd_errstr(err)); 746 return EIO; 747 } 748 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 749 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 750 if (err) { 751 printf("%s: open tx pipe failed: %s\n", 752 device_xname(sc->sc_dev), usbd_errstr(err)); 753 return EIO; 754 } 755 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 756 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 757 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 758 UPL_INTR_INTERVAL); 759 if (err) { 760 printf("%s: open intr pipe failed: %s\n", 761 device_xname(sc->sc_dev), usbd_errstr(err)); 762 return EIO; 763 } 764 765 return 0; 766 } 767 768 Static void 769 upl_intr(struct usbd_xfer *xfer, void *priv, 770 usbd_status status) 771 { 772 struct upl_softc *sc = priv; 773 struct ifnet *ifp = &sc->sc_if; 774 uByte stat; 775 776 DPRINTFN(15,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 777 778 if (sc->sc_dying) 779 return; 780 781 if (!(ifp->if_flags & IFF_RUNNING)) 782 return; 783 784 if (status != USBD_NORMAL_COMPLETION) { 785 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 786 return; 787 } 788 sc->sc_intr_errs++; 789 if (usbd_ratecheck(&sc->sc_rx_notice)) { 790 printf("%s: %u usb errors on intr: %s\n", 791 device_xname(sc->sc_dev), sc->sc_rx_errs, 792 usbd_errstr(status)); 793 sc->sc_intr_errs = 0; 794 } 795 if (status == USBD_STALLED) 796 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 797 return; 798 } 799 800 stat = sc->sc_ibuf; 801 802 if (stat == 0) 803 return; 804 805 DPRINTFN(10,("%s: %s: stat=0x%02x\n", device_xname(sc->sc_dev), 806 __func__, stat)); 807 808 } 809 810 Static int 811 upl_ioctl(struct ifnet *ifp, u_long command, void *data) 812 { 813 struct upl_softc *sc = ifp->if_softc; 814 struct ifaddr *ifa = (struct ifaddr *)data; 815 struct ifreq *ifr = (struct ifreq *)data; 816 int s, error = 0; 817 818 if (sc->sc_dying) 819 return EIO; 820 821 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 822 device_xname(sc->sc_dev), __func__, command)); 823 824 s = splnet(); 825 826 switch(command) { 827 case SIOCINITIFADDR: 828 ifp->if_flags |= IFF_UP; 829 upl_init(sc); 830 831 switch (ifa->ifa_addr->sa_family) { 832 #ifdef INET 833 case AF_INET: 834 break; 835 #endif /* INET */ 836 } 837 break; 838 839 case SIOCSIFMTU: 840 if (ifr->ifr_mtu > UPL_BUFSZ) 841 error = EINVAL; 842 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 843 error = 0; 844 break; 845 846 case SIOCSIFFLAGS: 847 if ((error = ifioctl_common(ifp, command, data)) != 0) 848 break; 849 /* XXX re-use ether_ioctl() */ 850 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 851 case IFF_UP: 852 upl_init(sc); 853 break; 854 case IFF_RUNNING: 855 upl_stop(sc); 856 break; 857 default: 858 break; 859 } 860 break; 861 default: 862 error = ifioctl_common(ifp, command, data); 863 break; 864 } 865 866 splx(s); 867 868 return error; 869 } 870 871 Static void 872 upl_watchdog(struct ifnet *ifp) 873 { 874 struct upl_softc *sc = ifp->if_softc; 875 876 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 877 878 if (sc->sc_dying) 879 return; 880 881 ifp->if_oerrors++; 882 printf("%s: watchdog timeout\n", device_xname(sc->sc_dev)); 883 884 upl_stop(sc); 885 upl_init(sc); 886 887 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 888 upl_start(ifp); 889 } 890 891 /* 892 * Stop the adapter and free any mbufs allocated to the 893 * RX and TX lists. 894 */ 895 Static void 896 upl_stop(struct upl_softc *sc) 897 { 898 usbd_status err; 899 struct ifnet *ifp; 900 int i; 901 902 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 903 904 ifp = &sc->sc_if; 905 ifp->if_timer = 0; 906 907 /* Stop transfers. */ 908 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 909 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 910 if (err) { 911 printf("%s: abort rx pipe failed: %s\n", 912 device_xname(sc->sc_dev), usbd_errstr(err)); 913 } 914 } 915 916 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 917 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 918 if (err) { 919 printf("%s: abort tx pipe failed: %s\n", 920 device_xname(sc->sc_dev), usbd_errstr(err)); 921 } 922 } 923 924 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 925 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 926 if (err) { 927 printf("%s: abort intr pipe failed: %s\n", 928 device_xname(sc->sc_dev), usbd_errstr(err)); 929 } 930 } 931 932 /* Free RX resources. */ 933 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 934 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 935 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 936 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 937 } 938 } 939 940 /* Free TX resources. */ 941 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 942 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 943 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 944 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 945 } 946 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 947 usbd_destroy_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 948 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 949 } 950 } 951 952 /* Close pipes */ 953 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 954 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 955 if (err) { 956 printf("%s: close rx pipe failed: %s\n", 957 device_xname(sc->sc_dev), usbd_errstr(err)); 958 } 959 sc->sc_ep[UPL_ENDPT_RX] = NULL; 960 } 961 962 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 963 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 964 if (err) { 965 printf("%s: close tx pipe failed: %s\n", 966 device_xname(sc->sc_dev), usbd_errstr(err)); 967 } 968 sc->sc_ep[UPL_ENDPT_TX] = NULL; 969 } 970 971 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 972 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 973 if (err) { 974 printf("%s: close intr pipe failed: %s\n", 975 device_xname(sc->sc_dev), usbd_errstr(err)); 976 } 977 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 978 } 979 980 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 981 } 982 983 Static int 984 upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 985 const struct rtentry *rt0) 986 { 987 int error; 988 989 DPRINTFN(10,("%s: %s: enter\n", 990 device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev), 991 __func__)); 992 993 /* 994 * if the queueing discipline needs packet classification, 995 * do it now. 996 */ 997 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 998 999 /* 1000 * Queue message on interface, and start output if interface 1001 * not yet active. 1002 */ 1003 error = if_transmit_lock(ifp, m); 1004 1005 return error; 1006 } 1007 1008 Static void 1009 upl_input(struct ifnet *ifp, struct mbuf *m) 1010 { 1011 #ifdef INET 1012 size_t pktlen = m->m_len; 1013 int s; 1014 1015 s = splnet(); 1016 if (__predict_false(!pktq_enqueue(ip_pktq, m, 0))) { 1017 ifp->if_iqdrops++; 1018 m_freem(m); 1019 } else { 1020 ifp->if_ipackets++; 1021 ifp->if_ibytes += pktlen; 1022 } 1023 splx(s); 1024 #endif 1025 } 1026