The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/if_aue.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_aue.c,v 1.85 2004/01/05 13:36:24 augustss Exp $     */
    2 /*
    3  * Copyright (c) 1997, 1998, 1999, 2000
    4  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Bill Paul.
   17  * 4. Neither the name of the author nor the names of any co-contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   31  * THE POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $
   34  */
   35 
   36 /*
   37  * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
   38  * Datasheet is available from http://www.admtek.com.tw.
   39  *
   40  * Written by Bill Paul <wpaul@ee.columbia.edu>
   41  * Electrical Engineering Department
   42  * Columbia University, New York City
   43  */
   44 
   45 /*
   46  * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet
   47  * support: the control endpoint for reading/writing registers, burst
   48  * read endpoint for packet reception, burst write for packet transmission
   49  * and one for "interrupts." The chip uses the same RX filter scheme
   50  * as the other ADMtek ethernet parts: one perfect filter entry for the
   51  * the station address and a 64-bit multicast hash table. The chip supports
   52  * both MII and HomePNA attachments.
   53  *
   54  * Since the maximum data transfer speed of USB is supposed to be 12Mbps,
   55  * you're never really going to get 100Mbps speeds from this device. I
   56  * think the idea is to allow the device to connect to 10 or 100Mbps
   57  * networks, not necessarily to provide 100Mbps performance. Also, since
   58  * the controller uses an external PHY chip, it's possible that board
   59  * designers might simply choose a 10Mbps PHY.
   60  *
   61  * Registers are accessed using usbd_do_request(). Packet transfers are
   62  * done using usbd_transfer() and friends.
   63  */
   64 
   65 /*
   66  * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
   67  */
   68 
   69 /*
   70  * TODO:
   71  * better error messages from rxstat
   72  * split out if_auevar.h
   73  * add thread to avoid register reads from interrupt context
   74  * more error checks
   75  * investigate short rx problem
   76  * proper cleanup on errors
   77  */
   78 
   79 #include <sys/cdefs.h>
   80 __KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.85 2004/01/05 13:36:24 augustss Exp $");
   81 
   82 #if defined(__NetBSD__)
   83 #include "opt_inet.h"
   84 #include "opt_ns.h"
   85 #include "bpfilter.h"
   86 #include "rnd.h"
   87 #elif defined(__OpenBSD__)
   88 #include "bpfilter.h"
   89 #endif /* defined(__OpenBSD__) */
   90 
   91 #include <sys/param.h>
   92 #include <sys/systm.h>
   93 #include <sys/sockio.h>
   94 #include <sys/lock.h>
   95 #include <sys/mbuf.h>
   96 #include <sys/malloc.h>
   97 #include <sys/kernel.h>
   98 #include <sys/socket.h>
   99 
  100 #include <sys/device.h>
  101 #if NRND > 0
  102 #include <sys/rnd.h>
  103 #endif
  104 
  105 #include <net/if.h>
  106 #if defined(__NetBSD__)
  107 #include <net/if_arp.h>
  108 #endif
  109 #include <net/if_dl.h>
  110 #include <net/if_media.h>
  111 
  112 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
  113 
  114 #if NBPFILTER > 0
  115 #include <net/bpf.h>
  116 #endif
  117 
  118 #if defined(__NetBSD__)
  119 #include <net/if_ether.h>
  120 #ifdef INET
  121 #include <netinet/in.h>
  122 #include <netinet/if_inarp.h>
  123 #endif
  124 #endif /* defined(__NetBSD__) */
  125 
  126 #if defined(__OpenBSD__)
  127 #ifdef INET
  128 #include <netinet/in.h>
  129 #include <netinet/in_systm.h>
  130 #include <netinet/in_var.h>
  131 #include <netinet/ip.h>
  132 #include <netinet/if_ether.h>
  133 #endif
  134 #endif /* defined(__OpenBSD__) */
  135 
  136 #ifdef NS
  137 #include <netns/ns.h>
  138 #include <netns/ns_if.h>
  139 #endif
  140 
  141 #include <dev/mii/mii.h>
  142 #include <dev/mii/miivar.h>
  143 
  144 #include <dev/usb/usb.h>
  145 #include <dev/usb/usbdi.h>
  146 #include <dev/usb/usbdi_util.h>
  147 #include <dev/usb/usbdevs.h>
  148 
  149 #include <dev/usb/if_auereg.h>
  150 
  151 #ifdef AUE_DEBUG
  152 #define DPRINTF(x)      if (auedebug) logprintf x
  153 #define DPRINTFN(n,x)   if (auedebug >= (n)) logprintf x
  154 int     auedebug = 0;
  155 #else
  156 #define DPRINTF(x)
  157 #define DPRINTFN(n,x)
  158 #endif
  159 
  160 /*
  161  * Various supported device vendors/products.
  162  */
  163 struct aue_type {
  164         struct usb_devno        aue_dev;
  165         u_int16_t               aue_flags;
  166 #define LSYS    0x0001          /* use Linksys reset */
  167 #define PNA     0x0002          /* has Home PNA */
  168 #define PII     0x0004          /* Pegasus II chip */
  169 };
  170 
  171 Static const struct aue_type aue_devs[] = {
  172  {{ USB_VENDOR_3COM,            USB_PRODUCT_3COM_3C460B},         PII },
  173  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX1},          PNA|PII },
  174  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX2},          PII },
  175  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_UFE1000},      LSYS },
  176  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX4},          PNA },
  177  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX5},          PNA },
  178  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX6},          PII },
  179  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX7},          PII },
  180  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX8},          PII },
  181  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX9},          PNA },
  182  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_XX10},         0 },
  183  {{ USB_VENDOR_ABOCOM,          USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 },
  184  {{ USB_VENDOR_ACCTON,          USB_PRODUCT_ACCTON_USB320_EC},    0 },
  185  {{ USB_VENDOR_ACCTON,          USB_PRODUCT_ACCTON_SS1001},       PII },
  186  {{ USB_VENDOR_ADMTEK,          USB_PRODUCT_ADMTEK_PEGASUS},      PNA },
  187  {{ USB_VENDOR_ADMTEK,          USB_PRODUCT_ADMTEK_PEGASUSII},    PII },
  188  {{ USB_VENDOR_BELKIN,          USB_PRODUCT_BELKIN_USB2LAN},      PII },
  189  {{ USB_VENDOR_BILLIONTON,      USB_PRODUCT_BILLIONTON_USB100},   0 },
  190  {{ USB_VENDOR_BILLIONTON,      USB_PRODUCT_BILLIONTON_USBLP100}, PNA },
  191  {{ USB_VENDOR_BILLIONTON,      USB_PRODUCT_BILLIONTON_USBEL100}, 0 },
  192  {{ USB_VENDOR_BILLIONTON,      USB_PRODUCT_BILLIONTON_USBE100},  PII },
  193  {{ USB_VENDOR_COMPAQ,          USB_PRODUCT_COMPAQ_HNE200},       PII },
  194  {{ USB_VENDOR_COREGA,          USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 },
  195  {{ USB_VENDOR_COREGA,          USB_PRODUCT_COREGA_FETHER_USB_TXS},PII },
  196  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX4},     LSYS|PII },
  197  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX1},     LSYS },
  198  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX},      LSYS },
  199  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX_PNA},  PNA },
  200  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX3},     LSYS|PII },
  201  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650TX2},     LSYS|PII },
  202  {{ USB_VENDOR_DLINK,           USB_PRODUCT_DLINK_DSB650},        0 },
  203  {{ USB_VENDOR_ELECOM,          USB_PRODUCT_ELECOM_LDUSBTX0},     0 },
  204  {{ USB_VENDOR_ELECOM,          USB_PRODUCT_ELECOM_LDUSBTX1},     LSYS },
  205  {{ USB_VENDOR_ELECOM,          USB_PRODUCT_ELECOM_LDUSBTX2},     0 },
  206  {{ USB_VENDOR_ELECOM,          USB_PRODUCT_ELECOM_LDUSBTX3},     LSYS },
  207  {{ USB_VENDOR_ELECOM,          USB_PRODUCT_ELECOM_LDUSBLTX},     PII },
  208  {{ USB_VENDOR_ELSA,            USB_PRODUCT_ELSA_USB2ETHERNET},   0 },
  209  {{ USB_VENDOR_HAWKING,         USB_PRODUCT_HAWKING_UF100},       PII },
  210  {{ USB_VENDOR_HP,              USB_PRODUCT_HP_HN210E},           PII },
  211  {{ USB_VENDOR_IODATA,          USB_PRODUCT_IODATA_USBETTX},      0 },
  212  {{ USB_VENDOR_IODATA,          USB_PRODUCT_IODATA_USBETTXS},     PII },
  213  {{ USB_VENDOR_KINGSTON,        USB_PRODUCT_KINGSTON_KNU101TX},   0 },
  214  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB10TX1},    LSYS|PII },
  215  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB10T},      LSYS },
  216  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB100TX},    LSYS },
  217  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB100H1},    LSYS|PNA },
  218  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB10TA},     LSYS },
  219  {{ USB_VENDOR_LINKSYS,         USB_PRODUCT_LINKSYS_USB10TX2},    LSYS|PII },
  220  {{ USB_VENDOR_MELCO,           USB_PRODUCT_MELCO_LUATX1},        0 },
  221  {{ USB_VENDOR_MELCO,           USB_PRODUCT_MELCO_LUATX5},        0 },
  222  {{ USB_VENDOR_MELCO,           USB_PRODUCT_MELCO_LUA2TX5},       PII },
  223  {{ USB_VENDOR_MICROSOFT,       USB_PRODUCT_MICROSOFT_MN110},     PII },
  224  {{ USB_VENDOR_NETGEAR,         USB_PRODUCT_NETGEAR_FA101},       PII },
  225  {{ USB_VENDOR_SIEMENS,         USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII },
  226  {{ USB_VENDOR_SMARTBRIDGES,    USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII },
  227  {{ USB_VENDOR_SMC,             USB_PRODUCT_SMC_2202USB},         0 },
  228  {{ USB_VENDOR_SMC,             USB_PRODUCT_SMC_2206USB},         PII },
  229  {{ USB_VENDOR_SOHOWARE,        USB_PRODUCT_SOHOWARE_NUB100},     0 },
  230 };
  231 #define aue_lookup(v, p) ((struct aue_type *)usb_lookup(aue_devs, v, p))
  232 
  233 USB_DECLARE_DRIVER(aue);
  234 
  235 Static void aue_reset_pegasus_II(struct aue_softc *sc);
  236 Static int aue_tx_list_init(struct aue_softc *);
  237 Static int aue_rx_list_init(struct aue_softc *);
  238 Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *);
  239 Static int aue_send(struct aue_softc *, struct mbuf *, int);
  240 Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
  241 Static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  242 Static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
  243 Static void aue_tick(void *);
  244 Static void aue_tick_task(void *);
  245 Static void aue_start(struct ifnet *);
  246 Static int aue_ioctl(struct ifnet *, u_long, caddr_t);
  247 Static void aue_init(void *);
  248 Static void aue_stop(struct aue_softc *);
  249 Static void aue_watchdog(struct ifnet *);
  250 Static int aue_openpipes(struct aue_softc *);
  251 Static int aue_ifmedia_upd(struct ifnet *);
  252 Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  253 
  254 Static int aue_eeprom_getword(struct aue_softc *, int);
  255 Static void aue_read_mac(struct aue_softc *, u_char *);
  256 Static int aue_miibus_readreg(device_ptr_t, int, int);
  257 Static void aue_miibus_writereg(device_ptr_t, int, int, int);
  258 Static void aue_miibus_statchg(device_ptr_t);
  259 
  260 Static void aue_lock_mii(struct aue_softc *);
  261 Static void aue_unlock_mii(struct aue_softc *);
  262 
  263 Static void aue_setmulti(struct aue_softc *);
  264 Static u_int32_t aue_crc(caddr_t);
  265 Static void aue_reset(struct aue_softc *);
  266 
  267 Static int aue_csr_read_1(struct aue_softc *, int);
  268 Static int aue_csr_write_1(struct aue_softc *, int, int);
  269 Static int aue_csr_read_2(struct aue_softc *, int);
  270 Static int aue_csr_write_2(struct aue_softc *, int, int);
  271 
  272 #define AUE_SETBIT(sc, reg, x)                          \
  273         aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
  274 
  275 #define AUE_CLRBIT(sc, reg, x)                          \
  276         aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
  277 
  278 Static int
  279 aue_csr_read_1(struct aue_softc *sc, int reg)
  280 {
  281         usb_device_request_t    req;
  282         usbd_status             err;
  283         uByte                   val = 0;
  284 
  285         if (sc->aue_dying)
  286                 return (0);
  287 
  288         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  289         req.bRequest = AUE_UR_READREG;
  290         USETW(req.wValue, 0);
  291         USETW(req.wIndex, reg);
  292         USETW(req.wLength, 1);
  293 
  294         err = usbd_do_request(sc->aue_udev, &req, &val);
  295 
  296         if (err) {
  297                 DPRINTF(("%s: aue_csr_read_1: reg=0x%x err=%s\n",
  298                          USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
  299                 return (0);
  300         }
  301 
  302         return (val);
  303 }
  304 
  305 Static int
  306 aue_csr_read_2(struct aue_softc *sc, int reg)
  307 {
  308         usb_device_request_t    req;
  309         usbd_status             err;
  310         uWord                   val;
  311 
  312         if (sc->aue_dying)
  313                 return (0);
  314 
  315         req.bmRequestType = UT_READ_VENDOR_DEVICE;
  316         req.bRequest = AUE_UR_READREG;
  317         USETW(req.wValue, 0);
  318         USETW(req.wIndex, reg);
  319         USETW(req.wLength, 2);
  320 
  321         err = usbd_do_request(sc->aue_udev, &req, &val);
  322 
  323         if (err) {
  324                 DPRINTF(("%s: aue_csr_read_2: reg=0x%x err=%s\n",
  325                          USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
  326                 return (0);
  327         }
  328 
  329         return (UGETW(val));
  330 }
  331 
  332 Static int
  333 aue_csr_write_1(struct aue_softc *sc, int reg, int aval)
  334 {
  335         usb_device_request_t    req;
  336         usbd_status             err;
  337         uByte                   val;
  338 
  339         if (sc->aue_dying)
  340                 return (0);
  341 
  342         val = aval;
  343         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  344         req.bRequest = AUE_UR_WRITEREG;
  345         USETW(req.wValue, val);
  346         USETW(req.wIndex, reg);
  347         USETW(req.wLength, 1);
  348 
  349         err = usbd_do_request(sc->aue_udev, &req, &val);
  350 
  351         if (err) {
  352                 DPRINTF(("%s: aue_csr_write_1: reg=0x%x err=%s\n",
  353                          USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
  354                 return (-1);
  355         }
  356 
  357         return (0);
  358 }
  359 
  360 Static int
  361 aue_csr_write_2(struct aue_softc *sc, int reg, int aval)
  362 {
  363         usb_device_request_t    req;
  364         usbd_status             err;
  365         uWord                   val;
  366 
  367         if (sc->aue_dying)
  368                 return (0);
  369 
  370         USETW(val, aval);
  371         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
  372         req.bRequest = AUE_UR_WRITEREG;
  373         USETW(req.wValue, aval);
  374         USETW(req.wIndex, reg);
  375         USETW(req.wLength, 2);
  376 
  377         err = usbd_do_request(sc->aue_udev, &req, &val);
  378 
  379         if (err) {
  380                 DPRINTF(("%s: aue_csr_write_2: reg=0x%x err=%s\n",
  381                          USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
  382                 return (-1);
  383         }
  384 
  385         return (0);
  386 }
  387 
  388 /*
  389  * Read a word of data stored in the EEPROM at address 'addr.'
  390  */
  391 Static int
  392 aue_eeprom_getword(struct aue_softc *sc, int addr)
  393 {
  394         int             i;
  395 
  396         aue_csr_write_1(sc, AUE_EE_REG, addr);
  397         aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
  398 
  399         for (i = 0; i < AUE_TIMEOUT; i++) {
  400                 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
  401                         break;
  402         }
  403 
  404         if (i == AUE_TIMEOUT) {
  405                 printf("%s: EEPROM read timed out\n",
  406                     USBDEVNAME(sc->aue_dev));
  407         }
  408 
  409         return (aue_csr_read_2(sc, AUE_EE_DATA));
  410 }
  411 
  412 /*
  413  * Read the MAC from the EEPROM.  It's at offset 0.
  414  */
  415 Static void
  416 aue_read_mac(struct aue_softc *sc, u_char *dest)
  417 {
  418         int                     i;
  419         int                     off = 0;
  420         int                     word;
  421 
  422         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  423 
  424         for (i = 0; i < 3; i++) {
  425                 word = aue_eeprom_getword(sc, off + i);
  426                 dest[2 * i] = (u_char)word;
  427                 dest[2 * i + 1] = (u_char)(word >> 8);
  428         }
  429 }
  430 
  431 /* Get exclusive access to the MII registers */
  432 Static void
  433 aue_lock_mii(struct aue_softc *sc)
  434 {
  435         sc->aue_refcnt++;
  436         lockmgr(&sc->aue_mii_lock, LK_EXCLUSIVE, NULL);
  437 }
  438 
  439 Static void
  440 aue_unlock_mii(struct aue_softc *sc)
  441 {
  442         lockmgr(&sc->aue_mii_lock, LK_RELEASE, NULL);
  443         if (--sc->aue_refcnt < 0)
  444                 usb_detach_wakeup(USBDEV(sc->aue_dev));
  445 }
  446 
  447 Static int
  448 aue_miibus_readreg(device_ptr_t dev, int phy, int reg)
  449 {
  450         struct aue_softc        *sc = USBGETSOFTC(dev);
  451         int                     i;
  452         u_int16_t               val;
  453 
  454         if (sc->aue_dying) {
  455 #ifdef DIAGNOSTIC
  456                 printf("%s: dying\n", USBDEVNAME(sc->aue_dev));
  457 #endif
  458                 return 0;
  459         }
  460 
  461 #if 0
  462         /*
  463          * The Am79C901 HomePNA PHY actually contains
  464          * two transceivers: a 1Mbps HomePNA PHY and a
  465          * 10Mbps full/half duplex ethernet PHY with
  466          * NWAY autoneg. However in the ADMtek adapter,
  467          * only the 1Mbps PHY is actually connected to
  468          * anything, so we ignore the 10Mbps one. It
  469          * happens to be configured for MII address 3,
  470          * so we filter that out.
  471          */
  472         if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
  473             sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
  474                 if (phy == 3)
  475                         return (0);
  476         }
  477 #endif
  478 
  479         aue_lock_mii(sc);
  480         aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
  481         aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
  482 
  483         for (i = 0; i < AUE_TIMEOUT; i++) {
  484                 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
  485                         break;
  486         }
  487 
  488         if (i == AUE_TIMEOUT) {
  489                 printf("%s: MII read timed out\n", USBDEVNAME(sc->aue_dev));
  490         }
  491 
  492         val = aue_csr_read_2(sc, AUE_PHY_DATA);
  493 
  494         DPRINTFN(11,("%s: %s: phy=%d reg=%d => 0x%04x\n",
  495                      USBDEVNAME(sc->aue_dev), __func__, phy, reg, val));
  496 
  497         aue_unlock_mii(sc);
  498         return (val);
  499 }
  500 
  501 Static void
  502 aue_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
  503 {
  504         struct aue_softc        *sc = USBGETSOFTC(dev);
  505         int                     i;
  506 
  507 #if 0
  508         if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
  509             sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
  510                 if (phy == 3)
  511                         return;
  512         }
  513 #endif
  514 
  515         DPRINTFN(11,("%s: %s: phy=%d reg=%d data=0x%04x\n",
  516                      USBDEVNAME(sc->aue_dev), __func__, phy, reg, data));
  517 
  518         aue_lock_mii(sc);
  519         aue_csr_write_2(sc, AUE_PHY_DATA, data);
  520         aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
  521         aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
  522 
  523         for (i = 0; i < AUE_TIMEOUT; i++) {
  524                 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
  525                         break;
  526         }
  527 
  528         if (i == AUE_TIMEOUT) {
  529                 printf("%s: MII read timed out\n",
  530                     USBDEVNAME(sc->aue_dev));
  531         }
  532         aue_unlock_mii(sc);
  533 }
  534 
  535 Static void
  536 aue_miibus_statchg(device_ptr_t dev)
  537 {
  538         struct aue_softc        *sc = USBGETSOFTC(dev);
  539         struct mii_data         *mii = GET_MII(sc);
  540 
  541         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  542 
  543         aue_lock_mii(sc);
  544         AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
  545 
  546         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
  547                 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
  548         } else {
  549                 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
  550         }
  551 
  552         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
  553                 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
  554         else
  555                 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
  556 
  557         AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
  558         aue_unlock_mii(sc);
  559 
  560         /*
  561          * Set the LED modes on the LinkSys adapter.
  562          * This turns on the 'dual link LED' bin in the auxmode
  563          * register of the Broadcom PHY.
  564          */
  565         if (!sc->aue_dying && (sc->aue_flags & LSYS)) {
  566                 u_int16_t auxmode;
  567                 auxmode = aue_miibus_readreg(dev, 0, 0x1b);
  568                 aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
  569         }
  570         DPRINTFN(5,("%s: %s: exit\n", USBDEVNAME(sc->aue_dev), __func__));
  571 }
  572 
  573 #define AUE_POLY        0xEDB88320
  574 #define AUE_BITS        6
  575 
  576 Static u_int32_t
  577 aue_crc(caddr_t addr)
  578 {
  579         u_int32_t               idx, bit, data, crc;
  580 
  581         /* Compute CRC for the address value. */
  582         crc = 0xFFFFFFFF; /* initial value */
  583 
  584         for (idx = 0; idx < 6; idx++) {
  585                 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
  586                         crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0);
  587         }
  588 
  589         return (crc & ((1 << AUE_BITS) - 1));
  590 }
  591 
  592 Static void
  593 aue_setmulti(struct aue_softc *sc)
  594 {
  595         struct ifnet            *ifp;
  596         struct ether_multi      *enm;
  597         struct ether_multistep  step;
  598         u_int32_t               h = 0, i;
  599 
  600         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  601 
  602         ifp = GET_IFP(sc);
  603 
  604         if (ifp->if_flags & IFF_PROMISC) {
  605 allmulti:
  606                 ifp->if_flags |= IFF_ALLMULTI;
  607                 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
  608                 return;
  609         }
  610 
  611         AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
  612 
  613         /* first, zot all the existing hash bits */
  614         for (i = 0; i < 8; i++)
  615                 aue_csr_write_1(sc, AUE_MAR0 + i, 0);
  616 
  617         /* now program new ones */
  618 #if defined(__NetBSD__)
  619         ETHER_FIRST_MULTI(step, &sc->aue_ec, enm);
  620 #else
  621         ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
  622 #endif
  623         while (enm != NULL) {
  624                 if (memcmp(enm->enm_addrlo,
  625                     enm->enm_addrhi, ETHER_ADDR_LEN) != 0)
  626                         goto allmulti;
  627 
  628                 h = aue_crc(enm->enm_addrlo);
  629                 AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));
  630                 ETHER_NEXT_MULTI(step, enm);
  631         }
  632 
  633         ifp->if_flags &= ~IFF_ALLMULTI;
  634 }
  635 
  636 Static void
  637 aue_reset_pegasus_II(struct aue_softc *sc)
  638 {
  639         /* Magic constants taken from Linux driver. */
  640         aue_csr_write_1(sc, AUE_REG_1D, 0);
  641         aue_csr_write_1(sc, AUE_REG_7B, 2);
  642 #if 0
  643         if ((sc->aue_flags & HAS_HOME_PNA) && mii_mode)
  644                 aue_csr_write_1(sc, AUE_REG_81, 6);
  645         else
  646 #endif
  647                 aue_csr_write_1(sc, AUE_REG_81, 2);
  648 }
  649 
  650 Static void
  651 aue_reset(struct aue_softc *sc)
  652 {
  653         int             i;
  654 
  655         DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  656 
  657         AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
  658 
  659         for (i = 0; i < AUE_TIMEOUT; i++) {
  660                 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
  661                         break;
  662         }
  663 
  664         if (i == AUE_TIMEOUT)
  665                 printf("%s: reset failed\n", USBDEVNAME(sc->aue_dev));
  666 
  667 #if 0
  668         /* XXX what is mii_mode supposed to be */
  669         if (sc->aue_mii_mode && (sc->aue_flags & PNA))
  670                 aue_csr_write_1(sc, AUE_GPIO1, 0x34);
  671         else
  672                 aue_csr_write_1(sc, AUE_GPIO1, 0x26);
  673 #endif
  674 
  675         /*
  676          * The PHY(s) attached to the Pegasus chip may be held
  677          * in reset until we flip on the GPIO outputs. Make sure
  678          * to set the GPIO pins high so that the PHY(s) will
  679          * be enabled.
  680          *
  681          * Note: We force all of the GPIO pins low first, *then*
  682          * enable the ones we want.
  683          */
  684         if (sc->aue_flags & LSYS) {
  685                 /* Grrr. LinkSys has to be different from everyone else. */
  686                 aue_csr_write_1(sc, AUE_GPIO0,
  687                     AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
  688         } else {
  689                 aue_csr_write_1(sc, AUE_GPIO0,
  690                     AUE_GPIO_OUT0 | AUE_GPIO_SEL0);
  691         }
  692         aue_csr_write_1(sc, AUE_GPIO0,
  693             AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
  694 
  695         if (sc->aue_flags & PII)
  696                 aue_reset_pegasus_II(sc);
  697 
  698         /* Wait a little while for the chip to get its brains in order. */
  699         delay(10000);           /* XXX */
  700 }
  701 
  702 /*
  703  * Probe for a Pegasus chip.
  704  */
  705 USB_MATCH(aue)
  706 {
  707         USB_MATCH_START(aue, uaa);
  708 
  709         if (uaa->iface != NULL)
  710                 return (UMATCH_NONE);
  711 
  712         return (aue_lookup(uaa->vendor, uaa->product) != NULL ?
  713                 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
  714 }
  715 
  716 /*
  717  * Attach the interface. Allocate softc structures, do ifmedia
  718  * setup and ethernet/BPF attach.
  719  */
  720 USB_ATTACH(aue)
  721 {
  722         USB_ATTACH_START(aue, sc, uaa);
  723         char                    devinfo[1024];
  724         int                     s;
  725         u_char                  eaddr[ETHER_ADDR_LEN];
  726         struct ifnet            *ifp;
  727         struct mii_data         *mii;
  728         usbd_device_handle      dev = uaa->device;
  729         usbd_interface_handle   iface;
  730         usbd_status             err;
  731         usb_interface_descriptor_t      *id;
  732         usb_endpoint_descriptor_t       *ed;
  733         int                     i;
  734 
  735         DPRINTFN(5,(" : aue_attach: sc=%p", sc));
  736 
  737         usbd_devinfo(dev, 0, devinfo);
  738         USB_ATTACH_SETUP;
  739         printf("%s: %s\n", USBDEVNAME(sc->aue_dev), devinfo);
  740 
  741         err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1);
  742         if (err) {
  743                 printf("%s: setting config no failed\n",
  744                     USBDEVNAME(sc->aue_dev));
  745                 USB_ATTACH_ERROR_RETURN;
  746         }
  747 
  748         usb_init_task(&sc->aue_tick_task, aue_tick_task, sc);
  749         usb_init_task(&sc->aue_stop_task, (void (*)(void *))aue_stop, sc);
  750         lockinit(&sc->aue_mii_lock, PZERO, "auemii", 0, 0);
  751 
  752         err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &iface);
  753         if (err) {
  754                 printf("%s: getting interface handle failed\n",
  755                     USBDEVNAME(sc->aue_dev));
  756                 USB_ATTACH_ERROR_RETURN;
  757         }
  758 
  759         sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags;
  760 
  761         sc->aue_udev = dev;
  762         sc->aue_iface = iface;
  763         sc->aue_product = uaa->product;
  764         sc->aue_vendor = uaa->vendor;
  765 
  766         id = usbd_get_interface_descriptor(iface);
  767 
  768         /* Find endpoints. */
  769         for (i = 0; i < id->bNumEndpoints; i++) {
  770                 ed = usbd_interface2endpoint_descriptor(iface, i);
  771                 if (ed == NULL) {
  772                         printf("%s: couldn't get endpoint descriptor %d\n",
  773                             USBDEVNAME(sc->aue_dev), i);
  774                         USB_ATTACH_ERROR_RETURN;
  775                 }
  776                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  777                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  778                         sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress;
  779                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
  780                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
  781                         sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress;
  782                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
  783                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
  784                         sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress;
  785                 }
  786         }
  787 
  788         if (sc->aue_ed[AUE_ENDPT_RX] == 0 || sc->aue_ed[AUE_ENDPT_TX] == 0 ||
  789             sc->aue_ed[AUE_ENDPT_INTR] == 0) {
  790                 printf("%s: missing endpoint\n", USBDEVNAME(sc->aue_dev));
  791                 USB_ATTACH_ERROR_RETURN;
  792         }
  793 
  794 
  795         s = splnet();
  796 
  797         /* Reset the adapter. */
  798         aue_reset(sc);
  799 
  800         /*
  801          * Get station address from the EEPROM.
  802          */
  803         aue_read_mac(sc, eaddr);
  804 
  805         /*
  806          * A Pegasus chip was detected. Inform the world.
  807          */
  808         ifp = GET_IFP(sc);
  809         printf("%s: Ethernet address %s\n", USBDEVNAME(sc->aue_dev),
  810             ether_sprintf(eaddr));
  811 
  812         /* Initialize interface info.*/
  813         ifp->if_softc = sc;
  814         ifp->if_mtu = ETHERMTU;
  815         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  816         ifp->if_ioctl = aue_ioctl;
  817         ifp->if_start = aue_start;
  818         ifp->if_watchdog = aue_watchdog;
  819 #if defined(__OpenBSD__)
  820         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  821 #endif
  822         strncpy(ifp->if_xname, USBDEVNAME(sc->aue_dev), IFNAMSIZ);
  823 
  824         IFQ_SET_READY(&ifp->if_snd);
  825 
  826         /* Initialize MII/media info. */
  827         mii = &sc->aue_mii;
  828         mii->mii_ifp = ifp;
  829         mii->mii_readreg = aue_miibus_readreg;
  830         mii->mii_writereg = aue_miibus_writereg;
  831         mii->mii_statchg = aue_miibus_statchg;
  832         mii->mii_flags = MIIF_AUTOTSLEEP;
  833         ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, aue_ifmedia_sts);
  834         mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
  835         if (LIST_FIRST(&mii->mii_phys) == NULL) {
  836                 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
  837                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
  838         } else
  839                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
  840 
  841         /* Attach the interface. */
  842         if_attach(ifp);
  843         Ether_ifattach(ifp, eaddr);
  844 #if NRND > 0
  845         rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->aue_dev),
  846             RND_TYPE_NET, 0);
  847 #endif
  848 
  849         usb_callout_init(sc->aue_stat_ch);
  850 
  851         sc->aue_attached = 1;
  852         splx(s);
  853 
  854         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->aue_udev,
  855                            USBDEV(sc->aue_dev));
  856 
  857         USB_ATTACH_SUCCESS_RETURN;
  858 }
  859 
  860 USB_DETACH(aue)
  861 {
  862         USB_DETACH_START(aue, sc);
  863         struct ifnet            *ifp = GET_IFP(sc);
  864         int                     s;
  865 
  866         DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  867 
  868         if (!sc->aue_attached) {
  869                 /* Detached before attached finished, so just bail out. */
  870                 return (0);
  871         }
  872 
  873         usb_uncallout(sc->aue_stat_ch, aue_tick, sc);
  874         /*
  875          * Remove any pending tasks.  They cannot be executing because they run
  876          * in the same thread as detach.
  877          */
  878         usb_rem_task(sc->aue_udev, &sc->aue_tick_task);
  879         usb_rem_task(sc->aue_udev, &sc->aue_stop_task);
  880 
  881         s = splusb();
  882 
  883         if (ifp->if_flags & IFF_RUNNING)
  884                 aue_stop(sc);
  885 
  886 #if defined(__NetBSD__)
  887 #if NRND > 0
  888         rnd_detach_source(&sc->rnd_source);
  889 #endif
  890         mii_detach(&sc->aue_mii, MII_PHY_ANY, MII_OFFSET_ANY);
  891         ifmedia_delete_instance(&sc->aue_mii.mii_media, IFM_INST_ANY);
  892         ether_ifdetach(ifp);
  893 #endif /* __NetBSD__ */
  894 
  895         if_detach(ifp);
  896 
  897 #ifdef DIAGNOSTIC
  898         if (sc->aue_ep[AUE_ENDPT_TX] != NULL ||
  899             sc->aue_ep[AUE_ENDPT_RX] != NULL ||
  900             sc->aue_ep[AUE_ENDPT_INTR] != NULL)
  901                 printf("%s: detach has active endpoints\n",
  902                        USBDEVNAME(sc->aue_dev));
  903 #endif
  904 
  905         sc->aue_attached = 0;
  906 
  907         if (--sc->aue_refcnt >= 0) {
  908                 /* Wait for processes to go away. */
  909                 usb_detach_wait(USBDEV(sc->aue_dev));
  910         }
  911         splx(s);
  912 
  913         usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->aue_udev,
  914                            USBDEV(sc->aue_dev));
  915 
  916         return (0);
  917 }
  918 
  919 int
  920 aue_activate(device_ptr_t self, enum devact act)
  921 {
  922         struct aue_softc *sc = (struct aue_softc *)self;
  923 
  924         DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  925 
  926         switch (act) {
  927         case DVACT_ACTIVATE:
  928                 return (EOPNOTSUPP);
  929                 break;
  930 
  931         case DVACT_DEACTIVATE:
  932                 if_deactivate(&sc->aue_ec.ec_if);
  933                 sc->aue_dying = 1;
  934                 break;
  935         }
  936         return (0);
  937 }
  938 
  939 /*
  940  * Initialize an RX descriptor and attach an MBUF cluster.
  941  */
  942 Static int
  943 aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m)
  944 {
  945         struct mbuf             *m_new = NULL;
  946 
  947         DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
  948 
  949         if (m == NULL) {
  950                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
  951                 if (m_new == NULL) {
  952                         printf("%s: no memory for rx list "
  953                             "-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
  954                         return (ENOBUFS);
  955                 }
  956 
  957                 MCLGET(m_new, M_DONTWAIT);
  958                 if (!(m_new->m_flags & M_EXT)) {
  959                         printf("%s: no memory for rx list "
  960                             "-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
  961                         m_freem(m_new);
  962                         return (ENOBUFS);
  963                 }
  964                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  965         } else {
  966                 m_new = m;
  967                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  968                 m_new->m_data = m_new->m_ext.ext_buf;
  969         }
  970 
  971         m_adj(m_new, ETHER_ALIGN);
  972         c->aue_mbuf = m_new;
  973 
  974         return (0);
  975 }
  976 
  977 Static int
  978 aue_rx_list_init(struct aue_softc *sc)
  979 {
  980         struct aue_cdata        *cd;
  981         struct aue_chain        *c;
  982         int                     i;
  983 
  984         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
  985 
  986         cd = &sc->aue_cdata;
  987         for (i = 0; i < AUE_RX_LIST_CNT; i++) {
  988                 c = &cd->aue_rx_chain[i];
  989                 c->aue_sc = sc;
  990                 c->aue_idx = i;
  991                 if (aue_newbuf(sc, c, NULL) == ENOBUFS)
  992                         return (ENOBUFS);
  993                 if (c->aue_xfer == NULL) {
  994                         c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
  995                         if (c->aue_xfer == NULL)
  996                                 return (ENOBUFS);
  997                         c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ);
  998                         if (c->aue_buf == NULL)
  999                                 return (ENOBUFS); /* XXX free xfer */
 1000                 }
 1001         }
 1002 
 1003         return (0);
 1004 }
 1005 
 1006 Static int
 1007 aue_tx_list_init(struct aue_softc *sc)
 1008 {
 1009         struct aue_cdata        *cd;
 1010         struct aue_chain        *c;
 1011         int                     i;
 1012 
 1013         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1014 
 1015         cd = &sc->aue_cdata;
 1016         for (i = 0; i < AUE_TX_LIST_CNT; i++) {
 1017                 c = &cd->aue_tx_chain[i];
 1018                 c->aue_sc = sc;
 1019                 c->aue_idx = i;
 1020                 c->aue_mbuf = NULL;
 1021                 if (c->aue_xfer == NULL) {
 1022                         c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
 1023                         if (c->aue_xfer == NULL)
 1024                                 return (ENOBUFS);
 1025                         c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ);
 1026                         if (c->aue_buf == NULL)
 1027                                 return (ENOBUFS);
 1028                 }
 1029         }
 1030 
 1031         return (0);
 1032 }
 1033 
 1034 Static void
 1035 aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 1036 {
 1037         struct aue_softc        *sc = priv;
 1038         struct ifnet            *ifp = GET_IFP(sc);
 1039         struct aue_intrpkt      *p = &sc->aue_cdata.aue_ibuf;
 1040 
 1041         DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
 1042 
 1043         if (sc->aue_dying)
 1044                 return;
 1045 
 1046         if (!(ifp->if_flags & IFF_RUNNING))
 1047                 return;
 1048 
 1049         if (status != USBD_NORMAL_COMPLETION) {
 1050                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
 1051                         return;
 1052                 }
 1053                 sc->aue_intr_errs++;
 1054                 if (usbd_ratecheck(&sc->aue_rx_notice)) {
 1055                         printf("%s: %u usb errors on intr: %s\n",
 1056                             USBDEVNAME(sc->aue_dev), sc->aue_intr_errs,
 1057                             usbd_errstr(status));
 1058                         sc->aue_intr_errs = 0;
 1059                 }
 1060                 if (status == USBD_STALLED)
 1061                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
 1062                 return;
 1063         }
 1064 
 1065         if (p->aue_txstat0)
 1066                 ifp->if_oerrors++;
 1067 
 1068         if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL))
 1069                 ifp->if_collisions++;
 1070 }
 1071 
 1072 /*
 1073  * A frame has been uploaded: pass the resulting mbuf chain up to
 1074  * the higher level protocols.
 1075  */
 1076 Static void
 1077 aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 1078 {
 1079         struct aue_chain        *c = priv;
 1080         struct aue_softc        *sc = c->aue_sc;
 1081         struct ifnet            *ifp = GET_IFP(sc);
 1082         struct mbuf             *m;
 1083         u_int32_t               total_len;
 1084         struct aue_rxpkt        r;
 1085         int                     s;
 1086 
 1087         DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
 1088 
 1089         if (sc->aue_dying)
 1090                 return;
 1091 
 1092         if (!(ifp->if_flags & IFF_RUNNING))
 1093                 return;
 1094 
 1095         if (status != USBD_NORMAL_COMPLETION) {
 1096                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
 1097                         return;
 1098                 sc->aue_rx_errs++;
 1099                 if (usbd_ratecheck(&sc->aue_rx_notice)) {
 1100                         printf("%s: %u usb errors on rx: %s\n",
 1101                             USBDEVNAME(sc->aue_dev), sc->aue_rx_errs,
 1102                             usbd_errstr(status));
 1103                         sc->aue_rx_errs = 0;
 1104                 }
 1105                 if (status == USBD_STALLED)
 1106                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
 1107                 goto done;
 1108         }
 1109 
 1110         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
 1111 
 1112         memcpy(mtod(c->aue_mbuf, char *), c->aue_buf, total_len);
 1113 
 1114         if (total_len <= 4 + ETHER_CRC_LEN) {
 1115                 ifp->if_ierrors++;
 1116                 goto done;
 1117         }
 1118 
 1119         memcpy(&r, c->aue_buf + total_len - 4, sizeof(r));
 1120 
 1121         /* Turn off all the non-error bits in the rx status word. */
 1122         r.aue_rxstat &= AUE_RXSTAT_MASK;
 1123         if (r.aue_rxstat) {
 1124                 ifp->if_ierrors++;
 1125                 goto done;
 1126         }
 1127 
 1128         /* No errors; receive the packet. */
 1129         m = c->aue_mbuf;
 1130         total_len -= ETHER_CRC_LEN + 4;
 1131         m->m_pkthdr.len = m->m_len = total_len;
 1132         ifp->if_ipackets++;
 1133 
 1134         m->m_pkthdr.rcvif = ifp;
 1135 
 1136         s = splnet();
 1137 
 1138         /* XXX ugly */
 1139         if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
 1140                 ifp->if_ierrors++;
 1141                 goto done1;
 1142         }
 1143 
 1144 #if NBPFILTER > 0
 1145         /*
 1146          * Handle BPF listeners. Let the BPF user see the packet, but
 1147          * don't pass it up to the ether_input() layer unless it's
 1148          * a broadcast packet, multicast packet, matches our ethernet
 1149          * address or the interface is in promiscuous mode.
 1150          */
 1151         if (ifp->if_bpf)
 1152                 BPF_MTAP(ifp, m);
 1153 #endif
 1154 
 1155         DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->aue_dev),
 1156                     __func__, m->m_len));
 1157         IF_INPUT(ifp, m);
 1158  done1:
 1159         splx(s);
 1160 
 1161  done:
 1162 
 1163         /* Setup new transfer. */
 1164         usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX],
 1165             c, c->aue_buf, AUE_BUFSZ,
 1166             USBD_SHORT_XFER_OK | USBD_NO_COPY,
 1167             USBD_NO_TIMEOUT, aue_rxeof);
 1168         usbd_transfer(xfer);
 1169 
 1170         DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->aue_dev),
 1171                     __func__));
 1172 }
 1173 
 1174 /*
 1175  * A frame was downloaded to the chip. It's safe for us to clean up
 1176  * the list buffers.
 1177  */
 1178 
 1179 Static void
 1180 aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 1181 {
 1182         struct aue_chain        *c = priv;
 1183         struct aue_softc        *sc = c->aue_sc;
 1184         struct ifnet            *ifp = GET_IFP(sc);
 1185         int                     s;
 1186 
 1187         if (sc->aue_dying)
 1188                 return;
 1189 
 1190         s = splnet();
 1191 
 1192         DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->aue_dev),
 1193                     __func__, status));
 1194 
 1195         ifp->if_timer = 0;
 1196         ifp->if_flags &= ~IFF_OACTIVE;
 1197 
 1198         if (status != USBD_NORMAL_COMPLETION) {
 1199                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
 1200                         splx(s);
 1201                         return;
 1202                 }
 1203                 ifp->if_oerrors++;
 1204                 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->aue_dev),
 1205                     usbd_errstr(status));
 1206                 if (status == USBD_STALLED)
 1207                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
 1208                 splx(s);
 1209                 return;
 1210         }
 1211 
 1212         ifp->if_opackets++;
 1213 
 1214         m_freem(c->aue_mbuf);
 1215         c->aue_mbuf = NULL;
 1216 
 1217         if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
 1218                 aue_start(ifp);
 1219 
 1220         splx(s);
 1221 }
 1222 
 1223 Static void
 1224 aue_tick(void *xsc)
 1225 {
 1226         struct aue_softc        *sc = xsc;
 1227 
 1228         DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
 1229 
 1230         if (sc == NULL)
 1231                 return;
 1232 
 1233         if (sc->aue_dying)
 1234                 return;
 1235 
 1236         /* Perform periodic stuff in process context. */
 1237         usb_add_task(sc->aue_udev, &sc->aue_tick_task);
 1238 }
 1239 
 1240 Static void
 1241 aue_tick_task(void *xsc)
 1242 {
 1243         struct aue_softc        *sc = xsc;
 1244         struct ifnet            *ifp;
 1245         struct mii_data         *mii;
 1246         int                     s;
 1247 
 1248         DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
 1249 
 1250         if (sc->aue_dying)
 1251                 return;
 1252 
 1253         ifp = GET_IFP(sc);
 1254         mii = GET_MII(sc);
 1255         if (mii == NULL)
 1256                 return;
 1257 
 1258         s = splnet();
 1259 
 1260         mii_tick(mii);
 1261         if (!sc->aue_link) {
 1262                 mii_pollstat(mii); /* XXX FreeBSD has removed this call */
 1263                 if (mii->mii_media_status & IFM_ACTIVE &&
 1264                     IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 1265                         DPRINTFN(2,("%s: %s: got link\n",
 1266                                     USBDEVNAME(sc->aue_dev),__func__));
 1267                         sc->aue_link++;
 1268                         if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
 1269                                 aue_start(ifp);
 1270                 }
 1271         }
 1272 
 1273         usb_callout(sc->aue_stat_ch, hz, aue_tick, sc);
 1274 
 1275         splx(s);
 1276 }
 1277 
 1278 Static int
 1279 aue_send(struct aue_softc *sc, struct mbuf *m, int idx)
 1280 {
 1281         int                     total_len;
 1282         struct aue_chain        *c;
 1283         usbd_status             err;
 1284 
 1285         DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__func__));
 1286 
 1287         c = &sc->aue_cdata.aue_tx_chain[idx];
 1288 
 1289         /*
 1290          * Copy the mbuf data into a contiguous buffer, leaving two
 1291          * bytes at the beginning to hold the frame length.
 1292          */
 1293         m_copydata(m, 0, m->m_pkthdr.len, c->aue_buf + 2);
 1294         c->aue_mbuf = m;
 1295 
 1296         /*
 1297          * The ADMtek documentation says that the packet length is
 1298          * supposed to be specified in the first two bytes of the
 1299          * transfer, however it actually seems to ignore this info
 1300          * and base the frame size on the bulk transfer length.
 1301          */
 1302         c->aue_buf[0] = (u_int8_t)m->m_pkthdr.len;
 1303         c->aue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
 1304         total_len = m->m_pkthdr.len + 2;
 1305 
 1306         usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_TX],
 1307             c, c->aue_buf, total_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
 1308             AUE_TX_TIMEOUT, aue_txeof);
 1309 
 1310         /* Transmit */
 1311         err = usbd_transfer(c->aue_xfer);
 1312         if (err != USBD_IN_PROGRESS) {
 1313                 printf("%s: aue_send error=%s\n", USBDEVNAME(sc->aue_dev),
 1314                        usbd_errstr(err));
 1315                 /* Stop the interface from process context. */
 1316                 usb_add_task(sc->aue_udev, &sc->aue_stop_task);
 1317                 return (EIO);
 1318         }
 1319         DPRINTFN(5,("%s: %s: send %d bytes\n", USBDEVNAME(sc->aue_dev),
 1320                     __func__, total_len));
 1321 
 1322         sc->aue_cdata.aue_tx_cnt++;
 1323 
 1324         return (0);
 1325 }
 1326 
 1327 Static void
 1328 aue_start(struct ifnet *ifp)
 1329 {
 1330         struct aue_softc        *sc = ifp->if_softc;
 1331         struct mbuf             *m_head = NULL;
 1332 
 1333         DPRINTFN(5,("%s: %s: enter, link=%d\n", USBDEVNAME(sc->aue_dev),
 1334                     __func__, sc->aue_link));
 1335 
 1336         if (sc->aue_dying)
 1337                 return;
 1338 
 1339         if (!sc->aue_link)
 1340                 return;
 1341 
 1342         if (ifp->if_flags & IFF_OACTIVE)
 1343                 return;
 1344 
 1345         IFQ_POLL(&ifp->if_snd, m_head);
 1346         if (m_head == NULL)
 1347                 return;
 1348 
 1349         if (aue_send(sc, m_head, 0)) {
 1350                 ifp->if_flags |= IFF_OACTIVE;
 1351                 return;
 1352         }
 1353 
 1354         IFQ_DEQUEUE(&ifp->if_snd, m_head);
 1355 
 1356 #if NBPFILTER > 0
 1357         /*
 1358          * If there's a BPF listener, bounce a copy of this frame
 1359          * to him.
 1360          */
 1361         if (ifp->if_bpf)
 1362                 BPF_MTAP(ifp, m_head);
 1363 #endif
 1364 
 1365         ifp->if_flags |= IFF_OACTIVE;
 1366 
 1367         /*
 1368          * Set a timeout in case the chip goes out to lunch.
 1369          */
 1370         ifp->if_timer = 5;
 1371 }
 1372 
 1373 Static void
 1374 aue_init(void *xsc)
 1375 {
 1376         struct aue_softc        *sc = xsc;
 1377         struct ifnet            *ifp = GET_IFP(sc);
 1378         struct mii_data         *mii = GET_MII(sc);
 1379         int                     i, s;
 1380         u_char                  *eaddr;
 1381 
 1382         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1383 
 1384         if (sc->aue_dying)
 1385                 return;
 1386 
 1387         if (ifp->if_flags & IFF_RUNNING)
 1388                 return;
 1389 
 1390         s = splnet();
 1391 
 1392         /*
 1393          * Cancel pending I/O and free all RX/TX buffers.
 1394          */
 1395         aue_reset(sc);
 1396 
 1397 #if defined(__OpenBSD__)
 1398         eaddr = sc->arpcom.ac_enaddr;
 1399 #elif defined(__NetBSD__)
 1400         eaddr = LLADDR(ifp->if_sadl);
 1401 #endif /* defined(__NetBSD__) */
 1402         for (i = 0; i < ETHER_ADDR_LEN; i++)
 1403                 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]);
 1404 
 1405          /* If we want promiscuous mode, set the allframes bit. */
 1406         if (ifp->if_flags & IFF_PROMISC)
 1407                 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
 1408         else
 1409                 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
 1410 
 1411         /* Init TX ring. */
 1412         if (aue_tx_list_init(sc) == ENOBUFS) {
 1413                 printf("%s: tx list init failed\n", USBDEVNAME(sc->aue_dev));
 1414                 splx(s);
 1415                 return;
 1416         }
 1417 
 1418         /* Init RX ring. */
 1419         if (aue_rx_list_init(sc) == ENOBUFS) {
 1420                 printf("%s: rx list init failed\n", USBDEVNAME(sc->aue_dev));
 1421                 splx(s);
 1422                 return;
 1423         }
 1424 
 1425         /* Load the multicast filter. */
 1426         aue_setmulti(sc);
 1427 
 1428         /* Enable RX and TX */
 1429         aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
 1430         AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
 1431         AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
 1432 
 1433         mii_mediachg(mii);
 1434 
 1435         if (sc->aue_ep[AUE_ENDPT_RX] == NULL) {
 1436                 if (aue_openpipes(sc)) {
 1437                         splx(s);
 1438                         return;
 1439                 }
 1440         }
 1441 
 1442         ifp->if_flags |= IFF_RUNNING;
 1443         ifp->if_flags &= ~IFF_OACTIVE;
 1444 
 1445         splx(s);
 1446 
 1447         usb_callout(sc->aue_stat_ch, hz, aue_tick, sc);
 1448 }
 1449 
 1450 Static int
 1451 aue_openpipes(struct aue_softc *sc)
 1452 {
 1453         struct aue_chain        *c;
 1454         usbd_status             err;
 1455         int i;
 1456 
 1457         /* Open RX and TX pipes. */
 1458         err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX],
 1459             USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]);
 1460         if (err) {
 1461                 printf("%s: open rx pipe failed: %s\n",
 1462                     USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1463                 return (EIO);
 1464         }
 1465         err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
 1466             USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]);
 1467         if (err) {
 1468                 printf("%s: open tx pipe failed: %s\n",
 1469                     USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1470                 return (EIO);
 1471         }
 1472         err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR],
 1473             USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_INTR], sc,
 1474             &sc->aue_cdata.aue_ibuf, AUE_INTR_PKTLEN, aue_intr,
 1475             AUE_INTR_INTERVAL);
 1476         if (err) {
 1477                 printf("%s: open intr pipe failed: %s\n",
 1478                     USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1479                 return (EIO);
 1480         }
 1481 
 1482         /* Start up the receive pipe. */
 1483         for (i = 0; i < AUE_RX_LIST_CNT; i++) {
 1484                 c = &sc->aue_cdata.aue_rx_chain[i];
 1485                 usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
 1486                     c, c->aue_buf, AUE_BUFSZ,
 1487                     USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
 1488                     aue_rxeof);
 1489                 (void)usbd_transfer(c->aue_xfer); /* XXX */
 1490                 DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->aue_dev),
 1491                             __func__));
 1492 
 1493         }
 1494         return (0);
 1495 }
 1496 
 1497 /*
 1498  * Set media options.
 1499  */
 1500 Static int
 1501 aue_ifmedia_upd(struct ifnet *ifp)
 1502 {
 1503         struct aue_softc        *sc = ifp->if_softc;
 1504         struct mii_data         *mii = GET_MII(sc);
 1505 
 1506         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1507 
 1508         if (sc->aue_dying)
 1509                 return (0);
 1510 
 1511         sc->aue_link = 0;
 1512         if (mii->mii_instance) {
 1513                 struct mii_softc        *miisc;
 1514                 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
 1515                     miisc = LIST_NEXT(miisc, mii_list))
 1516                          mii_phy_reset(miisc);
 1517         }
 1518         mii_mediachg(mii);
 1519 
 1520         return (0);
 1521 }
 1522 
 1523 /*
 1524  * Report current media status.
 1525  */
 1526 Static void
 1527 aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 1528 {
 1529         struct aue_softc        *sc = ifp->if_softc;
 1530         struct mii_data         *mii = GET_MII(sc);
 1531 
 1532         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1533 
 1534         mii_pollstat(mii);
 1535         ifmr->ifm_active = mii->mii_media_active;
 1536         ifmr->ifm_status = mii->mii_media_status;
 1537 }
 1538 
 1539 Static int
 1540 aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 1541 {
 1542         struct aue_softc        *sc = ifp->if_softc;
 1543         struct ifaddr           *ifa = (struct ifaddr *)data;
 1544         struct ifreq            *ifr = (struct ifreq *)data;
 1545         struct mii_data         *mii;
 1546         int                     s, error = 0;
 1547 
 1548         if (sc->aue_dying)
 1549                 return (EIO);
 1550 
 1551         s = splnet();
 1552 
 1553         switch(command) {
 1554         case SIOCSIFADDR:
 1555                 ifp->if_flags |= IFF_UP;
 1556                 aue_init(sc);
 1557 
 1558                 switch (ifa->ifa_addr->sa_family) {
 1559 #ifdef INET
 1560                 case AF_INET:
 1561 #if defined(__NetBSD__)
 1562                         arp_ifinit(ifp, ifa);
 1563 #else
 1564                         arp_ifinit(&sc->arpcom, ifa);
 1565 #endif
 1566                         break;
 1567 #endif /* INET */
 1568 #ifdef NS
 1569                 case AF_NS:
 1570                     {
 1571                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
 1572 
 1573                         if (ns_nullhost(*ina))
 1574                                 ina->x_host = *(union ns_host *)
 1575                                         LLADDR(ifp->if_sadl);
 1576                         else
 1577                                 memcpy(LLADDR(ifp->if_sadl),
 1578                                        ina->x_host.c_host,
 1579                                        ifp->if_addrlen);
 1580                         break;
 1581                     }
 1582 #endif /* NS */
 1583                 }
 1584                 break;
 1585 
 1586         case SIOCSIFMTU:
 1587                 if (ifr->ifr_mtu > ETHERMTU)
 1588                         error = EINVAL;
 1589                 else
 1590                         ifp->if_mtu = ifr->ifr_mtu;
 1591                 break;
 1592 
 1593         case SIOCSIFFLAGS:
 1594                 if (ifp->if_flags & IFF_UP) {
 1595                         if (ifp->if_flags & IFF_RUNNING &&
 1596                             ifp->if_flags & IFF_PROMISC &&
 1597                             !(sc->aue_if_flags & IFF_PROMISC)) {
 1598                                 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
 1599                         } else if (ifp->if_flags & IFF_RUNNING &&
 1600                             !(ifp->if_flags & IFF_PROMISC) &&
 1601                             sc->aue_if_flags & IFF_PROMISC) {
 1602                                 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
 1603                         } else if (!(ifp->if_flags & IFF_RUNNING))
 1604                                 aue_init(sc);
 1605                 } else {
 1606                         if (ifp->if_flags & IFF_RUNNING)
 1607                                 aue_stop(sc);
 1608                 }
 1609                 sc->aue_if_flags = ifp->if_flags;
 1610                 error = 0;
 1611                 break;
 1612         case SIOCADDMULTI:
 1613         case SIOCDELMULTI:
 1614                 error = (command == SIOCADDMULTI) ?
 1615                         ether_addmulti(ifr, &sc->aue_ec) :
 1616                         ether_delmulti(ifr, &sc->aue_ec);
 1617                 if (error == ENETRESET) {
 1618                         aue_init(sc);
 1619                 }
 1620                 aue_setmulti(sc);
 1621                 error = 0;
 1622                 break;
 1623         case SIOCGIFMEDIA:
 1624         case SIOCSIFMEDIA:
 1625                 mii = GET_MII(sc);
 1626                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 1627                 break;
 1628         default:
 1629                 error = EINVAL;
 1630                 break;
 1631         }
 1632 
 1633         splx(s);
 1634 
 1635         return (error);
 1636 }
 1637 
 1638 Static void
 1639 aue_watchdog(struct ifnet *ifp)
 1640 {
 1641         struct aue_softc        *sc = ifp->if_softc;
 1642         struct aue_chain        *c;
 1643         usbd_status             stat;
 1644         int                     s;
 1645 
 1646         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1647 
 1648         ifp->if_oerrors++;
 1649         printf("%s: watchdog timeout\n", USBDEVNAME(sc->aue_dev));
 1650 
 1651         s = splusb();
 1652         c = &sc->aue_cdata.aue_tx_chain[0];
 1653         usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &stat);
 1654         aue_txeof(c->aue_xfer, c, stat);
 1655 
 1656         if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
 1657                 aue_start(ifp);
 1658         splx(s);
 1659 }
 1660 
 1661 /*
 1662  * Stop the adapter and free any mbufs allocated to the
 1663  * RX and TX lists.
 1664  */
 1665 Static void
 1666 aue_stop(struct aue_softc *sc)
 1667 {
 1668         usbd_status             err;
 1669         struct ifnet            *ifp;
 1670         int                     i;
 1671 
 1672         DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 1673 
 1674         ifp = GET_IFP(sc);
 1675         ifp->if_timer = 0;
 1676 
 1677         aue_csr_write_1(sc, AUE_CTL0, 0);
 1678         aue_csr_write_1(sc, AUE_CTL1, 0);
 1679         aue_reset(sc);
 1680         usb_uncallout(sc->aue_stat_ch, aue_tick, sc);
 1681 
 1682         /* Stop transfers. */
 1683         if (sc->aue_ep[AUE_ENDPT_RX] != NULL) {
 1684                 err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]);
 1685                 if (err) {
 1686                         printf("%s: abort rx pipe failed: %s\n",
 1687                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1688                 }
 1689                 err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]);
 1690                 if (err) {
 1691                         printf("%s: close rx pipe failed: %s\n",
 1692                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1693                 }
 1694                 sc->aue_ep[AUE_ENDPT_RX] = NULL;
 1695         }
 1696 
 1697         if (sc->aue_ep[AUE_ENDPT_TX] != NULL) {
 1698                 err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
 1699                 if (err) {
 1700                         printf("%s: abort tx pipe failed: %s\n",
 1701                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1702                 }
 1703                 err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]);
 1704                 if (err) {
 1705                         printf("%s: close tx pipe failed: %s\n",
 1706                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1707                 }
 1708                 sc->aue_ep[AUE_ENDPT_TX] = NULL;
 1709         }
 1710 
 1711         if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) {
 1712                 err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
 1713                 if (err) {
 1714                         printf("%s: abort intr pipe failed: %s\n",
 1715                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1716                 }
 1717                 err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
 1718                 if (err) {
 1719                         printf("%s: close intr pipe failed: %s\n",
 1720                             USBDEVNAME(sc->aue_dev), usbd_errstr(err));
 1721                 }
 1722                 sc->aue_ep[AUE_ENDPT_INTR] = NULL;
 1723         }
 1724 
 1725         /* Free RX resources. */
 1726         for (i = 0; i < AUE_RX_LIST_CNT; i++) {
 1727                 if (sc->aue_cdata.aue_rx_chain[i].aue_mbuf != NULL) {
 1728                         m_freem(sc->aue_cdata.aue_rx_chain[i].aue_mbuf);
 1729                         sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL;
 1730                 }
 1731                 if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) {
 1732                         usbd_free_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer);
 1733                         sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL;
 1734                 }
 1735         }
 1736 
 1737         /* Free TX resources. */
 1738         for (i = 0; i < AUE_TX_LIST_CNT; i++) {
 1739                 if (sc->aue_cdata.aue_tx_chain[i].aue_mbuf != NULL) {
 1740                         m_freem(sc->aue_cdata.aue_tx_chain[i].aue_mbuf);
 1741                         sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL;
 1742                 }
 1743                 if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) {
 1744                         usbd_free_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer);
 1745                         sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL;
 1746                 }
 1747         }
 1748 
 1749         sc->aue_link = 0;
 1750 
 1751         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1752 }

Cache object: 931882a355c27bd7a0e3da322433edac


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.