1 /* $NetBSD: if_upl.c,v 1.57 2016/11/25 12:56:29 skrll 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.57 2016/11/25 12:56:29 skrll 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 ifp->if_ipackets++; 520 m->m_pkthdr.len = m->m_len = total_len; 521 522 m_set_rcvif(m, ifp); 523 524 s = splnet(); 525 526 /* XXX ugly */ 527 if (upl_newbuf(sc, c, NULL) == ENOBUFS) { 528 ifp->if_ierrors++; 529 goto done1; 530 } 531 532 /* 533 * Handle BPF listeners. Let the BPF user see the packet, but 534 * don't pass it up to the ether_input() layer unless it's 535 * a broadcast packet, multicast packet, matches our ethernet 536 * address or the interface is in promiscuous mode. 537 */ 538 bpf_mtap(ifp, m); 539 540 DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev), 541 __func__, m->m_len)); 542 543 if_input((ifp), (m)); 544 545 done1: 546 splx(s); 547 548 done: 549 #if 1 550 /* Setup new transfer. */ 551 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, 552 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upl_rxeof); 553 usbd_transfer(c->upl_xfer); 554 555 DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), 556 __func__)); 557 #endif 558 } 559 560 /* 561 * A frame was downloaded to the chip. It's safe for us to clean up 562 * the list buffers. 563 */ 564 Static void 565 upl_txeof(struct usbd_xfer *xfer, void *priv, 566 usbd_status status) 567 { 568 struct upl_chain *c = priv; 569 struct upl_softc *sc = c->upl_sc; 570 struct ifnet *ifp = &sc->sc_if; 571 int s; 572 573 if (sc->sc_dying) 574 return; 575 576 s = splnet(); 577 578 DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev), 579 __func__, status)); 580 581 ifp->if_timer = 0; 582 ifp->if_flags &= ~IFF_OACTIVE; 583 584 if (status != USBD_NORMAL_COMPLETION) { 585 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 586 splx(s); 587 return; 588 } 589 ifp->if_oerrors++; 590 printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev), 591 usbd_errstr(status)); 592 if (status == USBD_STALLED) 593 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]); 594 splx(s); 595 return; 596 } 597 598 ifp->if_opackets++; 599 600 m_freem(c->upl_mbuf); 601 c->upl_mbuf = NULL; 602 603 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 604 upl_start(ifp); 605 606 splx(s); 607 } 608 609 Static int 610 upl_send(struct upl_softc *sc, struct mbuf *m, int idx) 611 { 612 int total_len; 613 struct upl_chain *c; 614 usbd_status err; 615 616 c = &sc->sc_cdata.upl_tx_chain[idx]; 617 618 /* 619 * Copy the mbuf data into a contiguous buffer, leaving two 620 * bytes at the beginning to hold the frame length. 621 */ 622 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf); 623 c->upl_mbuf = m; 624 625 total_len = m->m_pkthdr.len; 626 627 DPRINTFN(10,("%s: %s: total_len=%d\n", 628 device_xname(sc->sc_dev), __func__, total_len)); 629 630 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, total_len, 0, 631 USBD_DEFAULT_TIMEOUT, upl_txeof); 632 633 /* Transmit */ 634 err = usbd_transfer(c->upl_xfer); 635 if (err != USBD_IN_PROGRESS) { 636 printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), 637 usbd_errstr(err)); 638 upl_stop(sc); 639 return EIO; 640 } 641 642 sc->sc_cdata.upl_tx_cnt++; 643 644 return 0; 645 } 646 647 Static void 648 upl_start(struct ifnet *ifp) 649 { 650 struct upl_softc *sc = ifp->if_softc; 651 struct mbuf *m_head = NULL; 652 653 if (sc->sc_dying) 654 return; 655 656 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 657 658 if (ifp->if_flags & IFF_OACTIVE) 659 return; 660 661 IFQ_POLL(&ifp->if_snd, m_head); 662 if (m_head == NULL) 663 return; 664 665 if (upl_send(sc, m_head, 0)) { 666 ifp->if_flags |= IFF_OACTIVE; 667 return; 668 } 669 670 IFQ_DEQUEUE(&ifp->if_snd, m_head); 671 672 /* 673 * If there's a BPF listener, bounce a copy of this frame 674 * to him. 675 */ 676 bpf_mtap(ifp, m_head); 677 678 ifp->if_flags |= IFF_OACTIVE; 679 680 /* 681 * Set a timeout in case the chip goes out to lunch. 682 */ 683 ifp->if_timer = 5; 684 } 685 686 Static void 687 upl_init(void *xsc) 688 { 689 struct upl_softc *sc = xsc; 690 struct ifnet *ifp = &sc->sc_if; 691 int s; 692 693 if (sc->sc_dying) 694 return; 695 696 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 697 698 if (ifp->if_flags & IFF_RUNNING) 699 return; 700 701 s = splnet(); 702 703 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { 704 if (upl_openpipes(sc)) { 705 splx(s); 706 return; 707 } 708 } 709 /* Init TX ring. */ 710 if (upl_tx_list_init(sc)) { 711 printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); 712 splx(s); 713 return; 714 } 715 716 /* Init RX ring. */ 717 if (upl_rx_list_init(sc)) { 718 printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); 719 splx(s); 720 return; 721 } 722 723 /* Start up the receive pipe. */ 724 for (int i = 0; i < UPL_RX_LIST_CNT; i++) { 725 struct upl_chain *c = &sc->sc_cdata.upl_rx_chain[i]; 726 usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, 727 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 728 upl_rxeof); 729 usbd_transfer(c->upl_xfer); 730 } 731 732 ifp->if_flags |= IFF_RUNNING; 733 ifp->if_flags &= ~IFF_OACTIVE; 734 735 splx(s); 736 } 737 738 Static int 739 upl_openpipes(struct upl_softc *sc) 740 { 741 usbd_status err; 742 743 /* Open RX and TX pipes. */ 744 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], 745 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]); 746 if (err) { 747 printf("%s: open rx pipe failed: %s\n", 748 device_xname(sc->sc_dev), usbd_errstr(err)); 749 return EIO; 750 } 751 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], 752 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); 753 if (err) { 754 printf("%s: open tx pipe failed: %s\n", 755 device_xname(sc->sc_dev), usbd_errstr(err)); 756 return EIO; 757 } 758 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], 759 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, 760 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr, 761 UPL_INTR_INTERVAL); 762 if (err) { 763 printf("%s: open intr pipe failed: %s\n", 764 device_xname(sc->sc_dev), usbd_errstr(err)); 765 return EIO; 766 } 767 768 return 0; 769 } 770 771 Static void 772 upl_intr(struct usbd_xfer *xfer, void *priv, 773 usbd_status status) 774 { 775 struct upl_softc *sc = priv; 776 struct ifnet *ifp = &sc->sc_if; 777 uByte stat; 778 779 DPRINTFN(15,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 780 781 if (sc->sc_dying) 782 return; 783 784 if (!(ifp->if_flags & IFF_RUNNING)) 785 return; 786 787 if (status != USBD_NORMAL_COMPLETION) { 788 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 789 return; 790 } 791 sc->sc_intr_errs++; 792 if (usbd_ratecheck(&sc->sc_rx_notice)) { 793 printf("%s: %u usb errors on intr: %s\n", 794 device_xname(sc->sc_dev), sc->sc_rx_errs, 795 usbd_errstr(status)); 796 sc->sc_intr_errs = 0; 797 } 798 if (status == USBD_STALLED) 799 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]); 800 return; 801 } 802 803 stat = sc->sc_ibuf; 804 805 if (stat == 0) 806 return; 807 808 DPRINTFN(10,("%s: %s: stat=0x%02x\n", device_xname(sc->sc_dev), 809 __func__, stat)); 810 811 } 812 813 Static int 814 upl_ioctl(struct ifnet *ifp, u_long command, void *data) 815 { 816 struct upl_softc *sc = ifp->if_softc; 817 struct ifaddr *ifa = (struct ifaddr *)data; 818 struct ifreq *ifr = (struct ifreq *)data; 819 int s, error = 0; 820 821 if (sc->sc_dying) 822 return EIO; 823 824 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", 825 device_xname(sc->sc_dev), __func__, command)); 826 827 s = splnet(); 828 829 switch(command) { 830 case SIOCINITIFADDR: 831 ifp->if_flags |= IFF_UP; 832 upl_init(sc); 833 834 switch (ifa->ifa_addr->sa_family) { 835 #ifdef INET 836 case AF_INET: 837 break; 838 #endif /* INET */ 839 } 840 break; 841 842 case SIOCSIFMTU: 843 if (ifr->ifr_mtu > UPL_BUFSZ) 844 error = EINVAL; 845 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 846 error = 0; 847 break; 848 849 case SIOCSIFFLAGS: 850 if ((error = ifioctl_common(ifp, command, data)) != 0) 851 break; 852 /* XXX re-use ether_ioctl() */ 853 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 854 case IFF_UP: 855 upl_init(sc); 856 break; 857 case IFF_RUNNING: 858 upl_stop(sc); 859 break; 860 default: 861 break; 862 } 863 break; 864 default: 865 error = ifioctl_common(ifp, command, data); 866 break; 867 } 868 869 splx(s); 870 871 return error; 872 } 873 874 Static void 875 upl_watchdog(struct ifnet *ifp) 876 { 877 struct upl_softc *sc = ifp->if_softc; 878 879 DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 880 881 if (sc->sc_dying) 882 return; 883 884 ifp->if_oerrors++; 885 printf("%s: watchdog timeout\n", device_xname(sc->sc_dev)); 886 887 upl_stop(sc); 888 upl_init(sc); 889 890 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 891 upl_start(ifp); 892 } 893 894 /* 895 * Stop the adapter and free any mbufs allocated to the 896 * RX and TX lists. 897 */ 898 Static void 899 upl_stop(struct upl_softc *sc) 900 { 901 usbd_status err; 902 struct ifnet *ifp; 903 int i; 904 905 DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); 906 907 ifp = &sc->sc_if; 908 ifp->if_timer = 0; 909 910 /* Stop transfers. */ 911 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 912 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]); 913 if (err) { 914 printf("%s: abort rx pipe failed: %s\n", 915 device_xname(sc->sc_dev), usbd_errstr(err)); 916 } 917 } 918 919 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 920 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]); 921 if (err) { 922 printf("%s: abort tx pipe failed: %s\n", 923 device_xname(sc->sc_dev), usbd_errstr(err)); 924 } 925 } 926 927 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 928 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 929 if (err) { 930 printf("%s: abort intr pipe failed: %s\n", 931 device_xname(sc->sc_dev), usbd_errstr(err)); 932 } 933 } 934 935 /* Free RX resources. */ 936 for (i = 0; i < UPL_RX_LIST_CNT; i++) { 937 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) { 938 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); 939 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; 940 } 941 } 942 943 /* Free TX resources. */ 944 for (i = 0; i < UPL_TX_LIST_CNT; i++) { 945 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) { 946 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf); 947 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; 948 } 949 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { 950 usbd_destroy_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); 951 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; 952 } 953 } 954 955 /* Close pipes */ 956 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { 957 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); 958 if (err) { 959 printf("%s: close rx pipe failed: %s\n", 960 device_xname(sc->sc_dev), usbd_errstr(err)); 961 } 962 sc->sc_ep[UPL_ENDPT_RX] = NULL; 963 } 964 965 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { 966 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); 967 if (err) { 968 printf("%s: close tx pipe failed: %s\n", 969 device_xname(sc->sc_dev), usbd_errstr(err)); 970 } 971 sc->sc_ep[UPL_ENDPT_TX] = NULL; 972 } 973 974 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { 975 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); 976 if (err) { 977 printf("%s: close intr pipe failed: %s\n", 978 device_xname(sc->sc_dev), usbd_errstr(err)); 979 } 980 sc->sc_ep[UPL_ENDPT_INTR] = NULL; 981 } 982 983 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 984 } 985 986 Static int 987 upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 988 const struct rtentry *rt0) 989 { 990 int error; 991 992 DPRINTFN(10,("%s: %s: enter\n", 993 device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev), 994 __func__)); 995 996 /* 997 * if the queueing discipline needs packet classification, 998 * do it now. 999 */ 1000 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 1001 1002 /* 1003 * Queue message on interface, and start output if interface 1004 * not yet active. 1005 */ 1006 error = if_transmit_lock(ifp, m); 1007 1008 return error; 1009 } 1010 1011 Static void 1012 upl_input(struct ifnet *ifp, struct mbuf *m) 1013 { 1014 #ifdef INET 1015 size_t pktlen = m->m_len; 1016 int s; 1017 1018 s = splnet(); 1019 if (__predict_false(!pktq_enqueue(ip_pktq, m, 0))) { 1020 ifp->if_iqdrops++; 1021 m_freem(m); 1022 } else { 1023 ifp->if_ipackets++; 1024 ifp->if_ibytes += pktlen; 1025 } 1026 splx(s); 1027 #endif 1028 } 1029