[BACK]Return to if_kue.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Annotation of src/sys/dev/usb/if_kue.c, Revision 1.88

1.88    ! ozaki-r     1: /*     $NetBSD: if_kue.c,v 1.87 2016/11/25 12:56:29 skrll Exp $        */
1.77      mrg         2:
1.1       augustss    3: /*
                      4:  * Copyright (c) 1997, 1998, 1999, 2000
                      5:  *     Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Bill Paul.
                     18:  * 4. Neither the name of the author nor the names of any co-contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
                     26:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     32:  * THE POSSIBILITY OF SUCH DAMAGE.
                     33:  *
                     34:  * $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $
                     35:  */
                     36:
                     37: /*
                     38:  * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver.
                     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 KLSI USB to ethernet adapter chip contains an USB serial interface,
                     47:  * ethernet MAC and embedded microcontroller (called the QT Engine).
                     48:  * The chip must have firmware loaded into it before it will operate.
                     49:  * Packets are passed between the chip and host via bulk transfers.
                     50:  * There is an interrupt endpoint mentioned in the software spec, however
                     51:  * it's currently unused. This device is 10Mbps half-duplex only, hence
                     52:  * there is no media selection logic. The MAC supports a 128 entry
                     53:  * multicast filter, though the exact size of the filter can depend
                     54:  * on the firmware. Curiously, while the software spec describes various
                     55:  * ethernet statistics counters, my sample adapter and firmware combination
                     56:  * claims not to support any statistics counters at all.
                     57:  *
                     58:  * Note that once we load the firmware in the device, we have to be
                     59:  * careful not to load it again: if you restart your computer but
                     60:  * leave the adapter attached to the USB controller, it may remain
                     61:  * powered on and retain its firmware. In this case, we don't need
                     62:  * to load the firmware a second time.
                     63:  *
                     64:  * Special thanks to Rob Furr for providing an ADS Technologies
                     65:  * adapter for development and testing. No monkeys were harmed during
                     66:  * the development of this driver.
                     67:  */
                     68:
                     69: /*
                     70:  * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
                     71:  */
1.44      lukem      72:
                     73: #include <sys/cdefs.h>
1.88    ! ozaki-r    74: __KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.87 2016/11/25 12:56:29 skrll Exp $");
1.1       augustss   75:
1.79      christos   76: #ifdef _KERNEL_OPT
1.1       augustss   77: #include "opt_inet.h"
1.87      skrll      78: #include "opt_usb.h"
1.79      christos   79: #endif
1.1       augustss   80:
                     81: #include <sys/param.h>
                     82: #include <sys/systm.h>
                     83: #include <sys/sockio.h>
                     84: #include <sys/mbuf.h>
1.84      skrll      85: #include <sys/kmem.h>
1.1       augustss   86: #include <sys/kernel.h>
                     87: #include <sys/socket.h>
1.37      augustss   88: #include <sys/device.h>
                     89: #include <sys/proc.h>
1.82      riastrad   90: #include <sys/rndsource.h>
1.1       augustss   91:
                     92: #include <net/if.h>
                     93: #include <net/if_arp.h>
                     94: #include <net/if_dl.h>
                     95: #include <net/bpf.h>
1.77      mrg        96: #include <net/if_ether.h>
1.1       augustss   97:
                     98: #ifdef INET
1.49      augustss   99: #include <netinet/in.h>
1.1       augustss  100: #include <netinet/if_inarp.h>
                    101: #endif
                    102:
                    103: #include <dev/usb/usb.h>
                    104: #include <dev/usb/usbdi.h>
                    105: #include <dev/usb/usbdi_util.h>
1.77      mrg       106: #include <dev/usb/usbdivar.h>
1.1       augustss  107: #include <dev/usb/usbdevs.h>
                    108:
                    109: #include <dev/usb/if_kuereg.h>
                    110: #include <dev/usb/kue_fw.h>
                    111:
                    112: #ifdef KUE_DEBUG
1.74      dyoung    113: #define DPRINTF(x)     if (kuedebug) printf x
                    114: #define DPRINTFN(n,x)  if (kuedebug >= (n)) printf x
1.1       augustss  115: int    kuedebug = 0;
                    116: #else
                    117: #define DPRINTF(x)
                    118: #define DPRINTFN(n,x)
                    119: #endif
                    120:
                    121: /*
                    122:  * Various supported device vendors/products.
                    123:  */
1.72      tsutsui   124: static const struct usb_devno kue_devs[] = {
1.42      augustss  125:        { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
                    126:        { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
                    127:        { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 },
                    128:        { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
1.43      augustss  129:        { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX },
1.1       augustss  130:        { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
1.43      augustss  131:        { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA },
1.1       augustss  132:        { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
1.43      augustss  133:        { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C },
1.42      augustss  134:        { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
                    135:        { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
                    136:        { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
1.43      augustss  137:        { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 },
                    138:        { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 },
1.42      augustss  139:        { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
1.43      augustss  140:        { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA },
                    141:        { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 },
1.42      augustss  142:        { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
1.43      augustss  143:        { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN },
1.42      augustss  144:        { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
1.43      augustss  145:        { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA },
1.1       augustss  146:        { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
1.43      augustss  147:        { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X },
1.1       augustss  148:        { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
                    149:        { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
1.40      augustss  150:        { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 },
1.43      augustss  151:        { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 },
                    152:        { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 },
                    153:        { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA },
                    154:        { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA },
1.52      augustss  155:        { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E },
1.1       augustss  156:        { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
                    157: };
1.46      augustss  158: #define kue_lookup(v, p) (usb_lookup(kue_devs, v, p))
1.1       augustss  159:
1.74      dyoung    160: int kue_match(device_t, cfdata_t, void *);
                    161: void kue_attach(device_t, device_t, void *);
                    162: int kue_detach(device_t, int);
                    163: int kue_activate(device_t, enum devact);
                    164: extern struct cfdriver kue_cd;
                    165: CFATTACH_DECL_NEW(kue, sizeof(struct kue_softc), kue_match, kue_attach,
                    166:     kue_detach, kue_activate);
1.1       augustss  167:
1.72      tsutsui   168: static int kue_tx_list_init(struct kue_softc *);
                    169: static int kue_rx_list_init(struct kue_softc *);
                    170: static int kue_send(struct kue_softc *, struct mbuf *, int);
                    171: static int kue_open_pipes(struct kue_softc *);
1.84      skrll     172: static void kue_rxeof(struct usbd_xfer *, void *, usbd_status);
                    173: static void kue_txeof(struct usbd_xfer *, void *, usbd_status);
1.72      tsutsui   174: static void kue_start(struct ifnet *);
                    175: static int kue_ioctl(struct ifnet *, u_long, void *);
                    176: static void kue_init(void *);
                    177: static void kue_stop(struct kue_softc *);
                    178: static void kue_watchdog(struct ifnet *);
1.29      augustss  179:
1.72      tsutsui   180: static void kue_setmulti(struct kue_softc *);
                    181: static void kue_reset(struct kue_softc *);
1.29      augustss  182:
1.72      tsutsui   183: static usbd_status kue_ctl(struct kue_softc *, int, uint8_t,
1.71      tsutsui   184:                           uint16_t, void *, uint32_t);
1.72      tsutsui   185: static usbd_status kue_setword(struct kue_softc *, uint8_t, uint16_t);
                    186: static int kue_load_fw(struct kue_softc *);
1.1       augustss  187:
1.72      tsutsui   188: static usbd_status
1.71      tsutsui   189: kue_setword(struct kue_softc *sc, uint8_t breq, uint16_t word)
1.1       augustss  190: {
                    191:        usb_device_request_t    req;
                    192:
1.74      dyoung    193:        DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  194:
                    195:        req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
                    196:        req.bRequest = breq;
                    197:        USETW(req.wValue, word);
                    198:        USETW(req.wIndex, 0);
                    199:        USETW(req.wLength, 0);
                    200:
1.84      skrll     201:        return usbd_do_request(sc->kue_udev, &req, NULL);
1.1       augustss  202: }
                    203:
1.72      tsutsui   204: static usbd_status
1.71      tsutsui   205: kue_ctl(struct kue_softc *sc, int rw, uint8_t breq, uint16_t val,
                    206:        void *data, uint32_t len)
1.1       augustss  207: {
                    208:        usb_device_request_t    req;
                    209:
1.74      dyoung    210:        DPRINTFN(10,("%s: %s: enter, len=%d\n", device_xname(sc->kue_dev),
1.48      augustss  211:                     __func__, len));
1.1       augustss  212:
                    213:        if (rw == KUE_CTL_WRITE)
                    214:                req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
                    215:        else
                    216:                req.bmRequestType = UT_READ_VENDOR_DEVICE;
                    217:
                    218:        req.bRequest = breq;
                    219:        USETW(req.wValue, val);
                    220:        USETW(req.wIndex, 0);
                    221:        USETW(req.wLength, len);
                    222:
1.84      skrll     223:        return usbd_do_request(sc->kue_udev, &req, data);
1.1       augustss  224: }
                    225:
1.72      tsutsui   226: static int
1.29      augustss  227: kue_load_fw(struct kue_softc *sc)
1.1       augustss  228: {
1.36      augustss  229:        usb_device_descriptor_t dd;
1.1       augustss  230:        usbd_status             err;
                    231:
1.74      dyoung    232:        DPRINTFN(1,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  233:
                    234:        /*
                    235:         * First, check if we even need to load the firmware.
                    236:         * If the device was still attached when the system was
                    237:         * rebooted, it may already have firmware loaded in it.
                    238:         * If this is the case, we don't need to do it again.
                    239:         * And in fact, if we try to load it again, we'll hang,
                    240:         * so we have to avoid this condition if we don't want
                    241:         * to look stupid.
                    242:         *
1.65      dyoung    243:         * We can test this quickly by checking the bcdRevision
                    244:         * code. The NIC will return a different revision code if
                    245:         * it's probed while the firmware is still loaded and
                    246:         * running.
                    247:         */
1.36      augustss  248:        if (usbd_get_device_desc(sc->kue_udev, &dd))
1.84      skrll     249:                return EIO;
1.65      dyoung    250:        if (UGETW(dd.bcdDevice) == KUE_WARM_REV) {
1.1       augustss  251:                printf("%s: warm boot, no firmware download\n",
1.74      dyoung    252:                       device_xname(sc->kue_dev));
1.84      skrll     253:                return 0;
1.1       augustss  254:        }
                    255:
                    256:        printf("%s: cold boot, downloading firmware\n",
1.74      dyoung    257:               device_xname(sc->kue_dev));
1.1       augustss  258:
                    259:        /* Load code segment */
1.49      augustss  260:        DPRINTFN(1,("%s: kue_load_fw: download code_seg\n",
1.74      dyoung    261:                    device_xname(sc->kue_dev)));
1.54      christos  262:        /*XXXUNCONST*/
1.1       augustss  263:        err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.54      christos  264:            0, __UNCONST(kue_code_seg), sizeof(kue_code_seg));
1.1       augustss  265:        if (err) {
                    266:                printf("%s: failed to load code segment: %s\n",
1.74      dyoung    267:                    device_xname(sc->kue_dev), usbd_errstr(err));
1.84      skrll     268:                        return EIO;
1.1       augustss  269:        }
                    270:
                    271:        /* Load fixup segment */
1.49      augustss  272:        DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n",
1.74      dyoung    273:                    device_xname(sc->kue_dev)));
1.54      christos  274:        /*XXXUNCONST*/
1.1       augustss  275:        err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.54      christos  276:            0, __UNCONST(kue_fix_seg), sizeof(kue_fix_seg));
1.1       augustss  277:        if (err) {
                    278:                printf("%s: failed to load fixup segment: %s\n",
1.74      dyoung    279:                    device_xname(sc->kue_dev), usbd_errstr(err));
1.84      skrll     280:                        return EIO;
1.1       augustss  281:        }
                    282:
                    283:        /* Send trigger command. */
1.49      augustss  284:        DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n",
1.74      dyoung    285:                    device_xname(sc->kue_dev)));
1.54      christos  286:        /*XXXUNCONST*/
1.1       augustss  287:        err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.54      christos  288:            0, __UNCONST(kue_trig_seg), sizeof(kue_trig_seg));
1.1       augustss  289:        if (err) {
                    290:                printf("%s: failed to load trigger segment: %s\n",
1.74      dyoung    291:                    device_xname(sc->kue_dev), usbd_errstr(err));
1.84      skrll     292:                        return EIO;
1.1       augustss  293:        }
                    294:
                    295:        usbd_delay_ms(sc->kue_udev, 10);
                    296:
                    297:        /*
                    298:         * Reload device descriptor.
                    299:         * Why? The chip without the firmware loaded returns
                    300:         * one revision code. The chip with the firmware
                    301:         * loaded and running returns a *different* revision
                    302:         * code. This confuses the quirk mechanism, which is
                    303:         * dependent on the revision data.
                    304:         */
                    305:        (void)usbd_reload_device_desc(sc->kue_udev);
                    306:
1.74      dyoung    307:        DPRINTFN(1,("%s: %s: done\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  308:
                    309:        /* Reset the adapter. */
                    310:        kue_reset(sc);
                    311:
1.84      skrll     312:        return 0;
1.1       augustss  313: }
                    314:
1.72      tsutsui   315: static void
1.29      augustss  316: kue_setmulti(struct kue_softc *sc)
1.1       augustss  317: {
                    318:        struct ifnet            *ifp = GET_IFP(sc);
                    319:        struct ether_multi      *enm;
                    320:        struct ether_multistep  step;
                    321:        int                     i;
                    322:
1.74      dyoung    323:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  324:
1.38      enami     325:        if (ifp->if_flags & IFF_PROMISC) {
                    326: allmulti:
                    327:                ifp->if_flags |= IFF_ALLMULTI;
1.1       augustss  328:                sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
                    329:                sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
                    330:                kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
                    331:                return;
                    332:        }
                    333:
                    334:        sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI;
                    335:
                    336:        i = 0;
                    337:        ETHER_FIRST_MULTI(step, &sc->kue_ec, enm);
                    338:        while (enm != NULL) {
1.38      enami     339:                if (i == KUE_MCFILTCNT(sc) ||
                    340:                    memcmp(enm->enm_addrlo, enm->enm_addrhi,
                    341:                        ETHER_ADDR_LEN) != 0)
                    342:                        goto allmulti;
                    343:
1.1       augustss  344:                memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN);
                    345:                ETHER_NEXT_MULTI(step, enm);
                    346:                i++;
                    347:        }
                    348:
1.38      enami     349:        ifp->if_flags &= ~IFF_ALLMULTI;
                    350:
                    351:        sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
                    352:        kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
                    353:            i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
1.1       augustss  354:
                    355:        kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
                    356: }
                    357:
                    358: /*
                    359:  * Issue a SET_CONFIGURATION command to reset the MAC. This should be
                    360:  * done after the firmware is loaded into the adapter in order to
                    361:  * bring it into proper operation.
                    362:  */
1.72      tsutsui   363: static void
1.29      augustss  364: kue_reset(struct kue_softc *sc)
1.1       augustss  365: {
1.74      dyoung    366:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  367:
1.50      augustss  368:        if (usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 1) ||
                    369:            usbd_device2interface_handle(sc->kue_udev, KUE_IFACE_IDX,
                    370:                                         &sc->kue_iface))
1.74      dyoung    371:                printf("%s: reset failed\n", device_xname(sc->kue_dev));
1.1       augustss  372:
                    373:        /* Wait a little while for the chip to get its brains in order. */
                    374:        usbd_delay_ms(sc->kue_udev, 10);
                    375: }
                    376:
                    377: /*
                    378:  * Probe for a KLSI chip.
                    379:  */
1.74      dyoung    380: int
                    381: kue_match(device_t parent, cfdata_t match, void *aux)
1.1       augustss  382: {
1.74      dyoung    383:        struct usb_attach_arg *uaa = aux;
1.1       augustss  384:
                    385:        DPRINTFN(25,("kue_match: enter\n"));
                    386:
1.84      skrll     387:        return kue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
                    388:                UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
1.1       augustss  389: }
                    390:
                    391: /*
                    392:  * Attach the interface. Allocate softc structures, do
                    393:  * setup and ethernet/BPF attach.
                    394:  */
1.74      dyoung    395: void
                    396: kue_attach(device_t parent, device_t self, void *aux)
1.1       augustss  397: {
1.74      dyoung    398:        struct kue_softc *sc = device_private(self);
                    399:        struct usb_attach_arg *uaa = aux;
1.53      augustss  400:        char                    *devinfop;
1.1       augustss  401:        int                     s;
                    402:        struct ifnet            *ifp;
1.84      skrll     403:        struct usbd_device *    dev = uaa->uaa_device;
                    404:        struct usbd_interface * iface;
1.1       augustss  405:        usbd_status             err;
                    406:        usb_interface_descriptor_t      *id;
                    407:        usb_endpoint_descriptor_t       *ed;
                    408:        int                     i;
                    409:
                    410:        DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev));
                    411:
1.63      cube      412:        sc->kue_dev = self;
                    413:
1.66      plunky    414:        aprint_naive("\n");
                    415:        aprint_normal("\n");
                    416:
1.53      augustss  417:        devinfop = usbd_devinfo_alloc(dev, 0);
1.63      cube      418:        aprint_normal_dev(self, "%s\n", devinfop);
1.53      augustss  419:        usbd_devinfo_free(devinfop);
1.1       augustss  420:
1.31      augustss  421:        err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1);
1.1       augustss  422:        if (err) {
1.78      skrll     423:                aprint_error_dev(self, "failed to set configuration"
                    424:                    ", err=%s\n", usbd_errstr(err));
1.74      dyoung    425:                return;
1.1       augustss  426:        }
                    427:
                    428:        sc->kue_udev = dev;
1.84      skrll     429:        sc->kue_product = uaa->uaa_product;
                    430:        sc->kue_vendor = uaa->uaa_vendor;
1.1       augustss  431:
                    432:        /* Load the firmware into the NIC. */
                    433:        if (kue_load_fw(sc)) {
1.63      cube      434:                aprint_error_dev(self, "loading firmware failed\n");
1.74      dyoung    435:                return;
1.1       augustss  436:        }
                    437:
                    438:        err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface);
                    439:        if (err) {
1.63      cube      440:                aprint_error_dev(self, "getting interface handle failed\n");
1.74      dyoung    441:                return;
1.1       augustss  442:        }
                    443:
                    444:        sc->kue_iface = iface;
                    445:        id = usbd_get_interface_descriptor(iface);
                    446:
                    447:        /* Find endpoints. */
                    448:        for (i = 0; i < id->bNumEndpoints; i++) {
                    449:                ed = usbd_interface2endpoint_descriptor(iface, i);
                    450:                if (ed == NULL) {
1.63      cube      451:                        aprint_error_dev(self, "couldn't get ep %d\n", i);
1.74      dyoung    452:                        return;
1.1       augustss  453:                }
                    454:                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12      augustss  455:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1       augustss  456:                        sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
                    457:                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1.12      augustss  458:                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1       augustss  459:                        sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
                    460:                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12      augustss  461:                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
1.1       augustss  462:                        sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
                    463:                }
                    464:        }
                    465:
                    466:        if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) {
1.63      cube      467:                aprint_error_dev(self, "missing endpoint\n");
1.74      dyoung    468:                return;
1.1       augustss  469:        }
                    470:
                    471:        /* Read ethernet descriptor */
                    472:        err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
1.18      augustss  473:            0, &sc->kue_desc, sizeof(sc->kue_desc));
1.1       augustss  474:        if (err) {
1.63      cube      475:                aprint_error_dev(self, "could not read Ethernet descriptor\n");
1.74      dyoung    476:                return;
1.1       augustss  477:        }
                    478:
1.84      skrll     479:        sc->kue_mcfilters = kmem_alloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
                    480:            KM_SLEEP);
1.1       augustss  481:        if (sc->kue_mcfilters == NULL) {
1.63      cube      482:                aprint_error_dev(self,
                    483:                    "no memory for multicast filter buffer\n");
1.74      dyoung    484:                return;
1.1       augustss  485:        }
                    486:
1.41      thorpej   487:        s = splnet();
1.1       augustss  488:
                    489:        /*
                    490:         * A KLSI chip was detected. Inform the world.
                    491:         */
1.63      cube      492:        aprint_normal_dev(self, "Ethernet address %s\n",
1.1       augustss  493:            ether_sprintf(sc->kue_desc.kue_macaddr));
                    494:
                    495:        /* Initialize interface info.*/
                    496:        ifp = GET_IFP(sc);
                    497:        ifp->if_softc = sc;
                    498:        ifp->if_mtu = ETHERMTU;
                    499:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    500:        ifp->if_ioctl = kue_ioctl;
                    501:        ifp->if_start = kue_start;
                    502:        ifp->if_watchdog = kue_watchdog;
1.74      dyoung    503:        strncpy(ifp->if_xname, device_xname(sc->kue_dev), IFNAMSIZ);
1.1       augustss  504:
1.34      thorpej   505:        IFQ_SET_READY(&ifp->if_snd);
                    506:
1.1       augustss  507:        /* Attach the interface. */
                    508:        if_attach(ifp);
1.74      dyoung    509:        ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
                    510:        rnd_attach_source(&sc->rnd_source, device_xname(sc->kue_dev),
1.81      tls       511:            RND_TYPE_NET, RND_FLAG_DEFAULT);
1.1       augustss  512:
1.71      tsutsui   513:        sc->kue_attached = true;
1.1       augustss  514:        splx(s);
1.6       augustss  515:
1.86      msaitoh   516:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev, sc->kue_dev);
1.6       augustss  517:
1.74      dyoung    518:        return;
1.1       augustss  519: }
                    520:
1.74      dyoung    521: int
                    522: kue_detach(device_t self, int flags)
1.1       augustss  523: {
1.74      dyoung    524:        struct kue_softc *sc = device_private(self);
1.6       augustss  525:        struct ifnet            *ifp = GET_IFP(sc);
1.1       augustss  526:        int                     s;
                    527:
1.6       augustss  528:        s = splusb();           /* XXX why? */
1.1       augustss  529:
1.8       augustss  530:        if (sc->kue_mcfilters != NULL) {
1.84      skrll     531:                kmem_free(sc->kue_mcfilters,
                    532:                    KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN);
1.8       augustss  533:                sc->kue_mcfilters = NULL;
                    534:        }
                    535:
                    536:        if (!sc->kue_attached) {
                    537:                /* Detached before attached finished, so just bail out. */
                    538:                splx(s);
1.84      skrll     539:                return 0;
1.8       augustss  540:        }
                    541:
1.6       augustss  542:        if (ifp->if_flags & IFF_RUNNING)
                    543:                kue_stop(sc);
1.1       augustss  544:
1.6       augustss  545:        rnd_detach_source(&sc->rnd_source);
                    546:        ether_ifdetach(ifp);
1.1       augustss  547:
1.6       augustss  548:        if_detach(ifp);
                    549:
                    550: #ifdef DIAGNOSTIC
                    551:        if (sc->kue_ep[KUE_ENDPT_TX] != NULL ||
                    552:            sc->kue_ep[KUE_ENDPT_RX] != NULL ||
                    553:            sc->kue_ep[KUE_ENDPT_INTR] != NULL)
1.63      cube      554:                aprint_debug_dev(self, "detach has active endpoints\n");
1.6       augustss  555: #endif
1.1       augustss  556:
1.71      tsutsui   557:        sc->kue_attached = false;
1.1       augustss  558:        splx(s);
                    559:
1.84      skrll     560:        return 0;
1.1       augustss  561: }
                    562:
                    563: int
1.74      dyoung    564: kue_activate(device_t self, enum devact act)
1.1       augustss  565: {
1.63      cube      566:        struct kue_softc *sc = device_private(self);
1.1       augustss  567:
1.74      dyoung    568:        DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  569:
                    570:        switch (act) {
                    571:        case DVACT_DEACTIVATE:
1.5       thorpej   572:                /* Deactivate the interface. */
                    573:                if_deactivate(&sc->kue_ec.ec_if);
1.71      tsutsui   574:                sc->kue_dying = true;
1.67      dyoung    575:                return 0;
                    576:        default:
                    577:                return EOPNOTSUPP;
1.1       augustss  578:        }
                    579: }
                    580:
1.72      tsutsui   581: static int
1.29      augustss  582: kue_rx_list_init(struct kue_softc *sc)
1.1       augustss  583: {
                    584:        struct kue_cdata        *cd;
                    585:        struct kue_chain        *c;
                    586:        int                     i;
                    587:
1.74      dyoung    588:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  589:
                    590:        cd = &sc->kue_cdata;
                    591:        for (i = 0; i < KUE_RX_LIST_CNT; i++) {
                    592:                c = &cd->kue_rx_chain[i];
                    593:                c->kue_sc = sc;
                    594:                c->kue_idx = i;
                    595:                if (c->kue_xfer == NULL) {
1.84      skrll     596:                        int error = usbd_create_xfer(sc->kue_ep[KUE_ENDPT_RX],
                    597:                            KUE_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->kue_xfer);
                    598:                        if (error)
                    599:                                return error;
                    600:                        c->kue_buf = usbd_get_buffer(c->kue_xfer);
1.1       augustss  601:                }
                    602:        }
                    603:
1.84      skrll     604:        return 0;
1.1       augustss  605: }
                    606:
1.72      tsutsui   607: static int
1.29      augustss  608: kue_tx_list_init(struct kue_softc *sc)
1.1       augustss  609: {
                    610:        struct kue_cdata        *cd;
                    611:        struct kue_chain        *c;
                    612:        int                     i;
                    613:
1.74      dyoung    614:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev), __func__));
1.1       augustss  615:
                    616:        cd = &sc->kue_cdata;
                    617:        for (i = 0; i < KUE_TX_LIST_CNT; i++) {
                    618:                c = &cd->kue_tx_chain[i];
                    619:                c->kue_sc = sc;
                    620:                c->kue_idx = i;
                    621:                if (c->kue_xfer == NULL) {
1.84      skrll     622:                        int error = usbd_create_xfer(sc->kue_ep[KUE_ENDPT_TX],
                    623:                            KUE_BUFSZ, 0, 0, &c->kue_xfer);
                    624:                        if (error)
                    625:                                return error;
                    626:                        c->kue_buf = usbd_get_buffer(c->kue_xfer);
1.1       augustss  627:                }
                    628:        }
                    629:
1.84      skrll     630:        return 0;
1.1       augustss  631: }
                    632:
                    633: /*
                    634:  * A frame has been uploaded: pass the resulting mbuf chain up to
                    635:  * the higher level protocols.
                    636:  */
1.72      tsutsui   637: static void
1.84      skrll     638: kue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1.1       augustss  639: {
                    640:        struct kue_chain        *c = priv;
                    641:        struct kue_softc        *sc = c->kue_sc;
                    642:        struct ifnet            *ifp = GET_IFP(sc);
                    643:        struct mbuf             *m;
1.73      tsutsui   644:        int                     total_len, pktlen;
1.1       augustss  645:        int                     s;
                    646:
1.74      dyoung    647:        DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->kue_dev),
1.48      augustss  648:                     __func__, status));
1.1       augustss  649:
1.6       augustss  650:        if (sc->kue_dying)
                    651:                return;
                    652:
1.1       augustss  653:        if (!(ifp->if_flags & IFF_RUNNING))
                    654:                return;
                    655:
                    656:        if (status != USBD_NORMAL_COMPLETION) {
                    657:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                    658:                        return;
1.11      augustss  659:                sc->kue_rx_errs++;
                    660:                if (usbd_ratecheck(&sc->kue_rx_notice)) {
                    661:                        printf("%s: %u usb errors on rx: %s\n",
1.74      dyoung    662:                            device_xname(sc->kue_dev), sc->kue_rx_errs,
1.11      augustss  663:                            usbd_errstr(status));
                    664:                        sc->kue_rx_errs = 0;
                    665:                }
1.1       augustss  666:                if (status == USBD_STALLED)
1.55      augustss  667:                        usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]);
1.1       augustss  668:                goto done;
                    669:        }
                    670:
                    671:        usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
                    672:
1.74      dyoung    673:        DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", device_xname(sc->kue_dev),
1.49      augustss  674:                     __func__, total_len,
1.73      tsutsui   675:                     le16dec(c->kue_buf)));
1.1       augustss  676:
                    677:        if (total_len <= 1)
                    678:                goto done;
                    679:
1.73      tsutsui   680:        pktlen = le16dec(c->kue_buf);
                    681:        if (pktlen > total_len - 2)
                    682:                pktlen = total_len - 2;
                    683:
                    684:        if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN ||
                    685:            pktlen > MCLBYTES - ETHER_ALIGN) {
                    686:                ifp->if_ierrors++;
                    687:                goto done;
                    688:        }
1.1       augustss  689:
                    690:        /* No errors; receive the packet. */
1.73      tsutsui   691:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    692:        if (m == NULL) {
1.1       augustss  693:                ifp->if_ierrors++;
                    694:                goto done;
                    695:        }
1.73      tsutsui   696:        if (pktlen > MHLEN - ETHER_ALIGN) {
                    697:                MCLGET(m, M_DONTWAIT);
                    698:                if ((m->m_flags & M_EXT) == 0) {
                    699:                        m_freem(m);
                    700:                        ifp->if_ierrors++;
                    701:                        goto done;
                    702:                }
                    703:        }
                    704:        m->m_data += ETHER_ALIGN;
                    705:
                    706:        /* copy data to mbuf */
                    707:        memcpy(mtod(m, uint8_t *), c->kue_buf + 2, pktlen);
1.1       augustss  708:
1.73      tsutsui   709:        m->m_pkthdr.len = m->m_len = pktlen;
1.85      ozaki-r   710:        m_set_rcvif(m, ifp);
1.1       augustss  711:
1.41      thorpej   712:        s = splnet();
1.1       augustss  713:
1.74      dyoung    714:        DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->kue_dev),
1.48      augustss  715:                    __func__, m->m_len));
1.83      ozaki-r   716:        if_percpuq_enqueue(ifp->if_percpuq, m);
1.73      tsutsui   717:
1.1       augustss  718:        splx(s);
                    719:
                    720:  done:
                    721:
                    722:        /* Setup new transfer. */
1.84      skrll     723:        usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, KUE_BUFSZ,
                    724:            USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof);
1.1       augustss  725:        usbd_transfer(c->kue_xfer);
                    726:
1.74      dyoung    727:        DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->kue_dev),
1.48      augustss  728:                    __func__));
1.1       augustss  729: }
                    730:
                    731: /*
                    732:  * A frame was downloaded to the chip. It's safe for us to clean up
                    733:  * the list buffers.
                    734:  */
                    735:
1.72      tsutsui   736: static void
1.84      skrll     737: kue_txeof(struct usbd_xfer *xfer, void *priv,
1.57      christos  738:     usbd_status status)
1.1       augustss  739: {
                    740:        struct kue_chain        *c = priv;
                    741:        struct kue_softc        *sc = c->kue_sc;
                    742:        struct ifnet            *ifp = GET_IFP(sc);
                    743:        int                     s;
                    744:
1.6       augustss  745:        if (sc->kue_dying)
                    746:                return;
                    747:
1.41      thorpej   748:        s = splnet();
1.1       augustss  749:
1.74      dyoung    750:        DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->kue_dev),
1.48      augustss  751:                    __func__, status));
1.1       augustss  752:
                    753:        ifp->if_timer = 0;
                    754:        ifp->if_flags &= ~IFF_OACTIVE;
                    755:
                    756:        if (status != USBD_NORMAL_COMPLETION) {
                    757:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                    758:                        splx(s);
                    759:                        return;
                    760:                }
                    761:                ifp->if_oerrors++;
1.74      dyoung    762:                printf("%s: usb error on tx: %s\n", device_xname(sc->kue_dev),
1.1       augustss  763:                    usbd_errstr(status));
                    764:                if (status == USBD_STALLED)
1.55      augustss  765:                        usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_TX]);
1.1       augustss  766:                splx(s);
                    767:                return;
                    768:        }
                    769:
                    770:        ifp->if_opackets++;
                    771:
1.34      thorpej   772:        if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1       augustss  773:                kue_start(ifp);
                    774:
                    775:        splx(s);
                    776: }
                    777:
1.72      tsutsui   778: static int
1.29      augustss  779: kue_send(struct kue_softc *sc, struct mbuf *m, int idx)
1.1       augustss  780: {
                    781:        int                     total_len;
                    782:        struct kue_chain        *c;
                    783:        usbd_status             err;
                    784:
1.74      dyoung    785:        DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  786:
                    787:        c = &sc->kue_cdata.kue_tx_chain[idx];
                    788:
1.73      tsutsui   789:        /* Frame length is specified in the first 2 bytes of the buffer. */
                    790:        le16enc(c->kue_buf, (uint16_t)m->m_pkthdr.len);
                    791:
1.1       augustss  792:        /*
                    793:         * Copy the mbuf data into a contiguous buffer, leaving two
                    794:         * bytes at the beginning to hold the frame length.
                    795:         */
                    796:        m_copydata(m, 0, m->m_pkthdr.len, c->kue_buf + 2);
                    797:
1.73      tsutsui   798:        total_len = 2 + m->m_pkthdr.len;
                    799:        total_len = roundup2(total_len, 64);
1.1       augustss  800:
1.84      skrll     801:        usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, total_len, 0,
                    802:            USBD_DEFAULT_TIMEOUT, kue_txeof);
1.1       augustss  803:
                    804:        /* Transmit */
                    805:        err = usbd_transfer(c->kue_xfer);
                    806:        if (err != USBD_IN_PROGRESS) {
1.74      dyoung    807:                printf("%s: kue_send error=%s\n", device_xname(sc->kue_dev),
1.28      augustss  808:                       usbd_errstr(err));
1.1       augustss  809:                kue_stop(sc);
1.84      skrll     810:                return EIO;
1.1       augustss  811:        }
                    812:
                    813:        sc->kue_cdata.kue_tx_cnt++;
                    814:
1.84      skrll     815:        return 0;
1.1       augustss  816: }
                    817:
1.72      tsutsui   818: static void
1.29      augustss  819: kue_start(struct ifnet *ifp)
1.1       augustss  820: {
                    821:        struct kue_softc        *sc = ifp->if_softc;
1.73      tsutsui   822:        struct mbuf             *m;
1.1       augustss  823:
1.74      dyoung    824:        DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  825:
1.6       augustss  826:        if (sc->kue_dying)
                    827:                return;
                    828:
1.1       augustss  829:        if (ifp->if_flags & IFF_OACTIVE)
                    830:                return;
                    831:
1.73      tsutsui   832:        IFQ_POLL(&ifp->if_snd, m);
                    833:        if (m == NULL)
1.1       augustss  834:                return;
                    835:
1.73      tsutsui   836:        if (kue_send(sc, m, 0)) {
1.1       augustss  837:                ifp->if_flags |= IFF_OACTIVE;
                    838:                return;
                    839:        }
                    840:
1.73      tsutsui   841:        IFQ_DEQUEUE(&ifp->if_snd, m);
1.34      thorpej   842:
1.1       augustss  843:        /*
                    844:         * If there's a BPF listener, bounce a copy of this frame
                    845:         * to him.
                    846:         */
1.73      tsutsui   847:        bpf_mtap(ifp, m);
                    848:        m_freem(m);
1.1       augustss  849:
                    850:        ifp->if_flags |= IFF_OACTIVE;
                    851:
                    852:        /*
                    853:         * Set a timeout in case the chip goes out to lunch.
                    854:         */
1.37      augustss  855:        ifp->if_timer = 6;
1.1       augustss  856: }
                    857:
1.72      tsutsui   858: static void
1.29      augustss  859: kue_init(void *xsc)
1.1       augustss  860: {
                    861:        struct kue_softc        *sc = xsc;
                    862:        struct ifnet            *ifp = GET_IFP(sc);
                    863:        int                     s;
1.71      tsutsui   864:        uint8_t                 eaddr[ETHER_ADDR_LEN];
1.1       augustss  865:
1.74      dyoung    866:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  867:
                    868:        if (ifp->if_flags & IFF_RUNNING)
                    869:                return;
                    870:
1.41      thorpej   871:        s = splnet();
1.1       augustss  872:
1.61      dyoung    873:        memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
1.1       augustss  874:        /* Set MAC address */
                    875:        kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN);
                    876:
                    877:        sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST;
                    878:
                    879:         /* If we want promiscuous mode, set the allframes bit. */
                    880:        if (ifp->if_flags & IFF_PROMISC)
                    881:                sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
                    882:
                    883:        kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
                    884:
                    885:        /* I'm not sure how to tune these. */
                    886: #if 0
                    887:        /*
                    888:         * Leave this one alone for now; setting it
                    889:         * wrong causes lockups on some machines/controllers.
                    890:         */
                    891:        kue_setword(sc, KUE_CMD_SET_SOFS, 1);
                    892: #endif
                    893:        kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
                    894:
1.84      skrll     895:        /* Load the multicast filter. */
                    896:        kue_setmulti(sc);
                    897:
                    898:        if (sc->kue_ep[KUE_ENDPT_RX] == NULL) {
                    899:                if (kue_open_pipes(sc)) {
                    900:                        splx(s);
                    901:                        return;
                    902:                }
                    903:        }
1.1       augustss  904:        /* Init TX ring. */
1.84      skrll     905:        if (kue_tx_list_init(sc)) {
1.74      dyoung    906:                printf("%s: tx list init failed\n", device_xname(sc->kue_dev));
1.1       augustss  907:                splx(s);
                    908:                return;
                    909:        }
                    910:
                    911:        /* Init RX ring. */
1.84      skrll     912:        if (kue_rx_list_init(sc)) {
1.74      dyoung    913:                printf("%s: rx list init failed\n", device_xname(sc->kue_dev));
1.1       augustss  914:                splx(s);
                    915:                return;
                    916:        }
                    917:
1.84      skrll     918:        /* Start up the receive pipe. */
                    919:        for (size_t i = 0; i < KUE_RX_LIST_CNT; i++) {
                    920:                struct kue_chain *c = &sc->kue_cdata.kue_rx_chain[i];
                    921:                usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, KUE_BUFSZ,
                    922:                    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof);
                    923:                DPRINTFN(5,("%s: %s: start read\n", device_xname(sc->kue_dev),
                    924:                            __func__));
                    925:                usbd_transfer(c->kue_xfer);
1.1       augustss  926:        }
                    927:
                    928:        ifp->if_flags |= IFF_RUNNING;
                    929:        ifp->if_flags &= ~IFF_OACTIVE;
                    930:
                    931:        splx(s);
                    932: }
                    933:
1.72      tsutsui   934: static int
1.29      augustss  935: kue_open_pipes(struct kue_softc *sc)
1.1       augustss  936: {
                    937:        usbd_status             err;
                    938:
1.74      dyoung    939:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  940:
                    941:        /* Open RX and TX pipes. */
                    942:        err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX],
                    943:            USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]);
                    944:        if (err) {
                    945:                printf("%s: open rx pipe failed: %s\n",
1.74      dyoung    946:                    device_xname(sc->kue_dev), usbd_errstr(err));
1.84      skrll     947:                return EIO;
1.1       augustss  948:        }
                    949:
                    950:        err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX],
                    951:            USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]);
                    952:        if (err) {
                    953:                printf("%s: open tx pipe failed: %s\n",
1.74      dyoung    954:                    device_xname(sc->kue_dev), usbd_errstr(err));
1.84      skrll     955:                return EIO;
1.1       augustss  956:        }
                    957:
1.84      skrll     958:        return 0;
1.1       augustss  959: }
                    960:
1.72      tsutsui   961: static int
1.59      christos  962: kue_ioctl(struct ifnet *ifp, u_long command, void *data)
1.1       augustss  963: {
                    964:        struct kue_softc        *sc = ifp->if_softc;
                    965:        struct ifaddr           *ifa = (struct ifaddr *)data;
                    966:        struct ifreq            *ifr = (struct ifreq *)data;
                    967:        int                     s, error = 0;
                    968:
1.74      dyoung    969:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss  970:
1.6       augustss  971:        if (sc->kue_dying)
1.84      skrll     972:                return EIO;
1.6       augustss  973:
1.41      thorpej   974:        s = splnet();
1.1       augustss  975:
                    976:        switch(command) {
1.64      dyoung    977:        case SIOCINITIFADDR:
1.1       augustss  978:                ifp->if_flags |= IFF_UP;
                    979:                kue_init(sc);
                    980:
                    981:                switch (ifa->ifa_addr->sa_family) {
                    982: #ifdef INET
                    983:                case AF_INET:
                    984:                        arp_ifinit(ifp, ifa);
                    985:                        break;
                    986: #endif /* INET */
                    987:                }
                    988:                break;
                    989:
                    990:        case SIOCSIFMTU:
1.62      dyoung    991:                if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU)
1.1       augustss  992:                        error = EINVAL;
1.62      dyoung    993:                else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET)
                    994:                        error = 0;
1.1       augustss  995:                break;
                    996:
                    997:        case SIOCSIFFLAGS:
1.64      dyoung    998:                if ((error = ifioctl_common(ifp, command, data)) != 0)
                    999:                        break;
1.1       augustss 1000:                if (ifp->if_flags & IFF_UP) {
                   1001:                        if (ifp->if_flags & IFF_RUNNING &&
                   1002:                            ifp->if_flags & IFF_PROMISC &&
                   1003:                            !(sc->kue_if_flags & IFF_PROMISC)) {
                   1004:                                sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
                   1005:                                kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
                   1006:                                    sc->kue_rxfilt);
                   1007:                        } else if (ifp->if_flags & IFF_RUNNING &&
                   1008:                            !(ifp->if_flags & IFF_PROMISC) &&
                   1009:                            sc->kue_if_flags & IFF_PROMISC) {
                   1010:                                sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
                   1011:                                kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
                   1012:                                    sc->kue_rxfilt);
                   1013:                        } else if (!(ifp->if_flags & IFF_RUNNING))
                   1014:                                kue_init(sc);
                   1015:                } else {
                   1016:                        if (ifp->if_flags & IFF_RUNNING)
                   1017:                                kue_stop(sc);
                   1018:                }
                   1019:                sc->kue_if_flags = ifp->if_flags;
                   1020:                error = 0;
                   1021:                break;
                   1022:        case SIOCADDMULTI:
                   1023:        case SIOCDELMULTI:
1.80      skrll    1024:                error = ether_ioctl(ifp, command, data);
                   1025:                if (error == ENETRESET) {
                   1026:                        if (ifp->if_flags & IFF_RUNNING)
                   1027:                                kue_setmulti(sc);
                   1028:                        error = 0;
                   1029:                }
1.1       augustss 1030:                break;
                   1031:        default:
1.64      dyoung   1032:                error = ether_ioctl(ifp, command, data);
1.1       augustss 1033:                break;
                   1034:        }
                   1035:
                   1036:        splx(s);
                   1037:
1.84      skrll    1038:        return error;
1.1       augustss 1039: }
                   1040:
1.72      tsutsui  1041: static void
1.29      augustss 1042: kue_watchdog(struct ifnet *ifp)
1.1       augustss 1043: {
                   1044:        struct kue_softc        *sc = ifp->if_softc;
1.37      augustss 1045:        struct kue_chain        *c;
                   1046:        usbd_status             stat;
                   1047:        int                     s;
1.1       augustss 1048:
1.74      dyoung   1049:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.6       augustss 1050:
                   1051:        if (sc->kue_dying)
                   1052:                return;
1.1       augustss 1053:
                   1054:        ifp->if_oerrors++;
1.74      dyoung   1055:        printf("%s: watchdog timeout\n", device_xname(sc->kue_dev));
1.1       augustss 1056:
1.37      augustss 1057:        s = splusb();
                   1058:        c = &sc->kue_cdata.kue_tx_chain[0];
                   1059:        usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
                   1060:        kue_txeof(c->kue_xfer, c, stat);
1.1       augustss 1061:
1.34      thorpej  1062:        if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1       augustss 1063:                kue_start(ifp);
1.37      augustss 1064:        splx(s);
1.1       augustss 1065: }
                   1066:
                   1067: /*
                   1068:  * Stop the adapter and free any mbufs allocated to the
                   1069:  * RX and TX lists.
                   1070:  */
1.72      tsutsui  1071: static void
1.29      augustss 1072: kue_stop(struct kue_softc *sc)
1.1       augustss 1073: {
                   1074:        usbd_status             err;
                   1075:        struct ifnet            *ifp;
                   1076:        int                     i;
                   1077:
1.74      dyoung   1078:        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__));
1.1       augustss 1079:
                   1080:        ifp = GET_IFP(sc);
                   1081:        ifp->if_timer = 0;
                   1082:
                   1083:        /* Stop transfers. */
                   1084:        if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
                   1085:                err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
                   1086:                if (err) {
                   1087:                        printf("%s: abort rx pipe failed: %s\n",
1.74      dyoung   1088:                            device_xname(sc->kue_dev), usbd_errstr(err));
1.1       augustss 1089:                }
                   1090:        }
                   1091:
                   1092:        if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
                   1093:                err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
                   1094:                if (err) {
                   1095:                        printf("%s: abort tx pipe failed: %s\n",
1.74      dyoung   1096:                            device_xname(sc->kue_dev), usbd_errstr(err));
1.1       augustss 1097:                }
                   1098:        }
                   1099:
                   1100:        if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
                   1101:                err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
                   1102:                if (err) {
                   1103:                        printf("%s: abort intr pipe failed: %s\n",
1.74      dyoung   1104:                            device_xname(sc->kue_dev), usbd_errstr(err));
1.1       augustss 1105:                }
                   1106:        }
                   1107:
                   1108:        /* Free RX resources. */
                   1109:        for (i = 0; i < KUE_RX_LIST_CNT; i++) {
                   1110:                if (sc->kue_cdata.kue_rx_chain[i].kue_xfer != NULL) {
1.84      skrll    1111:                        usbd_destroy_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer);
1.1       augustss 1112:                        sc->kue_cdata.kue_rx_chain[i].kue_xfer = NULL;
                   1113:                }
                   1114:        }
                   1115:
                   1116:        /* Free TX resources. */
                   1117:        for (i = 0; i < KUE_TX_LIST_CNT; i++) {
                   1118:                if (sc->kue_cdata.kue_tx_chain[i].kue_xfer != NULL) {
1.84      skrll    1119:                        usbd_destroy_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer);
1.1       augustss 1120:                        sc->kue_cdata.kue_tx_chain[i].kue_xfer = NULL;
                   1121:                }
                   1122:        }
                   1123:
1.84      skrll    1124:        /* Close pipes. */
                   1125:        if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
                   1126:                err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]);
                   1127:                if (err) {
                   1128:                        printf("%s: close rx pipe failed: %s\n",
                   1129:                            device_xname(sc->kue_dev), usbd_errstr(err));
                   1130:                }
                   1131:                sc->kue_ep[KUE_ENDPT_RX] = NULL;
                   1132:        }
                   1133:
                   1134:        if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
                   1135:                err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]);
                   1136:                if (err) {
                   1137:                        printf("%s: close tx pipe failed: %s\n",
                   1138:                            device_xname(sc->kue_dev), usbd_errstr(err));
                   1139:                }
                   1140:                sc->kue_ep[KUE_ENDPT_TX] = NULL;
                   1141:        }
                   1142:
                   1143:        if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
                   1144:                err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
                   1145:                if (err) {
                   1146:                        printf("%s: close intr pipe failed: %s\n",
                   1147:                            device_xname(sc->kue_dev), usbd_errstr(err));
                   1148:                }
                   1149:                sc->kue_ep[KUE_ENDPT_INTR] = NULL;
                   1150:        }
                   1151:
1.1       augustss 1152:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1153: }

CVSweb <webmaster@jp.NetBSD.org>