[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.38

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

CVSweb <webmaster@jp.NetBSD.org>