Diff for /src/sys/dev/netif/aue/if_aue.c between versions 1.5 and 1.6

version 1.5, 2003/11/20 22:07:26 version 1.6, 2003/12/30 01:01:45
Line 1 Line 1
/*/*-
  * Copyright (c) 1997, 1998, 1999, 2000   * Copyright (c) 1997, 1998, 1999, 2000
  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.   *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
  *   *
Line 29 Line 29
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.   * THE POSSIBILITY OF SUCH DAMAGE.
  *   *
 * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.19.2.18 2003/06/14 15:56:48 trhodes Exp $ * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.78 2003/12/17 14:23:07 sanpei Exp $
  * $DragonFly$   * $DragonFly$
  *   *
  * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.19.2.18 2003/06/14 15:56:48 trhodes Exp $   * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.19.2.18 2003/06/14 15:56:48 trhodes Exp $
  */   */
   
 /*  /*
 * ADMtek AN986 Pegasus USB to ethernet driver. Datasheet is available * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
 * from http://www.admtek.com.tw. * Datasheet is available from http://www.admtek.com.tw.
  *   *
  * Written by Bill Paul <wpaul@ee.columbia.edu>   * Written by Bill Paul <wpaul@ee.columbia.edu>
  * Electrical Engineering Department   * Electrical Engineering Department
Line 80 Line 80
   
 #include <net/bpf.h>  #include <net/bpf.h>
   
 #include <machine/clock.h>      /* for DELAY */  
 #include <sys/bus.h>  #include <sys/bus.h>
   #include <machine/bus.h>
   #if __FreeBSD_version < 500000
   #include <machine/clock.h>
   #endif
   
 #include <bus/usb/usb.h>  #include <bus/usb/usb.h>
 #include <bus/usb/usbdi.h>  #include <bus/usb/usbdi.h>
Line 95 Line 98
   
 #include "if_auereg.h"  #include "if_auereg.h"
   
   MODULE_DEPEND(aue, usb, 1, 1, 1);
   MODULE_DEPEND(aue, ether, 1, 1, 1);
   MODULE_DEPEND(aue, miibus, 1, 1, 1);
   
 /* "controller miibus0" required.  See GENERIC if you get errors here. */  /* "controller miibus0" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"  #include "miibus_if.h"
   
/*struct aue_type {
 * Various supported device vendors/products.        struct usb_devno        aue_dev;
 */        u_int16_t               aue_flags;
Static struct aue_type aue_devs[] = {#define LSYS  0x0001          /* use Linksys reset */
    { USB_VENDOR_ABOCOM,      USB_PRODUCT_ABOCOM_XX1,                 PNA|PII },#define PNA   0x0002          /* has Home PNA */
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX2,                 PII },#define PII   0x0004          /* Pegasus II chip */
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_UFE1000,         LSYS },};
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX4,                 PNA },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX5,                 PNA },Static const struct aue_type aue_devs[] = {
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX6,                 PII }, {{ USB_VENDOR_3COM,              USB_PRODUCT_3COM_3C460B},         PII },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX7,                 PII }, {{ USB_VENDOR_ABOCOM,             USB_PRODUCT_ABOCOM_XX1},          PNA|PII },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX8,                 PII }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX2},          PII },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX9,                 PNA }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_UFE1000},         LSYS },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_XX10,         0 }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX4},          PNA },
    { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_DSB650TX_PNA,  0 }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX5},          PNA },
    { USB_VENDOR_ACCTON,    USB_PRODUCT_ACCTON_USB320_EC,         0 }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX6},          PII },
    { USB_VENDOR_ACCTON,    USB_PRODUCT_ACCTON_SS1001,         PII }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX7},          PII },
    { USB_VENDOR_ADMTEK,    USB_PRODUCT_ADMTEK_PEGASUS,         PNA }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX8},          PII },
    { USB_VENDOR_ADMTEK,    USB_PRODUCT_ADMTEK_PEGASUSII,         PII }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX9},          PNA },
    { USB_VENDOR_BELKIN,    USB_PRODUCT_BELKIN_USB2LAN,       PII }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_XX10},         0 },
    { USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USB100,         0 }, {{ USB_VENDOR_ABOCOM,            USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 },
    { USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBLP100,  PNA }, {{ USB_VENDOR_ACCTON,            USB_PRODUCT_ACCTON_USB320_EC},         0 },
    { USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBEL100,  0 }, {{ USB_VENDOR_ACCTON,            USB_PRODUCT_ACCTON_SS1001},         PII },
    { USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBE100,         PII }, {{ USB_VENDOR_ADMTEK,            USB_PRODUCT_ADMTEK_PEGASUS},         PNA },
    { USB_VENDOR_COREGA,    USB_PRODUCT_COREGA_FETHER_USB_TX, 0 }, {{ USB_VENDOR_ADMTEK,            USB_PRODUCT_ADMTEK_PEGASUSII},         PII },
    { USB_VENDOR_COREGA,    USB_PRODUCT_COREGA_FETHER_USB_TXS,PII }, {{ USB_VENDOR_BELKIN,            USB_PRODUCT_BELKIN_USB2LAN},        PII },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX4,         LSYS|PII }, {{ USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USB100},         0 },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX1,         LSYS }, {{ USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBLP100}, PNA },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX,         LSYS }, {{ USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBEL100}, 0 },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX_PNA,         PNA }, {{ USB_VENDOR_BILLIONTON,        USB_PRODUCT_BILLIONTON_USBE100},  PII },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX3,         LSYS|PII }, {{ USB_VENDOR_COREGA,            USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX2,         LSYS|PII }, {{ USB_VENDOR_COREGA,            USB_PRODUCT_COREGA_FETHER_USB_TXS},PII },
    { USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650,         LSYS }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX4},         LSYS|PII },
    { USB_VENDOR_ELECOM,    USB_PRODUCT_ELECOM_LDUSBTX0,         0 }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX1},         LSYS },
    { USB_VENDOR_ELECOM,    USB_PRODUCT_ELECOM_LDUSBTX1,         LSYS }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX},         LSYS },
    { USB_VENDOR_ELECOM,    USB_PRODUCT_ELECOM_LDUSBTX2,         0 }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX_PNA},  PNA },
    { USB_VENDOR_ELECOM,    USB_PRODUCT_ELECOM_LDUSBTX3,         LSYS }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX3},         LSYS|PII },
    { USB_VENDOR_ELECOM,    USB_PRODUCT_ELECOM_LDUSBLTX,         PII }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650TX2},         LSYS|PII },
    { USB_VENDOR_ELSA,              USB_PRODUCT_ELSA_USB2ETHERNET,         0 }, {{ USB_VENDOR_DLINK,             USB_PRODUCT_DLINK_DSB650},         LSYS },
    { USB_VENDOR_IODATA,    USB_PRODUCT_IODATA_USBETTX,         0 }, {{ USB_VENDOR_ELECOM,            USB_PRODUCT_ELECOM_LDUSBTX0},         0 },
    { USB_VENDOR_IODATA,    USB_PRODUCT_IODATA_USBETTXS,         PII }, {{ USB_VENDOR_ELECOM,            USB_PRODUCT_ELECOM_LDUSBTX1},         LSYS },
    { USB_VENDOR_KINGSTON,  USB_PRODUCT_KINGSTON_KNU101TX,    0 }, {{ USB_VENDOR_ELECOM,            USB_PRODUCT_ELECOM_LDUSBTX2},         0 },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB10TX1,         LSYS|PII }, {{ USB_VENDOR_ELECOM,            USB_PRODUCT_ELECOM_LDUSBTX3},         LSYS },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB10T,         LSYS }, {{ USB_VENDOR_ELECOM,            USB_PRODUCT_ELECOM_LDUSBLTX},         PII },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB100TX,         LSYS }, {{ USB_VENDOR_ELSA,              USB_PRODUCT_ELSA_USB2ETHERNET},         0 },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB100H1,         LSYS|PNA }, {{ USB_VENDOR_HAWKING,          USB_PRODUCT_HAWKING_UF100},       PII },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB10TA,         LSYS }, {{ USB_VENDOR_HP,              USB_PRODUCT_HP_HN210E},           PII },
    { USB_VENDOR_LINKSYS,   USB_PRODUCT_LINKSYS_USB10TX2,         LSYS|PII }, {{ USB_VENDOR_IODATA,            USB_PRODUCT_IODATA_USBETTX},         0 },
    { USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUATX1,         0 }, {{ USB_VENDOR_IODATA,            USB_PRODUCT_IODATA_USBETTXS},         PII },
    { USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUATX5,         0 }, {{ USB_VENDOR_KINGSTON,  USB_PRODUCT_KINGSTON_KNU101TX},   0 },
    { USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUA2TX5,         PII }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB10TX1},         LSYS|PII },
    { USB_VENDOR_SIEMENS,   USB_PRODUCT_SIEMENS_SPEEDSTREAM,  PII }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB10T},         LSYS },
    { USB_VENDOR_SMARTBRIDGES,      USB_PRODUCT_SMARTBRIDGES_SMARTNIC,PII }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB100TX},         LSYS },
    { USB_VENDOR_SMC,               USB_PRODUCT_SMC_2202USB,         0 }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB100H1},         LSYS|PNA },
    { USB_VENDOR_SMC,               USB_PRODUCT_SMC_2206USB,         PII }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB10TA},         LSYS },
    { USB_VENDOR_SOHOWARE,  USB_PRODUCT_SOHOWARE_NUB100,         0 }, {{ USB_VENDOR_LINKSYS,           USB_PRODUCT_LINKSYS_USB10TX2},         LSYS|PII },
    { 0, 0, 0 } {{ USB_VENDOR_MICROSOFT,        USB_PRODUCT_MICROSOFT_MN110},     PII },
  {{ USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUATX1},         0 },
  {{ USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUATX5},         0 },
  {{ USB_VENDOR_MELCO,             USB_PRODUCT_MELCO_LUA2TX5},         PII },
  {{ USB_VENDOR_SIEMENS,           USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII },
  {{ USB_VENDOR_SMARTBRIDGES,      USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII },
  {{ USB_VENDOR_SMC,               USB_PRODUCT_SMC_2202USB},         0 },
  {{ USB_VENDOR_SMC,               USB_PRODUCT_SMC_2206USB},         PII },
  {{ USB_VENDOR_SOHOWARE,  USB_PRODUCT_SOHOWARE_NUB100},         0 },
 };  };
   #define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
   
 Static struct usb_qdat aue_qdat;  Static struct usb_qdat aue_qdat;
   
Static int aue_match(device_t);Static int aue_match(device_ptr_t);
Static int aue_attach(device_t);Static int aue_attach(device_ptr_t);
Static int aue_detach(device_t);Static int aue_detach(device_ptr_t);
   
Static void aue_reset_pegasus_II(struct aue_softc *);Static void aue_reset_pegasus_II(struct aue_softc *sc);
 Static int aue_tx_list_init(struct aue_softc *);  Static int aue_tx_list_init(struct aue_softc *);
 Static int aue_rx_list_init(struct aue_softc *);  Static int aue_rx_list_init(struct aue_softc *);
 Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *);  Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *);
Line 180  Static int aue_ioctl(struct ifnet *, u_l Line 196  Static int aue_ioctl(struct ifnet *, u_l
 Static void aue_init(void *);  Static void aue_init(void *);
 Static void aue_stop(struct aue_softc *);  Static void aue_stop(struct aue_softc *);
 Static void aue_watchdog(struct ifnet *);  Static void aue_watchdog(struct ifnet *);
Static void aue_shutdown(device_t);Static void aue_shutdown(device_ptr_t);
 Static int aue_ifmedia_upd(struct ifnet *);  Static int aue_ifmedia_upd(struct ifnet *);
 Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);  Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
   
 Static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *);  Static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *);
 Static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int);  Static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int);
Static int aue_miibus_readreg(device_t, int, int);Static int aue_miibus_readreg(device_ptr_t, int, int);
Static int aue_miibus_writereg(device_t, int, int, int);Static int aue_miibus_writereg(device_ptr_t, int, int, int);
Static void aue_miibus_statchg(device_t);Static void aue_miibus_statchg(device_ptr_t);
   
 Static void aue_setmulti(struct aue_softc *);  Static void aue_setmulti(struct aue_softc *);
Static u_int32_t aue_crc(caddr_t);Static uint32_t aue_mchash(const uint8_t *);
 Static void aue_reset(struct aue_softc *);  Static void aue_reset(struct aue_softc *);
   
Static int csr_read_1(struct aue_softc *, int);Static int aue_csr_read_1(struct aue_softc *, int);
Static int csr_write_1(struct aue_softc *, int, int);Static int aue_csr_write_1(struct aue_softc *, int, int);
Static int csr_read_2(struct aue_softc *, int);Static int aue_csr_read_2(struct aue_softc *, int);
Static int csr_write_2(struct aue_softc *, int, int);Static int aue_csr_write_2(struct aue_softc *, int, int);
   
 Static device_method_t aue_methods[] = {  Static device_method_t aue_methods[] = {
         /* Device interface */          /* Device interface */
Line 227  Static driver_t aue_driver = { Line 243  Static driver_t aue_driver = {
 Static devclass_t aue_devclass;  Static devclass_t aue_devclass;
   
 DECLARE_DUMMY_MODULE(if_aue);  DECLARE_DUMMY_MODULE(if_aue);
DRIVER_MODULE(if_aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0);DRIVER_MODULE(aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0);
 DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);  DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);
   
 #define AUE_SETBIT(sc, reg, x)                          \  #define AUE_SETBIT(sc, reg, x)                          \
        csr_write_1(sc, reg, csr_read_1(sc, reg) | (x))        aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
   
 #define AUE_CLRBIT(sc, reg, x)                          \  #define AUE_CLRBIT(sc, reg, x)                          \
        csr_write_1(sc, reg, csr_read_1(sc, reg) & ~(x))        aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
   
 Static int  Static int
csr_read_1(struct aue_softc *sc, int reg)aue_csr_read_1(struct aue_softc *sc, int reg)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         u_int8_t                val = 0;          u_int8_t                val = 0;
         int                     s;  
   
        if (sc->aue_gone)        if (sc->aue_dying)
                 return(0);                  return(0);
   
        s = splusb();        AUE_LOCK(sc);
   
         req.bmRequestType = UT_READ_VENDOR_DEVICE;          req.bmRequestType = UT_READ_VENDOR_DEVICE;
         req.bRequest = AUE_UR_READREG;          req.bRequest = AUE_UR_READREG;
Line 255  csr_read_1(struct aue_softc *sc, int reg Line 270  csr_read_1(struct aue_softc *sc, int reg
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 1);          USETW(req.wLength, 1);
   
        err = usbd_do_request_flags(sc->aue_udev, &req,        err = usbd_do_request(sc->aue_udev, &req, &val);
            &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        AUE_UNLOCK(sc);
   
        if (err)        if (err) {
                return(0);                return (0);
         }
   
        return(val);        return (val);
 }  }
   
 Static int  Static int
csr_read_2(struct aue_softc *sc, int reg)aue_csr_read_2(struct aue_softc *sc, int reg)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         u_int16_t               val = 0;          u_int16_t               val = 0;
         int                     s;  
   
        if (sc->aue_gone)        if (sc->aue_dying)
                return(0);                return (0);
   
        s = splusb();        AUE_LOCK(sc);
   
         req.bmRequestType = UT_READ_VENDOR_DEVICE;          req.bmRequestType = UT_READ_VENDOR_DEVICE;
         req.bRequest = AUE_UR_READREG;          req.bRequest = AUE_UR_READREG;
Line 285  csr_read_2(struct aue_softc *sc, int reg Line 299  csr_read_2(struct aue_softc *sc, int reg
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 2);          USETW(req.wLength, 2);
   
        err = usbd_do_request_flags(sc->aue_udev, &req,        err = usbd_do_request(sc->aue_udev, &req, &val);
            &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        AUE_UNLOCK(sc);
   
        if (err)        if (err) {
                return(0);                return (0);
         }
   
        return(val);        return (val);
 }  }
   
 Static int  Static int
csr_write_1(struct aue_softc *sc, int reg, int val)aue_csr_write_1(struct aue_softc *sc, int reg, int val)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->aue_gone)        if (sc->aue_dying)
                return(0);                return (0);
   
        s = splusb();        AUE_LOCK(sc);
   
         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;          req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
         req.bRequest = AUE_UR_WRITEREG;          req.bRequest = AUE_UR_WRITEREG;
Line 314  csr_write_1(struct aue_softc *sc, int re Line 327  csr_write_1(struct aue_softc *sc, int re
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 1);          USETW(req.wLength, 1);
   
        err = usbd_do_request_flags(sc->aue_udev, &req,        err = usbd_do_request(sc->aue_udev, &req, &val);
            &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        AUE_UNLOCK(sc);
   
        if (err)        if (err) {
                return(-1);                return (-1);
         }
   
        return(0);        return (0);
 }  }
   
 Static int  Static int
csr_write_2(struct aue_softc *sc, int reg, int val)aue_csr_write_2(struct aue_softc *sc, int reg, int val)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->aue_gone)        if (sc->aue_dying)
                return(0);                return (0);
   
        s = splusb();        AUE_LOCK(sc);
   
         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;          req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
         req.bRequest = AUE_UR_WRITEREG;          req.bRequest = AUE_UR_WRITEREG;
Line 343  csr_write_2(struct aue_softc *sc, int re Line 355  csr_write_2(struct aue_softc *sc, int re
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 2);          USETW(req.wLength, 2);
   
        err = usbd_do_request_flags(sc->aue_udev, &req,        err = usbd_do_request(sc->aue_udev, &req, &val);
            &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        AUE_UNLOCK(sc);
   
        if (err)        if (err) {
                return(-1);                return (-1);
         }
   
        return(0);        return (0);
 }  }
   
 /*  /*
Line 361  Static void Line 373  Static void
 aue_eeprom_getword(struct aue_softc *sc, int addr, u_int16_t *dest)  aue_eeprom_getword(struct aue_softc *sc, int addr, u_int16_t *dest)
 {  {
         int             i;          int             i;
        u_int16_t               word = 0;        u_int16_t       word = 0;
   
        csr_write_1(sc, AUE_EE_REG, addr);        aue_csr_write_1(sc, AUE_EE_REG, addr);
        csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);        aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
   
         for (i = 0; i < AUE_TIMEOUT; i++) {          for (i = 0; i < AUE_TIMEOUT; i++) {
                if (csr_read_1(sc, AUE_EE_CTL) &                if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
                    AUE_EECTL_DONE) 
                         break;                          break;
         }          }
   
Line 377  aue_eeprom_getword(struct aue_softc *sc, Line 388  aue_eeprom_getword(struct aue_softc *sc,
                     sc->aue_unit);                      sc->aue_unit);
         }          }
   
        word = csr_read_2(sc, AUE_EE_DATA);        word = aue_csr_read_2(sc, AUE_EE_DATA);
         *dest = word;          *dest = word;
   
         return;          return;
Line 405  aue_read_eeprom(struct aue_softc *sc, ca Line 416  aue_read_eeprom(struct aue_softc *sc, ca
 }  }
   
 Static int  Static int
aue_miibus_readreg(device_t dev, int phy, int reg)aue_miibus_readreg(device_ptr_t dev, int phy, int reg)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = USBGETSOFTC(dev);
         int                     i;          int                     i;
         u_int16_t               val = 0;          u_int16_t               val = 0;
   
         sc = device_get_softc(dev);  
   
         /*          /*
          * The Am79C901 HomePNA PHY actually contains           * The Am79C901 HomePNA PHY actually contains
          * two transceivers: a 1Mbps HomePNA PHY and a           * two transceivers: a 1Mbps HomePNA PHY and a
Line 423  aue_miibus_readreg(device_t dev, int phy Line 432  aue_miibus_readreg(device_t dev, int phy
          * happens to be configured for MII address 3,           * happens to be configured for MII address 3,
          * so we filter that out.           * so we filter that out.
          */           */
        if (sc->aue_info->aue_vid == USB_VENDOR_ADMTEK &&        if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
            sc->aue_info->aue_did == USB_PRODUCT_ADMTEK_PEGASUS) {            sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
                 if (phy == 3)                  if (phy == 3)
                        return(0);                        return (0);
 #ifdef notdef  #ifdef notdef
                 if (phy != 1)                  if (phy != 1)
                        return(0);                        return (0);
 #endif  #endif
         }          }
   
        csr_write_1(sc, AUE_PHY_ADDR, phy);        aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
        csr_write_1(sc, AUE_PHY_CTL, reg|AUE_PHYCTL_READ);        aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
   
         for (i = 0; i < AUE_TIMEOUT; i++) {          for (i = 0; i < AUE_TIMEOUT; i++) {
                if (csr_read_1(sc, AUE_PHY_CTL) &                if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
                    AUE_PHYCTL_DONE) 
                         break;                          break;
         }          }
   
         if (i == AUE_TIMEOUT) {          if (i == AUE_TIMEOUT) {
                printf("aue%d: MII read timed out\n",                printf("aue%d: MII read timed out\n", sc->aue_unit);
                    sc->aue_unit); 
         }          }
   
        val = csr_read_2(sc, AUE_PHY_DATA);        val = aue_csr_read_2(sc, AUE_PHY_DATA);
   
        return(val);        return (val);
 }  }
   
 Static int  Static int
aue_miibus_writereg(device_t dev, int phy, int reg, int data)aue_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = USBGETSOFTC(dev);
         int                     i;          int                     i;
   
         if (phy == 3)          if (phy == 3)
                return(0);                return (0);
   
        sc = device_get_softc(dev);        aue_csr_write_2(sc, AUE_PHY_DATA, data);
        aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
        csr_write_2(sc, AUE_PHY_DATA, data);        aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
        csr_write_1(sc, AUE_PHY_ADDR, phy); 
        csr_write_1(sc, AUE_PHY_CTL, reg|AUE_PHYCTL_WRITE); 
   
         for (i = 0; i < AUE_TIMEOUT; i++) {          for (i = 0; i < AUE_TIMEOUT; i++) {
                if (csr_read_1(sc, AUE_PHY_CTL) &                if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
                    AUE_PHYCTL_DONE) 
                         break;                          break;
         }          }
   
Line 482  aue_miibus_writereg(device_t dev, int ph Line 486  aue_miibus_writereg(device_t dev, int ph
 }  }
   
 Static void  Static void
aue_miibus_statchg(device_t dev)aue_miibus_statchg(device_ptr_t dev)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = USBGETSOFTC(dev);
        struct mii_data         *mii;        struct mii_data         *mii = GET_MII(sc);
   
        sc = device_get_softc(dev);        AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
        mii = device_get_softc(sc->aue_miibus); 
 
        AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB|AUE_CTL0_TX_ENB); 
         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {          if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
                 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);                  AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
         } else {          } else {
                 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);                  AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
         }          }
   
        if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {        if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
                 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);                  AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
        } else {        else
                 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);                  AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
        }
        AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB|AUE_CTL0_TX_ENB);        AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
   
         /*          /*
          * Set the LED modes on the LinkSys adapter.           * Set the LED modes on the LinkSys adapter.
          * This turns on the 'dual link LED' bin in the auxmode           * This turns on the 'dual link LED' bin in the auxmode
          * register of the Broadcom PHY.           * register of the Broadcom PHY.
          */           */
        if (sc->aue_info->aue_flags & LSYS) {        if (sc->aue_flags & LSYS) {
                u_int16_t               auxmode;                u_int16_t auxmode;
                 auxmode = aue_miibus_readreg(dev, 0, 0x1b);                  auxmode = aue_miibus_readreg(dev, 0, 0x1b);
                 aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);                  aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
         }          }
Line 522  aue_miibus_statchg(device_t dev) Line 523  aue_miibus_statchg(device_t dev)
 #define AUE_BITS        6  #define AUE_BITS        6
   
 Static u_int32_t  Static u_int32_t
aue_crc(caddr_t addr)aue_mchash(const uint8_t *addr)
 {  {
        u_int32_t         idx, bit, data, crc;        uint32_t crc;
         int idx, bit;
         uint8_t data;
   
         /* Compute CRC for the address value. */          /* Compute CRC for the address value. */
         crc = 0xFFFFFFFF; /* initial value */          crc = 0xFFFFFFFF; /* initial value */
Line 555  aue_setmulti(struct aue_softc *sc) Line 558  aue_setmulti(struct aue_softc *sc)
   
         /* first, zot all the existing hash bits */          /* first, zot all the existing hash bits */
         for (i = 0; i < 8; i++)          for (i = 0; i < 8; i++)
                csr_write_1(sc, AUE_MAR0 + i, 0);                aue_csr_write_1(sc, AUE_MAR0 + i, 0);
   
         /* now program new ones */          /* now program new ones */
        for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;#if __FreeBSD_version >= 500000
            ifma = ifma->ifma_link.le_next) {        TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 #else
         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 #endif
         {
                 if (ifma->ifma_addr->sa_family != AF_LINK)                  if (ifma->ifma_addr->sa_family != AF_LINK)
                         continue;                          continue;
                h = aue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));                h = aue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
                 AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));                  AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));
         }          }
   
Line 573  Static void Line 580  Static void
 aue_reset_pegasus_II(struct aue_softc *sc)  aue_reset_pegasus_II(struct aue_softc *sc)
 {  {
         /* Magic constants taken from Linux driver. */          /* Magic constants taken from Linux driver. */
        csr_write_1(sc, AUE_REG_1D, 0);        aue_csr_write_1(sc, AUE_REG_1D, 0);
        csr_write_1(sc, AUE_REG_7B, 2);        aue_csr_write_1(sc, AUE_REG_7B, 2);
 #if 0  #if 0
         if ((sc->aue_flags & HAS_HOME_PNA) && mii_mode)          if ((sc->aue_flags & HAS_HOME_PNA) && mii_mode)
                csr_write_1(sc, AUE_REG_81, 6);                aue_csr_write_1(sc, AUE_REG_81, 6);
         else          else
 #endif  #endif
                csr_write_1(sc, AUE_REG_81, 2);                aue_csr_write_1(sc, AUE_REG_81, 2);
 }  }
   
 Static void  Static void
Line 591  aue_reset(struct aue_softc *sc) Line 598  aue_reset(struct aue_softc *sc)
         AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);          AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
   
         for (i = 0; i < AUE_TIMEOUT; i++) {          for (i = 0; i < AUE_TIMEOUT; i++) {
                if (!(csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))                if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
                         break;                          break;
         }          }
   
Line 607  aue_reset(struct aue_softc *sc) Line 614  aue_reset(struct aue_softc *sc)
          * Note: We force all of the GPIO pins low first, *then*           * Note: We force all of the GPIO pins low first, *then*
          * enable the ones we want.           * enable the ones we want.
          */           */
        csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);        aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);
        csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);        aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);
   
        /* Grrr. LinkSys has to be different from everyone else. */        if (sc->aue_flags & LSYS) {
        if (sc->aue_info->aue_flags & LSYS) {                /* Grrr. LinkSys has to be different from everyone else. */
                csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1);                aue_csr_write_1(sc, AUE_GPIO0,
                csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1|                    AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
                        AUE_GPIO_OUT0);                aue_csr_write_1(sc, AUE_GPIO0,
                     AUE_GPIO_SEL0 | AUE_GPIO_SEL1 | AUE_GPIO_OUT0);
         }          }
   
        if (sc->aue_info->aue_flags & PII)        if (sc->aue_flags & PII)
                 aue_reset_pegasus_II(sc);                  aue_reset_pegasus_II(sc);
   
         /* Wait a little while for the chip to get its brains in order. */          /* Wait a little while for the chip to get its brains in order. */
         DELAY(10000);          DELAY(10000);
   
        return;        return;
 }  }
   
 /*  /*
Line 632  aue_reset(struct aue_softc *sc) Line 640  aue_reset(struct aue_softc *sc)
 USB_MATCH(aue)  USB_MATCH(aue)
 {  {
         USB_MATCH_START(aue, uaa);          USB_MATCH_START(aue, uaa);
         struct aue_type                 *t;  
   
         if (!uaa->iface)  
                 return(UMATCH_NONE);  
   
        t = aue_devs;        if (uaa->iface != NULL)
        while(t->aue_vid) {                return (UMATCH_NONE);
                if (uaa->vendor == t->aue_vid && 
                    uaa->product == t->aue_did) { 
                        return(UMATCH_VENDOR_PRODUCT); 
                } 
                t++; 
        } 
   
        return(UMATCH_NONE);        return (aue_lookup(uaa->vendor, uaa->product) != NULL ?
                 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
 }  }
   
 /*  /*
Line 657  USB_ATTACH(aue) Line 656  USB_ATTACH(aue)
 {  {
         USB_ATTACH_START(aue, sc, uaa);          USB_ATTACH_START(aue, sc, uaa);
         char                    devinfo[1024];          char                    devinfo[1024];
         int                     s;  
         u_char                  eaddr[ETHER_ADDR_LEN];          u_char                  eaddr[ETHER_ADDR_LEN];
         struct ifnet            *ifp;          struct ifnet            *ifp;
           usbd_interface_handle   iface;
           usbd_status             err;
         usb_interface_descriptor_t      *id;          usb_interface_descriptor_t      *id;
         usb_endpoint_descriptor_t       *ed;          usb_endpoint_descriptor_t       *ed;
         int                     i;          int                     i;
         struct aue_type         *t;  
   
         s = splimp();  
   
         bzero(sc, sizeof(struct aue_softc));          bzero(sc, sizeof(struct aue_softc));
        sc->aue_iface = uaa->iface;
         usbd_devinfo(uaa->device, 0, devinfo);
 
         sc->aue_udev = uaa->device;          sc->aue_udev = uaa->device;
         sc->aue_unit = device_get_unit(self);          sc->aue_unit = device_get_unit(self);
   
         if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) {          if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) {
                 printf("aue%d: getting interface handle failed\n",                  printf("aue%d: getting interface handle failed\n",
                     sc->aue_unit);                      sc->aue_unit);
                 splx(s);  
                 USB_ATTACH_ERROR_RETURN;                  USB_ATTACH_ERROR_RETURN;
         }          }
   
        t = aue_devs;        err = usbd_device2interface_handle(uaa->device, AUE_IFACE_IDX, &iface);
        while(t->aue_vid) {        if (err) {
                if (uaa->vendor == t->aue_vid &&                printf("aue%d: getting interface handle failed\n",
                    uaa->product == t->aue_did) {                    sc->aue_unit);
                        sc->aue_info = t;                USB_ATTACH_ERROR_RETURN;
                        break; 
                } 
                t++; 
         }          }
   
        id = usbd_get_interface_descriptor(uaa->iface);        sc->aue_iface = iface;
         sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags;
 
         sc->aue_product = uaa->product;
         sc->aue_vendor = uaa->vendor;
 
         id = usbd_get_interface_descriptor(sc->aue_iface);
   
         usbd_devinfo(uaa->device, 0, devinfo);          usbd_devinfo(uaa->device, 0, devinfo);
         device_set_desc_copy(self, devinfo);          device_set_desc_copy(self, devinfo);
Line 697  USB_ATTACH(aue) Line 698  USB_ATTACH(aue)
   
         /* Find endpoints. */          /* Find endpoints. */
         for (i = 0; i < id->bNumEndpoints; i++) {          for (i = 0; i < id->bNumEndpoints; i++) {
                ed = usbd_interface2endpoint_descriptor(uaa->iface, i);                ed = usbd_interface2endpoint_descriptor(iface, i);
                if (!ed) {                if (ed == NULL) {
                         printf("aue%d: couldn't get ep %d\n",                          printf("aue%d: couldn't get ep %d\n",
                             sc->aue_unit, i);                              sc->aue_unit, i);
                         splx(s);  
                         USB_ATTACH_ERROR_RETURN;                          USB_ATTACH_ERROR_RETURN;
                 }                  }
                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&                  if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                         sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress;                          sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress;
                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&                  } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                         sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress;                          sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress;
                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&                  } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
                         sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress;                          sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress;
                 }                  }
         }          }
   
   #if __FreeBSD_version >= 500000
           mtx_init(&sc->aue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
               MTX_DEF | MTX_RECURSE);
   #endif
           AUE_LOCK(sc);
   
         /* Reset the adapter. */          /* Reset the adapter. */
         aue_reset(sc);          aue_reset(sc);
   
Line 733  USB_ATTACH(aue) Line 739  USB_ATTACH(aue)
   
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
         ifp->if_softc = sc;          ifp->if_softc = sc;
        ifp->if_unit = sc->aue_unit;        if_initname(ifp, "aue", sc->aue_unit);
        ifp->if_name = "aue"; 
         ifp->if_mtu = ETHERMTU;          ifp->if_mtu = ETHERMTU;
         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;          ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
         ifp->if_ioctl = aue_ioctl;          ifp->if_ioctl = aue_ioctl;
Line 761  USB_ATTACH(aue) Line 766  USB_ATTACH(aue)
         if (mii_phy_probe(self, &sc->aue_miibus,          if (mii_phy_probe(self, &sc->aue_miibus,
             aue_ifmedia_upd, aue_ifmedia_sts)) {              aue_ifmedia_upd, aue_ifmedia_sts)) {
                 printf("aue%d: MII without any PHY!\n", sc->aue_unit);                  printf("aue%d: MII without any PHY!\n", sc->aue_unit);
                splx(s);                AUE_UNLOCK(sc);
 #if __FreeBSD_version >= 500000
                 mtx_destroy(&sc->aue_mtx);
 #endif
                 USB_ATTACH_ERROR_RETURN;                  USB_ATTACH_ERROR_RETURN;
         }          }
   
Line 771  USB_ATTACH(aue) Line 779  USB_ATTACH(aue)
         /*          /*
          * Call MI attach routine.           * Call MI attach routine.
          */           */
   #if __FreeBSD_version >= 500000
           ether_ifattach(ifp, eaddr);
   #else
         ether_ifattach(ifp, ETHER_BPF_SUPPORTED);          ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
   #endif
         callout_handle_init(&sc->aue_stat_ch);          callout_handle_init(&sc->aue_stat_ch);
         usb_register_netisr();          usb_register_netisr();
        sc->aue_gone = 0;        sc->aue_dying = 0;
   
        splx(s);        AUE_UNLOCK(sc);
         USB_ATTACH_SUCCESS_RETURN;          USB_ATTACH_SUCCESS_RETURN;
 }  }
   
Line 785  aue_detach(device_ptr_t dev) Line 797  aue_detach(device_ptr_t dev)
 {  {
         struct aue_softc        *sc;          struct aue_softc        *sc;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         int                     s;  
   
         s = splusb();  
   
         sc = device_get_softc(dev);          sc = device_get_softc(dev);
           AUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
        sc->aue_gone = 1;        sc->aue_dying = 1;
         untimeout(aue_tick, sc, sc->aue_stat_ch);          untimeout(aue_tick, sc, sc->aue_stat_ch);
   #if __FreeBSD_version >= 500000
           ether_ifdetach(ifp);
   #else
         ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);          ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
   #endif
   
         if (sc->aue_ep[AUE_ENDPT_TX] != NULL)          if (sc->aue_ep[AUE_ENDPT_TX] != NULL)
                 usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);                  usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
Line 804  aue_detach(device_ptr_t dev) Line 818  aue_detach(device_ptr_t dev)
         if (sc->aue_ep[AUE_ENDPT_INTR] != NULL)          if (sc->aue_ep[AUE_ENDPT_INTR] != NULL)
                 usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);                  usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
 #endif  #endif
         splx(s);  
   
        return(0);        AUE_UNLOCK(sc);
 #if __FreeBSD_version >= 500000
         mtx_destroy(&sc->aue_mtx);
 #endif
 
         return (0);
 }  }
   
 /*  /*
Line 822  aue_newbuf(struct aue_softc *sc, struct Line 840  aue_newbuf(struct aue_softc *sc, struct
                 if (m_new == NULL) {                  if (m_new == NULL) {
                         printf("aue%d: no memory for rx list "                          printf("aue%d: no memory for rx list "
                             "-- packet dropped!\n", sc->aue_unit);                              "-- packet dropped!\n", sc->aue_unit);
                        return(ENOBUFS);                        return (ENOBUFS);
                 }                  }
   
                 MCLGET(m_new, M_DONTWAIT);                  MCLGET(m_new, M_DONTWAIT);
Line 830  aue_newbuf(struct aue_softc *sc, struct Line 848  aue_newbuf(struct aue_softc *sc, struct
                         printf("aue%d: no memory for rx list "                          printf("aue%d: no memory for rx list "
                             "-- packet dropped!\n", sc->aue_unit);                              "-- packet dropped!\n", sc->aue_unit);
                         m_freem(m_new);                          m_freem(m_new);
                        return(ENOBUFS);                        return (ENOBUFS);
                 }                  }
                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;                  m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
         } else {          } else {
Line 842  aue_newbuf(struct aue_softc *sc, struct Line 860  aue_newbuf(struct aue_softc *sc, struct
         m_adj(m_new, ETHER_ALIGN);          m_adj(m_new, ETHER_ALIGN);
         c->aue_mbuf = m_new;          c->aue_mbuf = m_new;
   
        return(0);        return (0);
 }  }
   
 Static int  Static int
Line 858  aue_rx_list_init(struct aue_softc *sc) Line 876  aue_rx_list_init(struct aue_softc *sc)
                 c->aue_sc = sc;                  c->aue_sc = sc;
                 c->aue_idx = i;                  c->aue_idx = i;
                 if (aue_newbuf(sc, c, NULL) == ENOBUFS)                  if (aue_newbuf(sc, c, NULL) == ENOBUFS)
                        return(ENOBUFS);                        return (ENOBUFS);
                 if (c->aue_xfer == NULL) {                  if (c->aue_xfer == NULL) {
                         c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);                          c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
                         if (c->aue_xfer == NULL)                          if (c->aue_xfer == NULL)
                                return(ENOBUFS);                                return (ENOBUFS);
                 }                  }
         }          }
   
        return(0);        return (0);
 }  }
   
 Static int  Static int
Line 885  aue_tx_list_init(struct aue_softc *sc) Line 903  aue_tx_list_init(struct aue_softc *sc)
                 if (c->aue_xfer == NULL) {                  if (c->aue_xfer == NULL) {
                         c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);                          c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
                         if (c->aue_xfer == NULL)                          if (c->aue_xfer == NULL)
                                return(ENOBUFS);                                return (ENOBUFS);
                 }                  }
                 c->aue_buf = malloc(AUE_BUFSZ, M_USBDEV, M_NOWAIT);                  c->aue_buf = malloc(AUE_BUFSZ, M_USBDEV, M_NOWAIT);
                 if (c->aue_buf == NULL)                  if (c->aue_buf == NULL)
                        return(ENOBUFS);                        return (ENOBUFS);
         }          }
   
        return(0);        return (0);
 }  }
   
 #ifdef AUE_INTR_PIPE  #ifdef AUE_INTR_PIPE
 Static void  Static void
 aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)  aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = priv;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         struct aue_intrpkt      *p;          struct aue_intrpkt      *p;
         int                     s;  
   
         s = splimp();  
   
        sc = priv;        AUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
         if (!(ifp->if_flags & IFF_RUNNING)) {          if (!(ifp->if_flags & IFF_RUNNING)) {
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {                  if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                        splx(s);                        AUE_UNLOCK(sc);
                         return;                          return;
                 }                  }
                 printf("aue%d: usb error on intr: %s\n", sc->aue_unit,                  printf("aue%d: usb error on intr: %s\n", sc->aue_unit,
                     usbd_errstr(status));                      usbd_errstr(status));
                 if (status == USBD_STALLED)                  if (status == USBD_STALLED)
                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);                          usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 935  aue_intr(usbd_xfer_handle xfer, usbd_pri Line 950  aue_intr(usbd_xfer_handle xfer, usbd_pri
         if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL & AUE_TXSTAT0_EXCESSCOLL))          if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL & AUE_TXSTAT0_EXCESSCOLL))
                 ifp->if_collisions++;                  ifp->if_collisions++;
   
        splx(s);        AUE_UNLOCK(sc);
         return;          return;
 }  }
 #endif  #endif
Line 947  aue_rxstart(struct ifnet *ifp) Line 962  aue_rxstart(struct ifnet *ifp)
         struct aue_chain        *c;          struct aue_chain        *c;
   
         sc = ifp->if_softc;          sc = ifp->if_softc;
           AUE_LOCK(sc);
         c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod];          c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod];
   
         if (aue_newbuf(sc, c, NULL) == ENOBUFS) {          if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
                 ifp->if_ierrors++;                  ifp->if_ierrors++;
                   AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 960  aue_rxstart(struct ifnet *ifp) Line 977  aue_rxstart(struct ifnet *ifp)
             USBD_NO_TIMEOUT, aue_rxeof);              USBD_NO_TIMEOUT, aue_rxeof);
         usbd_transfer(c->aue_xfer);          usbd_transfer(c->aue_xfer);
   
           AUE_UNLOCK(sc);
         return;          return;
 }  }
   
Line 977  aue_rxeof(usbd_xfer_handle xfer, usbd_pr Line 995  aue_rxeof(usbd_xfer_handle xfer, usbd_pr
         int                     total_len = 0;          int                     total_len = 0;
         struct aue_rxpkt        r;          struct aue_rxpkt        r;
   
        c = priv;        if (sc->aue_dying)
        sc = c->aue_sc;                return;
         AUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
        if (!(ifp->if_flags & IFF_RUNNING))        if (!(ifp->if_flags & IFF_RUNNING)) {
                 AUE_UNLOCK(sc);
                 return;                  return;
           }
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                         AUE_UNLOCK(sc);
                         return;                          return;
                printf("aue%d: usb error on rx: %s\n", sc->aue_unit,                }
                    usbd_errstr(status));                if (usbd_ratecheck(&sc->aue_rx_notice))
                         printf("aue%d: usb error on rx: %s\n", sc->aue_unit,
                             usbd_errstr(status));
                 if (status == USBD_STALLED)                  if (status == USBD_STALLED)
                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);                          usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
                 goto done;                  goto done;
Line 1021  aue_rxeof(usbd_xfer_handle xfer, usbd_pr Line 1045  aue_rxeof(usbd_xfer_handle xfer, usbd_pr
   
         /* Put the packet on the special USB input queue. */          /* Put the packet on the special USB input queue. */
         usb_ether_input(m);          usb_ether_input(m);
        AUE_UNLOCK(sc);
         return;          return;
 done:  done:
   
Line 1031  done: Line 1055  done:
             USBD_NO_TIMEOUT, aue_rxeof);              USBD_NO_TIMEOUT, aue_rxeof);
         usbd_transfer(xfer);          usbd_transfer(xfer);
   
           AUE_UNLOCK(sc);
         return;          return;
 }  }
   
Line 1042  done: Line 1067  done:
 Static void  Static void
 aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)  aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {  {
        struct aue_softc        *sc;        struct aue_chain        *c = priv;
        struct aue_chain   *c;        struct aue_softc        *sc = c->aue_sc;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        s = splimp();        AUE_LOCK(sc);
 
        c = priv; 
        sc = c->aue_sc; 
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {                  if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                        splx(s);                        AUE_UNLOCK(sc);
                         return;                          return;
                 }                  }
                 printf("aue%d: usb error on tx: %s\n", sc->aue_unit,                  printf("aue%d: usb error on tx: %s\n", sc->aue_unit,
                     usbd_errstr(status));                      usbd_errstr(status));
                 if (status == USBD_STALLED)                  if (status == USBD_STALLED)
                         usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);                          usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 1082  aue_txeof(usbd_xfer_handle xfer, usbd_pr Line 1103  aue_txeof(usbd_xfer_handle xfer, usbd_pr
         else          else
                 ifp->if_opackets++;                  ifp->if_opackets++;
   
        splx(s);        AUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1090  aue_txeof(usbd_xfer_handle xfer, usbd_pr Line 1111  aue_txeof(usbd_xfer_handle xfer, usbd_pr
 Static void  Static void
 aue_tick(void *xsc)  aue_tick(void *xsc)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = xsc;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         struct mii_data         *mii;          struct mii_data         *mii;
         int                     s;  
   
         s = splimp();  
   
        sc = xsc;        if (sc == NULL)
 
        if (sc == NULL) { 
                splx(s); 
                 return;                  return;
        }
         AUE_LOCK(sc);
   
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
        mii = device_get_softc(sc->aue_miibus);        mii = GET_MII(sc);
         if (mii == NULL) {          if (mii == NULL) {
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
         mii_tick(mii);          mii_tick(mii);
        if (!sc->aue_link) {        if (!sc->aue_link && mii->mii_media_status & IFM_ACTIVE &&
                mii_pollstat(mii);            IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
                if (mii->mii_media_status & IFM_ACTIVE &&                sc->aue_link++;
                    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)                if (ifp->if_snd.ifq_head != NULL)
                        sc->aue_link++;                        aue_start(ifp);
                        if (ifp->if_snd.ifq_head != NULL) 
                                aue_start(ifp); 
         }          }
   
         sc->aue_stat_ch = timeout(aue_tick, sc, hz);          sc->aue_stat_ch = timeout(aue_tick, sc, hz);
   
        splx(s);        AUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1163  aue_encap(struct aue_softc *sc, struct m Line 1177  aue_encap(struct aue_softc *sc, struct m
         err = usbd_transfer(c->aue_xfer);          err = usbd_transfer(c->aue_xfer);
         if (err != USBD_IN_PROGRESS) {          if (err != USBD_IN_PROGRESS) {
                 aue_stop(sc);                  aue_stop(sc);
                return(EIO);                return (EIO);
         }          }
   
         sc->aue_cdata.aue_tx_cnt++;          sc->aue_cdata.aue_tx_cnt++;
   
        return(0);        return (0);
 }  }
   
 Static void  Static void
 aue_start(struct ifnet *ifp)  aue_start(struct ifnet *ifp)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = ifp->if_softc;
         struct mbuf             *m_head = NULL;          struct mbuf             *m_head = NULL;
   
        sc = ifp->if_softc;        AUE_LOCK(sc);
   
        if (!sc->aue_link)        if (!sc->aue_link) {
                 AUE_UNLOCK(sc);
                 return;                  return;
           }
   
        if (ifp->if_flags & IFF_OACTIVE)        if (ifp->if_flags & IFF_OACTIVE) {
                 AUE_UNLOCK(sc);
                 return;                  return;
           }
   
         IF_DEQUEUE(&ifp->if_snd, m_head);          IF_DEQUEUE(&ifp->if_snd, m_head);
        if (m_head == NULL)        if (m_head == NULL) {
                 AUE_UNLOCK(sc);
                 return;                  return;
           }
   
         if (aue_encap(sc, m_head, 0)) {          if (aue_encap(sc, m_head, 0)) {
                 IF_PREPEND(&ifp->if_snd, m_head);                  IF_PREPEND(&ifp->if_snd, m_head);
                 ifp->if_flags |= IFF_OACTIVE;                  ifp->if_flags |= IFF_OACTIVE;
                   AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 1199  aue_start(struct ifnet *ifp) Line 1220  aue_start(struct ifnet *ifp)
          * If there's a BPF listener, bounce a copy of this frame           * If there's a BPF listener, bounce a copy of this frame
          * to him.           * to him.
          */           */
        if (ifp->if_bpf)        BPF_MTAP(ifp, m_head);
                bpf_mtap(ifp, m_head); 
   
         ifp->if_flags |= IFF_OACTIVE;          ifp->if_flags |= IFF_OACTIVE;
   
Line 1208  aue_start(struct ifnet *ifp) Line 1228  aue_start(struct ifnet *ifp)
          * Set a timeout in case the chip goes out to lunch.           * Set a timeout in case the chip goes out to lunch.
          */           */
         ifp->if_timer = 5;          ifp->if_timer = 5;
           AUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1217  aue_init(void *xsc) Line 1238  aue_init(void *xsc)
 {  {
         struct aue_softc        *sc = xsc;          struct aue_softc        *sc = xsc;
         struct ifnet            *ifp = &sc->arpcom.ac_if;          struct ifnet            *ifp = &sc->arpcom.ac_if;
        struct mii_data         *mii;        struct mii_data         *mii = GET_MII(sc);
         struct aue_chain        *c;          struct aue_chain        *c;
         usbd_status             err;          usbd_status             err;
        int                     i, s;        int                     i;
   
        if (ifp->if_flags & IFF_RUNNING)        AUE_LOCK(sc);
                return; 
   
        s = splimp();        if (ifp->if_flags & IFF_RUNNING) {
                 AUE_UNLOCK(sc);
                 return;
         }
   
         /*          /*
          * Cancel pending I/O and free all RX/TX buffers.           * Cancel pending I/O and free all RX/TX buffers.
          */           */
         aue_reset(sc);          aue_reset(sc);
   
         mii = device_get_softc(sc->aue_miibus);  
   
         /* Set MAC address */          /* Set MAC address */
         for (i = 0; i < ETHER_ADDR_LEN; i++)          for (i = 0; i < ETHER_ADDR_LEN; i++)
                csr_write_1(sc, AUE_PAR0 + i, sc->arpcom.ac_enaddr[i]);                aue_csr_write_1(sc, AUE_PAR0 + i, sc->arpcom.ac_enaddr[i]);
   
          /* If we want promiscuous mode, set the allframes bit. */           /* If we want promiscuous mode, set the allframes bit. */
        if (ifp->if_flags & IFF_PROMISC) {        if (ifp->if_flags & IFF_PROMISC)
                 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);                  AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
        } else {        else
                 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);                  AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
         }  
   
         /* Init TX ring. */          /* Init TX ring. */
         if (aue_tx_list_init(sc) == ENOBUFS) {          if (aue_tx_list_init(sc) == ENOBUFS) {
                 printf("aue%d: tx list init failed\n", sc->aue_unit);                  printf("aue%d: tx list init failed\n", sc->aue_unit);
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
         /* Init RX ring. */          /* Init RX ring. */
         if (aue_rx_list_init(sc) == ENOBUFS) {          if (aue_rx_list_init(sc) == ENOBUFS) {
                 printf("aue%d: rx list init failed\n", sc->aue_unit);                  printf("aue%d: rx list init failed\n", sc->aue_unit);
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 1267  aue_init(void *xsc) Line 1287  aue_init(void *xsc)
         aue_setmulti(sc);          aue_setmulti(sc);
   
         /* Enable RX and TX */          /* Enable RX and TX */
        csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND|AUE_CTL0_RX_ENB);        aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
         AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);          AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
         AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);          AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
   
         mii_mediachg(mii);          mii_mediachg(mii);
   
         /* Open RX and TX pipes. */          /* Open RX and TX pipes. */
Line 1278  aue_init(void *xsc) Line 1299  aue_init(void *xsc)
         if (err) {          if (err) {
                 printf("aue%d: open rx pipe failed: %s\n",                  printf("aue%d: open rx pipe failed: %s\n",
                     sc->aue_unit, usbd_errstr(err));                      sc->aue_unit, usbd_errstr(err));
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
         err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],          err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
Line 1286  aue_init(void *xsc) Line 1307  aue_init(void *xsc)
         if (err) {          if (err) {
                 printf("aue%d: open tx pipe failed: %s\n",                  printf("aue%d: open tx pipe failed: %s\n",
                     sc->aue_unit, usbd_errstr(err));                      sc->aue_unit, usbd_errstr(err));
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 1298  aue_init(void *xsc) Line 1319  aue_init(void *xsc)
         if (err) {          if (err) {
                 printf("aue%d: open intr pipe failed: %s\n",                  printf("aue%d: open intr pipe failed: %s\n",
                     sc->aue_unit, usbd_errstr(err));                      sc->aue_unit, usbd_errstr(err));
                splx(s);                AUE_UNLOCK(sc);
                 return;                  return;
         }          }
 #endif  #endif
Line 1315  aue_init(void *xsc) Line 1336  aue_init(void *xsc)
         ifp->if_flags |= IFF_RUNNING;          ifp->if_flags |= IFF_RUNNING;
         ifp->if_flags &= ~IFF_OACTIVE;          ifp->if_flags &= ~IFF_OACTIVE;
   
         (void)splx(s);  
   
         sc->aue_stat_ch = timeout(aue_tick, sc, hz);          sc->aue_stat_ch = timeout(aue_tick, sc, hz);
   
           AUE_UNLOCK(sc);
   
         return;          return;
 }  }
   
Line 1328  aue_init(void *xsc) Line 1349  aue_init(void *xsc)
 Static int  Static int
 aue_ifmedia_upd(struct ifnet *ifp)  aue_ifmedia_upd(struct ifnet *ifp)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = ifp->if_softc;
        struct mii_data         *mii;        struct mii_data         *mii = GET_MII(sc);
 
        sc = ifp->if_softc; 
   
         mii = device_get_softc(sc->aue_miibus);  
         sc->aue_link = 0;          sc->aue_link = 0;
         if (mii->mii_instance) {          if (mii->mii_instance) {
                 struct mii_softc        *miisc;                  struct mii_softc        *miisc;
                for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;                LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
                    miisc = LIST_NEXT(miisc, mii_list)) 
                          mii_phy_reset(miisc);                           mii_phy_reset(miisc);
         }          }
         mii_mediachg(mii);          mii_mediachg(mii);
   
        return(0);        return (0);
 }  }
   
 /*  /*
Line 1352  aue_ifmedia_upd(struct ifnet *ifp) Line 1369  aue_ifmedia_upd(struct ifnet *ifp)
 Static void  Static void
 aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)  aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = ifp->if_softc;
        struct mii_data         *mii;        struct mii_data         *mii = GET_MII(sc);
 
        sc = ifp->if_softc; 
   
         mii = device_get_softc(sc->aue_miibus);  
         mii_pollstat(mii);          mii_pollstat(mii);
         ifmr->ifm_active = mii->mii_media_active;          ifmr->ifm_active = mii->mii_media_active;
         ifmr->ifm_status = mii->mii_media_status;          ifmr->ifm_status = mii->mii_media_status;
Line 1369  Static int Line 1383  Static int
 aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)  aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {  {
         struct aue_softc        *sc = ifp->if_softc;          struct aue_softc        *sc = ifp->if_softc;
        struct ifreq            *ifr = (struct ifreq *) data;        struct ifreq            *ifr = (struct ifreq *)data;
         struct mii_data         *mii;          struct mii_data         *mii;
        int                     s, error = 0;        int                     error = 0;
   
        s = splimp();        AUE_LOCK(sc);
   
         switch(command) {          switch(command) {
         case SIOCSIFADDR:  
         case SIOCGIFADDR:  
         case SIOCSIFMTU:  
                 error = ether_ioctl(ifp, command, data);  
                 break;  
         case SIOCSIFFLAGS:          case SIOCSIFFLAGS:
                 if (ifp->if_flags & IFF_UP) {                  if (ifp->if_flags & IFF_UP) {
                         if (ifp->if_flags & IFF_RUNNING &&                          if (ifp->if_flags & IFF_RUNNING &&
Line 1407  aue_ioctl(struct ifnet *ifp, u_long comm Line 1416  aue_ioctl(struct ifnet *ifp, u_long comm
                 break;                  break;
         case SIOCGIFMEDIA:          case SIOCGIFMEDIA:
         case SIOCSIFMEDIA:          case SIOCSIFMEDIA:
                mii = device_get_softc(sc->aue_miibus);                mii = GET_MII(sc);
                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);                  error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
                 break;                  break;
         default:          default:
                error = EINVAL;                error = ether_ioctl(ifp, command, data);
                 break;                  break;
         }          }
   
        (void)splx(s);        AUE_UNLOCK(sc);
   
        return(error);        return (error);
 }  }
   
 Static void  Static void
 aue_watchdog(struct ifnet *ifp)  aue_watchdog(struct ifnet *ifp)
 {  {
        struct aue_softc        *sc;        struct aue_softc        *sc = ifp->if_softc;
         struct aue_chain        *c;          struct aue_chain        *c;
         usbd_status             stat;          usbd_status             stat;
   
        sc = ifp->if_softc;        AUE_LOCK(sc);
   
         ifp->if_oerrors++;          ifp->if_oerrors++;
         printf("aue%d: watchdog timeout\n", sc->aue_unit);          printf("aue%d: watchdog timeout\n", sc->aue_unit);
Line 1438  aue_watchdog(struct ifnet *ifp) Line 1447  aue_watchdog(struct ifnet *ifp)
   
         if (ifp->if_snd.ifq_head != NULL)          if (ifp->if_snd.ifq_head != NULL)
                 aue_start(ifp);                  aue_start(ifp);
        AUE_UNLOCK(sc);
         return;          return;
 }  }
   
Line 1453  aue_stop(struct aue_softc *sc) Line 1462  aue_stop(struct aue_softc *sc)
         struct ifnet            *ifp;          struct ifnet            *ifp;
         int                     i;          int                     i;
   
           AUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
         ifp->if_timer = 0;          ifp->if_timer = 0;
   
        csr_write_1(sc, AUE_CTL0, 0);        aue_csr_write_1(sc, AUE_CTL0, 0);
        csr_write_1(sc, AUE_CTL1, 0);        aue_csr_write_1(sc, AUE_CTL1, 0);
         aue_reset(sc);          aue_reset(sc);
         untimeout(aue_tick, sc, sc->aue_stat_ch);          untimeout(aue_tick, sc, sc->aue_stat_ch);
   
Line 1546  aue_stop(struct aue_softc *sc) Line 1556  aue_stop(struct aue_softc *sc)
         sc->aue_link = 0;          sc->aue_link = 0;
   
         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);          ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
           AUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1560  aue_shutdown(device_ptr_t dev) Line 1571  aue_shutdown(device_ptr_t dev)
         struct aue_softc        *sc;          struct aue_softc        *sc;
   
         sc = device_get_softc(dev);          sc = device_get_softc(dev);
        sc->aue_dying++;
         AUE_LOCK(sc);
         aue_reset(sc);          aue_reset(sc);
         aue_stop(sc);          aue_stop(sc);
           AUE_UNLOCK(sc);
   
         return;          return;
 }  }

Removed from v.1.5  
changed lines
  Added in v.1.6