LCOV - code coverage report
Current view: top level - dev/usb - if_smsc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 639 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: if_smsc.c,v 1.32 2018/08/25 17:09:40 mestre Exp $     */
       2             : /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
       3             : /*-
       4             :  * Copyright (c) 2012
       5             :  *      Ben Gray <bgray@freebsd.org>.
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer.
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      18             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      19             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      20             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      21             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      22             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      26             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             :  */
      28             : 
      29             : /*
      30             :  * SMSC LAN9xxx devices (http://www.smsc.com/)
      31             :  * 
      32             :  * The LAN9500 & LAN9500A devices are stand-alone USB to Ethernet chips that
      33             :  * support USB 2.0 and 10/100 Mbps Ethernet.
      34             :  *
      35             :  * The LAN951x devices are an integrated USB hub and USB to Ethernet adapter.
      36             :  * The driver only covers the Ethernet part, the standard USB hub driver
      37             :  * supports the hub part.
      38             :  *
      39             :  * This driver is closely modelled on the Linux driver written and copyrighted
      40             :  * by SMSC.
      41             :  *
      42             :  * H/W TCP & UDP Checksum Offloading
      43             :  * ---------------------------------
      44             :  * The chip supports both tx and rx offloading of UDP & TCP checksums, this
      45             :  * feature can be dynamically enabled/disabled.  
      46             :  *
      47             :  * RX checksuming is performed across bytes after the IPv4 header to the end of
      48             :  * the Ethernet frame, this means if the frame is padded with non-zero values
      49             :  * the H/W checksum will be incorrect, however the rx code compensates for this.
      50             :  *
      51             :  * TX checksuming is more complicated, the device requires a special header to
      52             :  * be prefixed onto the start of the frame which indicates the start and end
      53             :  * positions of the UDP or TCP frame.  This requires the driver to manually
      54             :  * go through the packet data and decode the headers prior to sending.
      55             :  * On Linux they generally provide cues to the location of the csum and the
      56             :  * area to calculate it over, on FreeBSD we seem to have to do it all ourselves,
      57             :  * hence this is not as optimal and therefore h/w tX checksum is currently not
      58             :  * implemented.
      59             :  */
      60             : 
      61             : #include "bpfilter.h"
      62             : 
      63             : #include <sys/param.h>
      64             : #include <sys/systm.h>
      65             : #include <sys/sockio.h>
      66             : #include <sys/rwlock.h>
      67             : #include <sys/mbuf.h>
      68             : #include <sys/kernel.h>
      69             : #include <sys/socket.h>
      70             : 
      71             : #include <sys/device.h>
      72             : 
      73             : #include <machine/bus.h>
      74             : 
      75             : #include <net/if.h>
      76             : #include <net/if_media.h>
      77             : 
      78             : #if NBPFILTER > 0
      79             : #include <net/bpf.h>
      80             : #endif
      81             : 
      82             : #include <netinet/in.h>
      83             : #include <netinet/if_ether.h>
      84             : 
      85             : #include <dev/mii/miivar.h>
      86             : 
      87             : #include <dev/usb/usb.h>
      88             : #include <dev/usb/usbdi.h>
      89             : #include <dev/usb/usbdi_util.h>
      90             : #include <dev/usb/usbdivar.h>
      91             : #include <dev/usb/usbdevs.h>
      92             : 
      93             : #include "if_smscreg.h"
      94             : 
      95             : /*
      96             :  * Various supported device vendors/products.
      97             :  */
      98             : static const struct usb_devno smsc_devs[] = {
      99             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_LAN89530 },
     100             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_LAN9530 },
     101             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_LAN9730 },
     102             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500 },
     103             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500A },
     104             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500A_ALT },
     105             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500A_HAL },
     106             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500A_SAL10 },
     107             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500_ALT },
     108             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9500_SAL10 },
     109             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9505 },
     110             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9505A },
     111             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9505A_HAL },
     112             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9505A_SAL10 },
     113             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9505_SAL10 },
     114             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9512_14 },
     115             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9512_14_ALT },
     116             :         { USB_VENDOR_SMC2,      USB_PRODUCT_SMC2_SMSC9512_14_SAL10 }
     117             : };
     118             : 
     119             : #ifdef SMSC_DEBUG
     120             : static int smsc_debug = 0;
     121             : #define smsc_dbg_printf(sc, fmt, args...) \
     122             :         do { \
     123             :                 if (smsc_debug > 0) \
     124             :                         printf("debug: " fmt, ##args); \
     125             :         } while(0)
     126             : #else
     127             : #define smsc_dbg_printf(sc, fmt, args...)
     128             : #endif
     129             : 
     130             : #define smsc_warn_printf(sc, fmt, args...) \
     131             :         printf("%s: warning: " fmt, (sc)->sc_dev.dv_xname, ##args)
     132             : 
     133             : #define smsc_err_printf(sc, fmt, args...) \
     134             :         printf("%s: error: " fmt, (sc)->sc_dev.dv_xname, ##args)
     135             : 
     136             : int              smsc_chip_init(struct smsc_softc *sc);
     137             : int              smsc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
     138             : void             smsc_iff(struct smsc_softc *);
     139             : int              smsc_setmacaddress(struct smsc_softc *, const uint8_t *);
     140             : 
     141             : int              smsc_match(struct device *, void *, void *);
     142             : void             smsc_attach(struct device *, struct device *, void *);
     143             : int              smsc_detach(struct device *, int);
     144             : 
     145             : void             smsc_init(void *);
     146             : void             smsc_stop(struct smsc_softc *);
     147             : void             smsc_start(struct ifnet *);
     148             : void             smsc_reset(struct smsc_softc *);
     149             : 
     150             : void             smsc_tick(void *);
     151             : void             smsc_tick_task(void *);
     152             : void             smsc_miibus_statchg(struct device *);
     153             : int              smsc_miibus_readreg(struct device *, int, int);
     154             : void             smsc_miibus_writereg(struct device *, int, int, int);
     155             : int              smsc_ifmedia_upd(struct ifnet *);
     156             : void             smsc_ifmedia_sts(struct ifnet *, struct ifmediareq *);
     157             : void             smsc_lock_mii(struct smsc_softc *sc);
     158             : void             smsc_unlock_mii(struct smsc_softc *sc);
     159             : 
     160             : int              smsc_tx_list_init(struct smsc_softc *);
     161             : int              smsc_rx_list_init(struct smsc_softc *);
     162             : int              smsc_encap(struct smsc_softc *, struct mbuf *, int);
     163             : void             smsc_rxeof(struct usbd_xfer *, void *, usbd_status);
     164             : void             smsc_txeof(struct usbd_xfer *, void *, usbd_status);
     165             : 
     166             : int              smsc_read_reg(struct smsc_softc *, uint32_t, uint32_t *);
     167             : int              smsc_write_reg(struct smsc_softc *, uint32_t, uint32_t);
     168             : int              smsc_wait_for_bits(struct smsc_softc *, uint32_t, uint32_t);
     169             : int              smsc_sethwcsum(struct smsc_softc *);
     170             : 
     171             : struct cfdriver smsc_cd = {
     172             :         NULL, "smsc", DV_IFNET
     173             : };
     174             : 
     175             : const struct cfattach smsc_ca = {
     176             :         sizeof(struct smsc_softc), smsc_match, smsc_attach, smsc_detach,
     177             : };
     178             : 
     179             : #if defined(__arm__) || defined(__arm64__)
     180             : 
     181             : #include <dev/ofw/openfirm.h>
     182             : 
     183             : void
     184             : smsc_enaddr_OF(struct smsc_softc *sc)
     185             : {
     186             :         char *device = "/axi/usb/hub/ethernet";
     187             :         char prop[64];
     188             :         int node;
     189             : 
     190             :         if (sc->sc_dev.dv_unit != 0)
     191             :                 return;
     192             : 
     193             :         /*
     194             :          * Get the Raspberry Pi MAC address from FDT.  This is all
     195             :          * much more complicated than strictly needed since the
     196             :          * firmware device tree keeps changing as drivers get
     197             :          * upstreamed.  Sigh.
     198             :          * 
     199             :          * Ultimately this should just use the "ethernet0" alias and
     200             :          * the "local-mac-address" property.
     201             :          */
     202             : 
     203             :         if ((node = OF_finddevice("/aliases")) == -1)
     204             :                 return;
     205             :         if (OF_getprop(node, "ethernet0", prop, sizeof(prop)) > 0 ||
     206             :             OF_getprop(node, "ethernet", prop, sizeof(prop)) > 0)
     207             :                 device = prop;
     208             : 
     209             :         if ((node = OF_finddevice(device)) == -1)
     210             :                 return;
     211             :         if (OF_getprop(node, "local-mac-address", sc->sc_ac.ac_enaddr,
     212             :             sizeof(sc->sc_ac.ac_enaddr)) != sizeof(sc->sc_ac.ac_enaddr)) {
     213             :                 OF_getprop(node, "mac-address", sc->sc_ac.ac_enaddr,
     214             :                     sizeof(sc->sc_ac.ac_enaddr));
     215             :         }
     216             : }
     217             : #else
     218             : #define smsc_enaddr_OF(x) do {} while(0)
     219             : #endif
     220             : 
     221             : int
     222           0 : smsc_read_reg(struct smsc_softc *sc, uint32_t off, uint32_t *data)
     223             : {
     224           0 :         usb_device_request_t req;
     225           0 :         uint32_t buf;
     226             :         usbd_status err;
     227             : 
     228           0 :         req.bmRequestType = UT_READ_VENDOR_DEVICE;
     229           0 :         req.bRequest = SMSC_UR_READ_REG;
     230           0 :         USETW(req.wValue, 0);
     231           0 :         USETW(req.wIndex, off);
     232           0 :         USETW(req.wLength, 4);
     233             : 
     234           0 :         err = usbd_do_request(sc->sc_udev, &req, &buf);
     235           0 :         if (err != 0)
     236           0 :                 smsc_warn_printf(sc, "Failed to read register 0x%0x\n", off);
     237             : 
     238           0 :         *data = letoh32(buf);
     239             :         
     240           0 :         return (err);
     241           0 : }
     242             : 
     243             : int
     244           0 : smsc_write_reg(struct smsc_softc *sc, uint32_t off, uint32_t data)
     245             : {
     246           0 :         usb_device_request_t req;
     247           0 :         uint32_t buf;
     248             :         usbd_status err;
     249             : 
     250           0 :         buf = htole32(data);
     251             : 
     252           0 :         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
     253           0 :         req.bRequest = SMSC_UR_WRITE_REG;
     254           0 :         USETW(req.wValue, 0);
     255           0 :         USETW(req.wIndex, off);
     256           0 :         USETW(req.wLength, 4);
     257             : 
     258           0 :         err = usbd_do_request(sc->sc_udev, &req, &buf);
     259           0 :         if (err != 0)
     260           0 :                 smsc_warn_printf(sc, "Failed to write register 0x%0x\n", off);
     261             : 
     262           0 :         return (err);
     263           0 : }
     264             : 
     265             : int
     266           0 : smsc_wait_for_bits(struct smsc_softc *sc, uint32_t reg, uint32_t bits)
     267             : {
     268           0 :         uint32_t val;
     269             :         int err, i;
     270             : 
     271           0 :         for (i = 0; i < 100; i++) {
     272           0 :                 if ((err = smsc_read_reg(sc, reg, &val)) != 0)
     273           0 :                         return (err);
     274           0 :                 if (!(val & bits))
     275           0 :                         return (0);
     276           0 :                 DELAY(5);
     277             :         }
     278             : 
     279           0 :         return (1);
     280           0 : }
     281             : 
     282             : int
     283           0 : smsc_miibus_readreg(struct device *dev, int phy, int reg)
     284             : {
     285           0 :         struct smsc_softc *sc = (struct smsc_softc *)dev;
     286             :         uint32_t addr;
     287           0 :         uint32_t val = 0;
     288             : 
     289           0 :         smsc_lock_mii(sc);
     290           0 :         if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
     291           0 :                 smsc_warn_printf(sc, "MII is busy\n");
     292           0 :                 goto done;
     293             :         }
     294             : 
     295           0 :         addr = (phy << 11) | (reg << 6) | SMSC_MII_READ;
     296           0 :         smsc_write_reg(sc, SMSC_MII_ADDR, addr);
     297             : 
     298           0 :         if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
     299           0 :                 smsc_warn_printf(sc, "MII read timeout\n");
     300             : 
     301           0 :         smsc_read_reg(sc, SMSC_MII_DATA, &val);
     302             : 
     303             : done:
     304           0 :         smsc_unlock_mii(sc);
     305           0 :         return (val & 0xFFFF);
     306           0 : }
     307             : 
     308             : void
     309           0 : smsc_miibus_writereg(struct device *dev, int phy, int reg, int val)
     310             : {
     311           0 :         struct smsc_softc *sc = (struct smsc_softc *)dev;
     312             :         uint32_t addr;
     313             : 
     314           0 :         if (sc->sc_phyno != phy)
     315           0 :                 return;
     316             : 
     317           0 :         smsc_lock_mii(sc);
     318           0 :         if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) {
     319           0 :                 smsc_warn_printf(sc, "MII is busy\n");
     320           0 :                 smsc_unlock_mii(sc);
     321           0 :                 return;
     322             :         }
     323             : 
     324           0 :         smsc_write_reg(sc, SMSC_MII_DATA, val);
     325             : 
     326           0 :         addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE;
     327           0 :         smsc_write_reg(sc, SMSC_MII_ADDR, addr);
     328           0 :         smsc_unlock_mii(sc);
     329             : 
     330           0 :         if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
     331           0 :                 smsc_warn_printf(sc, "MII write timeout\n");
     332           0 : }
     333             : 
     334             : void
     335           0 : smsc_miibus_statchg(struct device *dev)
     336             : {
     337           0 :         struct smsc_softc *sc = (struct smsc_softc *)dev;
     338           0 :         struct mii_data *mii = &sc->sc_mii;
     339           0 :         struct ifnet *ifp = &sc->sc_ac.ac_if;
     340             :         int err;
     341             :         uint32_t flow;
     342           0 :         uint32_t afc_cfg;
     343             : 
     344           0 :         if (mii == NULL || ifp == NULL ||
     345           0 :             (ifp->if_flags & IFF_RUNNING) == 0)
     346           0 :                 return;
     347             : 
     348             :         /* Use the MII status to determine link status */
     349           0 :         sc->sc_flags &= ~SMSC_FLAG_LINK;
     350           0 :         if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
     351             :             (IFM_ACTIVE | IFM_AVALID)) {
     352           0 :                 switch (IFM_SUBTYPE(mii->mii_media_active)) {
     353             :                         case IFM_10_T:
     354             :                         case IFM_100_TX:
     355           0 :                                 sc->sc_flags |= SMSC_FLAG_LINK;
     356           0 :                                 break;
     357             :                         case IFM_1000_T:
     358             :                                 /* Gigabit ethernet not supported by chipset */
     359             :                                 break;
     360             :                         default:
     361             :                                 break;
     362             :                 }
     363             :         }
     364             : 
     365             :         /* Lost link, do nothing. */
     366           0 :         if ((sc->sc_flags & SMSC_FLAG_LINK) == 0) {
     367             :                 smsc_dbg_printf(sc, "link flag not set\n");
     368           0 :                 return;
     369             :         }
     370             :         
     371           0 :         err = smsc_read_reg(sc, SMSC_AFC_CFG, &afc_cfg);
     372           0 :         if (err) {
     373           0 :                 smsc_warn_printf(sc, "failed to read initial AFC_CFG, "
     374             :                     "error %d\n", err);
     375           0 :                 return;
     376             :         }
     377             :         
     378             :         /* Enable/disable full duplex operation and TX/RX pause */
     379           0 :         if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
     380             :                 smsc_dbg_printf(sc, "full duplex operation\n");
     381           0 :                 sc->sc_mac_csr &= ~SMSC_MAC_CSR_RCVOWN;
     382           0 :                 sc->sc_mac_csr |= SMSC_MAC_CSR_FDPX;
     383             : 
     384           0 :                 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
     385           0 :                         flow = 0xffff0002;
     386             :                 else
     387             :                         flow = 0;
     388             :                         
     389           0 :                 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
     390           0 :                         afc_cfg |= 0xf;
     391             :                 else
     392           0 :                         afc_cfg &= ~0xf;
     393             :                 
     394             :         } else {
     395             :                 smsc_dbg_printf(sc, "half duplex operation\n");
     396           0 :                 sc->sc_mac_csr &= ~SMSC_MAC_CSR_FDPX;
     397           0 :                 sc->sc_mac_csr |= SMSC_MAC_CSR_RCVOWN;
     398             :                 
     399             :                 flow = 0;
     400           0 :                 afc_cfg |= 0xf;
     401             :         }
     402             : 
     403           0 :         err = smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
     404           0 :         err += smsc_write_reg(sc, SMSC_FLOW, flow);
     405           0 :         err += smsc_write_reg(sc, SMSC_AFC_CFG, afc_cfg);
     406           0 :         if (err)
     407           0 :                 smsc_warn_printf(sc, "media change failed, error %d\n", err);
     408           0 : }
     409             : 
     410             : int
     411           0 : smsc_ifmedia_upd(struct ifnet *ifp)
     412             : {
     413           0 :         struct smsc_softc *sc = ifp->if_softc;
     414           0 :         struct mii_data *mii = &sc->sc_mii;
     415             :         int err;
     416             : 
     417           0 :         if (mii->mii_instance) {
     418             :                 struct mii_softc *miisc;
     419             : 
     420           0 :                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
     421           0 :                         mii_phy_reset(miisc);
     422           0 :         }
     423           0 :         err = mii_mediachg(mii);
     424           0 :         return (err);
     425             : }
     426             : 
     427             : void
     428           0 : smsc_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
     429             : {
     430           0 :         struct smsc_softc *sc = ifp->if_softc;
     431           0 :         struct mii_data *mii = &sc->sc_mii;
     432             : 
     433           0 :         mii_pollstat(mii);
     434             :         
     435           0 :         ifmr->ifm_active = mii->mii_media_active;
     436           0 :         ifmr->ifm_status = mii->mii_media_status;
     437           0 : }
     438             : 
     439             : static inline uint32_t
     440           0 : smsc_hash(uint8_t addr[ETHER_ADDR_LEN])
     441             : {
     442           0 :         return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f;
     443             : }
     444             : 
     445             : void
     446           0 : smsc_iff(struct smsc_softc *sc)
     447             : {
     448           0 :         struct ifnet            *ifp = &sc->sc_ac.ac_if;
     449             :         struct arpcom           *ac = &sc->sc_ac;
     450             :         struct ether_multi      *enm;
     451             :         struct ether_multistep   step;
     452           0 :         uint32_t                 hashtbl[2] = { 0, 0 };
     453             :         uint32_t                 hash;
     454             : 
     455           0 :         if (usbd_is_dying(sc->sc_udev))
     456           0 :                 return;
     457             : 
     458           0 :         sc->sc_mac_csr &= ~(SMSC_MAC_CSR_HPFILT | SMSC_MAC_CSR_MCPAS |
     459             :             SMSC_MAC_CSR_PRMS);
     460           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
     461             : 
     462           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
     463           0 :                 ifp->if_flags |= IFF_ALLMULTI;
     464           0 :                 sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
     465           0 :                 if (ifp->if_flags & IFF_PROMISC)
     466           0 :                         sc->sc_mac_csr |= SMSC_MAC_CSR_PRMS;
     467             :         } else {
     468           0 :                 sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;
     469             : 
     470           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
     471           0 :                 while (enm != NULL) {
     472           0 :                         hash = smsc_hash(enm->enm_addrlo);
     473             : 
     474           0 :                         hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
     475             : 
     476           0 :                         ETHER_NEXT_MULTI(step, enm);
     477             :                 }
     478             :         }
     479             : 
     480             :         /* Debug */
     481           0 :         if (sc->sc_mac_csr & SMSC_MAC_CSR_MCPAS)
     482             :                 smsc_dbg_printf(sc, "receive all multicast enabled\n");
     483           0 :         else if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT)
     484             :                 smsc_dbg_printf(sc, "receive select group of macs\n");
     485             : 
     486             :         /* Write the hash table and mac control registers */
     487           0 :         smsc_write_reg(sc, SMSC_HASHH, hashtbl[1]);
     488           0 :         smsc_write_reg(sc, SMSC_HASHL, hashtbl[0]);
     489           0 :         smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
     490           0 : }
     491             : 
     492             : int
     493           0 : smsc_sethwcsum(struct smsc_softc *sc)
     494             : {
     495           0 :         struct ifnet *ifp = &sc->sc_ac.ac_if;
     496           0 :         uint32_t val;
     497             :         int err;
     498             : 
     499           0 :         if (!ifp)
     500           0 :                 return (-EIO);
     501             : 
     502           0 :         err = smsc_read_reg(sc, SMSC_COE_CTRL, &val);
     503           0 :         if (err != 0) {
     504           0 :                 smsc_warn_printf(sc, "failed to read SMSC_COE_CTRL (err=%d)\n",
     505             :                     err);
     506           0 :                 return (err);
     507             :         }
     508             : 
     509             :         /* Enable/disable the Rx checksum */
     510           0 :         if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
     511           0 :                 val |= SMSC_COE_CTRL_RX_EN;
     512             :         else
     513           0 :                 val &= ~SMSC_COE_CTRL_RX_EN;
     514             : 
     515             :         /* Enable/disable the Tx checksum (currently not supported) */
     516           0 :         if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
     517           0 :                 val |= SMSC_COE_CTRL_TX_EN;
     518             :         else
     519           0 :                 val &= ~SMSC_COE_CTRL_TX_EN;
     520             : 
     521           0 :         err = smsc_write_reg(sc, SMSC_COE_CTRL, val);
     522           0 :         if (err != 0) {
     523           0 :                 smsc_warn_printf(sc, "failed to write SMSC_COE_CTRL (err=%d)\n",
     524             :                     err);
     525           0 :                 return (err);
     526             :         }
     527             : 
     528           0 :         return (0);
     529           0 : }
     530             : 
     531             : int
     532           0 : smsc_setmacaddress(struct smsc_softc *sc, const uint8_t *addr)
     533             : {
     534             :         int err;
     535             :         uint32_t val;
     536             : 
     537             :         smsc_dbg_printf(sc, "setting mac address to "
     538             :             "%02x:%02x:%02x:%02x:%02x:%02x\n",
     539             :             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
     540             : 
     541           0 :         val = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
     542           0 :         if ((err = smsc_write_reg(sc, SMSC_MAC_ADDRL, val)) != 0)
     543             :                 goto done;
     544             :                 
     545           0 :         val = (addr[5] << 8) | addr[4];
     546           0 :         err = smsc_write_reg(sc, SMSC_MAC_ADDRH, val);
     547             :         
     548             : done:
     549           0 :         return (err);
     550             : }
     551             : 
     552             : void
     553           0 : smsc_reset(struct smsc_softc *sc)
     554             : {
     555           0 :         if (usbd_is_dying(sc->sc_udev))
     556             :                 return;
     557             : 
     558             :         /* Wait a little while for the chip to get its brains in order. */
     559           0 :         DELAY(1000);
     560             : 
     561             :         /* Reinitialize controller to achieve full reset. */
     562           0 :         smsc_chip_init(sc);
     563           0 : }
     564             : 
     565             : void
     566           0 : smsc_init(void *xsc)
     567             : {
     568           0 :         struct smsc_softc       *sc = xsc;
     569           0 :         struct ifnet            *ifp = &sc->sc_ac.ac_if;
     570             :         struct smsc_chain       *c;
     571             :         usbd_status              err;
     572             :         int                      s, i;
     573             :         
     574           0 :         s = splnet();
     575             : 
     576             :         /* Cancel pending I/O */
     577           0 :         smsc_stop(sc);
     578             : 
     579             :         /* Reset the ethernet interface. */
     580           0 :         smsc_reset(sc);
     581             : 
     582             :         /* Init RX ring. */
     583           0 :         if (smsc_rx_list_init(sc) == ENOBUFS) {
     584           0 :                 printf("%s: rx list init failed\n", sc->sc_dev.dv_xname);
     585           0 :                 splx(s);
     586           0 :                 return;
     587             :         }
     588             : 
     589             :         /* Init TX ring. */
     590           0 :         if (smsc_tx_list_init(sc) == ENOBUFS) {
     591           0 :                 printf("%s: tx list init failed\n", sc->sc_dev.dv_xname);
     592           0 :                 splx(s);
     593           0 :                 return;
     594             :         }
     595             : 
     596             :         /* Program promiscuous mode and multicast filters. */
     597           0 :         smsc_iff(sc);
     598             : 
     599             :         /* Open RX and TX pipes. */
     600           0 :         err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_RX],
     601           0 :             USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_RX]);
     602           0 :         if (err) {
     603           0 :                 printf("%s: open rx pipe failed: %s\n",
     604           0 :                     sc->sc_dev.dv_xname, usbd_errstr(err));
     605           0 :                 splx(s);
     606           0 :                 return;
     607             :         }
     608             : 
     609           0 :         err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_TX],
     610           0 :             USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_TX]);
     611           0 :         if (err) {
     612           0 :                 printf("%s: open tx pipe failed: %s\n",
     613           0 :                     sc->sc_dev.dv_xname, usbd_errstr(err));
     614           0 :                 splx(s);
     615           0 :                 return;
     616             :         }
     617             : 
     618             :         /* Start up the receive pipe. */
     619           0 :         for (i = 0; i < SMSC_RX_LIST_CNT; i++) {
     620           0 :                 c = &sc->sc_cdata.rx_chain[i];
     621           0 :                 usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_RX],
     622           0 :                     c, c->sc_buf, sc->sc_bufsz,
     623             :                     USBD_SHORT_XFER_OK | USBD_NO_COPY,
     624             :                     USBD_NO_TIMEOUT, smsc_rxeof);
     625           0 :                 usbd_transfer(c->sc_xfer);
     626             :         }
     627             : 
     628             :         /* TCP/UDP checksum offload engines. */
     629           0 :         smsc_sethwcsum(sc);
     630             : 
     631             :         /* Indicate we are up and running. */
     632           0 :         ifp->if_flags |= IFF_RUNNING;
     633           0 :         ifq_clr_oactive(&ifp->if_snd);
     634             : 
     635           0 :         timeout_add_sec(&sc->sc_stat_ch, 1);
     636             : 
     637           0 :         splx(s);
     638           0 : }
     639             : 
     640             : void
     641           0 : smsc_start(struct ifnet *ifp)
     642             : {
     643           0 :         struct smsc_softc       *sc = ifp->if_softc;
     644             :         struct mbuf             *m_head = NULL;
     645             : 
     646             :         /* Don't send anything if there is no link or controller is busy. */
     647           0 :         if ((sc->sc_flags & SMSC_FLAG_LINK) == 0 ||
     648           0 :                 ifq_is_oactive(&ifp->if_snd)) {
     649           0 :                 return;
     650             :         }
     651             : 
     652           0 :         m_head = ifq_deq_begin(&ifp->if_snd);
     653           0 :         if (m_head == NULL)
     654           0 :                 return;
     655             : 
     656           0 :         if (smsc_encap(sc, m_head, 0)) {
     657           0 :                 ifq_deq_rollback(&ifp->if_snd, m_head);
     658           0 :                 ifq_set_oactive(&ifp->if_snd);
     659           0 :                 return;
     660             :         }
     661           0 :         ifq_deq_commit(&ifp->if_snd, m_head);
     662             : 
     663             : #if NBPFILTER > 0
     664           0 :         if (ifp->if_bpf)
     665           0 :                 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
     666             : #endif
     667           0 :         ifq_set_oactive(&ifp->if_snd);
     668           0 : }
     669             : 
     670             : void
     671           0 : smsc_tick(void *xsc)
     672             : {
     673           0 :         struct smsc_softc *sc = xsc;
     674             : 
     675           0 :         if (sc == NULL)
     676           0 :                 return;
     677             : 
     678           0 :         if (usbd_is_dying(sc->sc_udev))
     679           0 :                 return;
     680             : 
     681           0 :         usb_add_task(sc->sc_udev, &sc->sc_tick_task);
     682           0 : }
     683             : 
     684             : void
     685           0 : smsc_stop(struct smsc_softc *sc)
     686             : {
     687             :         usbd_status             err;
     688             :         struct ifnet            *ifp;
     689             :         int                     i;
     690             : 
     691           0 :         smsc_reset(sc);
     692             : 
     693           0 :         ifp = &sc->sc_ac.ac_if;
     694           0 :         ifp->if_timer = 0;
     695           0 :         ifp->if_flags &= ~IFF_RUNNING;
     696           0 :         ifq_clr_oactive(&ifp->if_snd);
     697             : 
     698           0 :         timeout_del(&sc->sc_stat_ch);
     699             : 
     700             :         /* Stop transfers. */
     701           0 :         if (sc->sc_ep[SMSC_ENDPT_RX] != NULL) {
     702           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
     703           0 :                 err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
     704           0 :                 if (err) {
     705           0 :                         printf("%s: close rx pipe failed: %s\n",
     706           0 :                             sc->sc_dev.dv_xname, usbd_errstr(err));
     707           0 :                 }
     708           0 :                 sc->sc_ep[SMSC_ENDPT_RX] = NULL;
     709           0 :         }
     710             : 
     711           0 :         if (sc->sc_ep[SMSC_ENDPT_TX] != NULL) {
     712           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_TX]);
     713           0 :                 err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_TX]);
     714           0 :                 if (err) {
     715           0 :                         printf("%s: close tx pipe failed: %s\n",
     716           0 :                             sc->sc_dev.dv_xname, usbd_errstr(err));
     717           0 :                 }
     718           0 :                 sc->sc_ep[SMSC_ENDPT_TX] = NULL;
     719           0 :         }
     720             : 
     721           0 :         if (sc->sc_ep[SMSC_ENDPT_INTR] != NULL) {
     722           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_INTR]);
     723           0 :                 err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_INTR]);
     724           0 :                 if (err) {
     725           0 :                         printf("%s: close intr pipe failed: %s\n",
     726           0 :                             sc->sc_dev.dv_xname, usbd_errstr(err));
     727           0 :                 }
     728           0 :                 sc->sc_ep[SMSC_ENDPT_INTR] = NULL;
     729           0 :         }
     730             : 
     731             :         /* Free RX resources. */
     732           0 :         for (i = 0; i < SMSC_RX_LIST_CNT; i++) {
     733           0 :                 if (sc->sc_cdata.rx_chain[i].sc_mbuf != NULL) {
     734           0 :                         m_freem(sc->sc_cdata.rx_chain[i].sc_mbuf);
     735           0 :                         sc->sc_cdata.rx_chain[i].sc_mbuf = NULL;
     736           0 :                 }
     737           0 :                 if (sc->sc_cdata.rx_chain[i].sc_xfer != NULL) {
     738           0 :                         usbd_free_xfer(sc->sc_cdata.rx_chain[i].sc_xfer);
     739           0 :                         sc->sc_cdata.rx_chain[i].sc_xfer = NULL;
     740           0 :                 }
     741             :         }
     742             : 
     743             :         /* Free TX resources. */
     744           0 :         for (i = 0; i < SMSC_TX_LIST_CNT; i++) {
     745           0 :                 if (sc->sc_cdata.tx_chain[i].sc_mbuf != NULL) {
     746           0 :                         m_freem(sc->sc_cdata.tx_chain[i].sc_mbuf);
     747           0 :                         sc->sc_cdata.tx_chain[i].sc_mbuf = NULL;
     748           0 :                 }
     749           0 :                 if (sc->sc_cdata.tx_chain[i].sc_xfer != NULL) {
     750           0 :                         usbd_free_xfer(sc->sc_cdata.tx_chain[i].sc_xfer);
     751           0 :                         sc->sc_cdata.tx_chain[i].sc_xfer = NULL;
     752           0 :                 }
     753             :         }
     754           0 : }
     755             : 
     756             : int
     757           0 : smsc_chip_init(struct smsc_softc *sc)
     758             : {
     759             :         int err;
     760           0 :         uint32_t reg_val;
     761             :         int burst_cap;
     762             : 
     763             :         /* Enter H/W config mode */
     764           0 :         smsc_write_reg(sc, SMSC_HW_CFG, SMSC_HW_CFG_LRST);
     765             : 
     766           0 :         if ((err = smsc_wait_for_bits(sc, SMSC_HW_CFG,
     767           0 :             SMSC_HW_CFG_LRST)) != 0) {
     768           0 :                 smsc_warn_printf(sc, "timed-out waiting for reset to "
     769             :                     "complete\n");
     770           0 :                 goto init_failed;
     771             :         }
     772             : 
     773             :         /* Reset the PHY */
     774           0 :         smsc_write_reg(sc, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST);
     775             : 
     776           0 :         if ((err = smsc_wait_for_bits(sc, SMSC_PM_CTRL,
     777           0 :             SMSC_PM_CTRL_PHY_RST)) != 0) {
     778           0 :                 smsc_warn_printf(sc, "timed-out waiting for phy reset to "
     779             :                     "complete\n");
     780           0 :                 goto init_failed;
     781             :         }
     782           0 :         usbd_delay_ms(sc->sc_udev, 40);
     783             : 
     784             :         /* Set the mac address */
     785           0 :         if ((err = smsc_setmacaddress(sc, sc->sc_ac.ac_enaddr)) != 0) {
     786           0 :                 smsc_warn_printf(sc, "failed to set the MAC address\n");
     787           0 :                 goto init_failed;
     788             :         }
     789             : 
     790             :         /*
     791             :          * Don't know what the HW_CFG_BIR bit is, but following the reset
     792             :          * sequence as used in the Linux driver.
     793             :          */
     794           0 :         if ((err = smsc_read_reg(sc, SMSC_HW_CFG, &reg_val)) != 0) {
     795           0 :                 smsc_warn_printf(sc, "failed to read HW_CFG: %d\n", err);
     796           0 :                 goto init_failed;
     797             :         }
     798           0 :         reg_val |= SMSC_HW_CFG_BIR;
     799           0 :         smsc_write_reg(sc, SMSC_HW_CFG, reg_val);
     800             : 
     801             :         /*
     802             :          * There is a so called 'turbo mode' that the linux driver supports, it
     803             :          * seems to allow you to jam multiple frames per Rx transaction.
     804             :          * By default this driver supports that and therefore allows multiple
     805             :          * frames per URB.
     806             :          *
     807             :          * The xfer buffer size needs to reflect this as well, therefore based
     808             :          * on the calculations in the Linux driver the RX bufsize is set to
     809             :          * 18944,
     810             :          *     bufsz = (16 * 1024 + 5 * 512)
     811             :          *
     812             :          * Burst capability is the number of URBs that can be in a burst of
     813             :          * data/ethernet frames.
     814             :          */
     815             : #ifdef SMSC_TURBO
     816             :         if (sc->sc_udev->speed == USB_SPEED_HIGH)
     817             :                 burst_cap = 37;
     818             :         else
     819             :                 burst_cap = 128;
     820             : #else
     821             :         burst_cap = 0;
     822             : #endif
     823             : 
     824           0 :         smsc_write_reg(sc, SMSC_BURST_CAP, burst_cap);
     825             : 
     826             :         /* Set the default bulk in delay (magic value from Linux driver) */
     827           0 :         smsc_write_reg(sc, SMSC_BULK_IN_DLY, 0x00002000);
     828             : 
     829             : 
     830             : 
     831             :         /*
     832             :          * Initialise the RX interface
     833             :          */
     834           0 :         if ((err = smsc_read_reg(sc, SMSC_HW_CFG, &reg_val)) < 0) {
     835           0 :                 smsc_warn_printf(sc, "failed to read HW_CFG: (err = %d)\n",
     836             :                     err);
     837           0 :                 goto init_failed;
     838             :         }
     839             : 
     840             :         /*
     841             :          * The following setings are used for 'turbo mode', a.k.a multiple
     842             :          * frames per Rx transaction (again info taken form Linux driver).
     843             :          */
     844             : #ifdef SMSC_TURBO
     845             :         reg_val |= (SMSC_HW_CFG_MEF | SMSC_HW_CFG_BCE);
     846             : #endif
     847             : 
     848           0 :         smsc_write_reg(sc, SMSC_HW_CFG, reg_val);
     849             : 
     850             :         /* Clear the status register ? */
     851           0 :         smsc_write_reg(sc, SMSC_INTR_STATUS, 0xffffffff);
     852             : 
     853             :         /* Read and display the revision register */
     854           0 :         if ((err = smsc_read_reg(sc, SMSC_ID_REV, &sc->sc_rev_id)) < 0) {
     855           0 :                 smsc_warn_printf(sc, "failed to read ID_REV (err = %d)\n", err);
     856           0 :                 goto init_failed;
     857             :         }
     858             : 
     859             :         /* GPIO/LED setup */
     860           0 :         reg_val = SMSC_LED_GPIO_CFG_SPD_LED | SMSC_LED_GPIO_CFG_LNK_LED | 
     861             :                   SMSC_LED_GPIO_CFG_FDX_LED;
     862           0 :         smsc_write_reg(sc, SMSC_LED_GPIO_CFG, reg_val);
     863             : 
     864             :         /*
     865             :          * Initialise the TX interface
     866             :          */
     867           0 :         smsc_write_reg(sc, SMSC_FLOW, 0);
     868             : 
     869           0 :         smsc_write_reg(sc, SMSC_AFC_CFG, AFC_CFG_DEFAULT);
     870             : 
     871             :         /* Read the current MAC configuration */
     872           0 :         if ((err = smsc_read_reg(sc, SMSC_MAC_CSR, &sc->sc_mac_csr)) < 0) {
     873           0 :                 smsc_warn_printf(sc, "failed to read MAC_CSR (err=%d)\n", err);
     874           0 :                 goto init_failed;
     875             :         }
     876             :         
     877             :         /* Vlan */
     878           0 :         smsc_write_reg(sc, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN);
     879             : 
     880             :         /*
     881             :          * Start TX
     882             :          */
     883           0 :         sc->sc_mac_csr |= SMSC_MAC_CSR_TXEN;
     884           0 :         smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
     885           0 :         smsc_write_reg(sc, SMSC_TX_CFG, SMSC_TX_CFG_ON);
     886             : 
     887             :         /*
     888             :          * Start RX
     889             :          */
     890           0 :         sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN;
     891           0 :         smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
     892             : 
     893           0 :         return (0);
     894             :         
     895             : init_failed:
     896           0 :         smsc_err_printf(sc, "smsc_chip_init failed (err=%d)\n", err);
     897           0 :         return (err);
     898           0 : }
     899             : 
     900             : int
     901           0 : smsc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     902             : {
     903           0 :         struct smsc_softc       *sc = ifp->if_softc;
     904           0 :         struct ifreq            *ifr = (struct ifreq *)data;
     905             :         int                     s, error = 0;
     906             : 
     907           0 :         s = splnet();
     908             : 
     909           0 :         switch(cmd) {
     910             :         case SIOCSIFADDR:
     911           0 :                 ifp->if_flags |= IFF_UP;
     912           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
     913           0 :                         smsc_init(sc);
     914             :                 break;
     915             : 
     916             :         case SIOCSIFFLAGS:
     917           0 :                 if (ifp->if_flags & IFF_UP) {
     918           0 :                         if (ifp->if_flags & IFF_RUNNING)
     919           0 :                                 error = ENETRESET;
     920             :                         else
     921           0 :                                 smsc_init(sc);
     922             :                 } else {
     923           0 :                         if (ifp->if_flags & IFF_RUNNING)
     924           0 :                                 smsc_stop(sc);
     925             :                 }
     926             :                 break;
     927             : 
     928             :         case SIOCGIFMEDIA:
     929             :         case SIOCSIFMEDIA:
     930           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
     931           0 :                 break;
     932             : 
     933             :         default:
     934           0 :                 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
     935           0 :         }
     936             : 
     937           0 :         if (error == ENETRESET) {
     938           0 :                 if (ifp->if_flags & IFF_RUNNING)
     939           0 :                         smsc_iff(sc);
     940             :                 error = 0;
     941           0 :         }
     942             : 
     943           0 :         splx(s);
     944           0 :         return(error);
     945             : }
     946             : 
     947             : int
     948           0 : smsc_match(struct device *parent, void *match, void *aux)
     949             : {
     950           0 :         struct usb_attach_arg *uaa = aux;
     951             : 
     952           0 :         if (uaa->iface == NULL || uaa->configno != 1)
     953           0 :                 return UMATCH_NONE;
     954             : 
     955           0 :         return (usb_lookup(smsc_devs, uaa->vendor, uaa->product) != NULL) ?
     956             :             UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE;
     957           0 : }
     958             : 
     959             : void
     960           0 : smsc_attach(struct device *parent, struct device *self, void *aux)
     961             : {
     962           0 :         struct smsc_softc *sc = (struct smsc_softc *)self;
     963           0 :         struct usb_attach_arg *uaa = aux;
     964             :         usb_interface_descriptor_t *id;
     965             :         usb_endpoint_descriptor_t *ed;
     966             :         struct mii_data *mii;
     967             :         struct ifnet *ifp;
     968           0 :         uint32_t mac_h, mac_l;
     969             :         int s, i;
     970             : 
     971           0 :         sc->sc_udev = uaa->device;
     972           0 :         sc->sc_iface = uaa->iface;
     973             : 
     974             :         /* Setup the endpoints for the SMSC LAN95xx device(s) */
     975           0 :         usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc,
     976             :             USB_TASK_TYPE_GENERIC);
     977           0 :         rw_init(&sc->sc_mii_lock, "smscmii");
     978           0 :         usb_init_task(&sc->sc_stop_task, (void (*)(void *))smsc_stop, sc,
     979             :             USB_TASK_TYPE_GENERIC);
     980             : 
     981           0 :         id = usbd_get_interface_descriptor(sc->sc_iface);
     982             : 
     983           0 :         if (sc->sc_udev->speed >= USB_SPEED_HIGH)
     984           0 :                 sc->sc_bufsz = SMSC_MAX_BUFSZ;
     985             :         else
     986           0 :                 sc->sc_bufsz = SMSC_MIN_BUFSZ;
     987             : 
     988             :         /* Find endpoints. */
     989           0 :         for (i = 0; i < id->bNumEndpoints; i++) {
     990           0 :                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
     991           0 :                 if (!ed) {
     992           0 :                         printf("%s: couldn't get ep %d\n",
     993           0 :                             sc->sc_dev.dv_xname, i);
     994           0 :                         return;
     995             :                 }
     996           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
     997           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
     998           0 :                         sc->sc_ed[SMSC_ENDPT_RX] = ed->bEndpointAddress;
     999           0 :                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    1000           0 :                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    1001           0 :                         sc->sc_ed[SMSC_ENDPT_TX] = ed->bEndpointAddress;
    1002           0 :                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    1003           0 :                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
    1004           0 :                         sc->sc_ed[SMSC_ENDPT_INTR] = ed->bEndpointAddress;
    1005           0 :                 }
    1006             :         }
    1007             : 
    1008           0 :         s = splnet();
    1009             : 
    1010           0 :         ifp = &sc->sc_ac.ac_if;
    1011           0 :         ifp->if_softc = sc;
    1012           0 :         strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
    1013           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    1014           0 :         ifp->if_ioctl = smsc_ioctl;
    1015           0 :         ifp->if_start = smsc_start;
    1016           0 :         ifp->if_capabilities = IFCAP_VLAN_MTU;
    1017             : 
    1018             :         /* Setup some of the basics */
    1019           0 :         sc->sc_phyno = 1;
    1020             : 
    1021             :         /*
    1022             :          * Attempt to get the mac address, if an EEPROM is not attached this
    1023             :          * will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
    1024             :          * address based on urandom.
    1025             :          */
    1026           0 :         memset(sc->sc_ac.ac_enaddr, 0xff, ETHER_ADDR_LEN);
    1027             :         
    1028             :         /* Check if there is already a MAC address in the register */
    1029           0 :         if ((smsc_read_reg(sc, SMSC_MAC_ADDRL, &mac_l) == 0) &&
    1030           0 :             (smsc_read_reg(sc, SMSC_MAC_ADDRH, &mac_h) == 0)) {
    1031           0 :                 sc->sc_ac.ac_enaddr[5] = (uint8_t)((mac_h >> 8) & 0xff);
    1032           0 :                 sc->sc_ac.ac_enaddr[4] = (uint8_t)((mac_h) & 0xff);
    1033           0 :                 sc->sc_ac.ac_enaddr[3] = (uint8_t)((mac_l >> 24) & 0xff);
    1034           0 :                 sc->sc_ac.ac_enaddr[2] = (uint8_t)((mac_l >> 16) & 0xff);
    1035           0 :                 sc->sc_ac.ac_enaddr[1] = (uint8_t)((mac_l >> 8) & 0xff);
    1036           0 :                 sc->sc_ac.ac_enaddr[0] = (uint8_t)((mac_l) & 0xff);
    1037           0 :         }
    1038             : 
    1039             :         smsc_enaddr_OF(sc);
    1040             :         
    1041           0 :         printf("%s: address %s\n", sc->sc_dev.dv_xname,
    1042           0 :             ether_sprintf(sc->sc_ac.ac_enaddr));
    1043             :         
    1044             :         /* Initialise the chip for the first time */
    1045           0 :         smsc_chip_init(sc);
    1046             : 
    1047             :         /* Initialize MII/media info. */
    1048           0 :         mii = &sc->sc_mii;
    1049           0 :         mii->mii_ifp = ifp;
    1050           0 :         mii->mii_readreg = smsc_miibus_readreg;
    1051           0 :         mii->mii_writereg = smsc_miibus_writereg;
    1052           0 :         mii->mii_statchg = smsc_miibus_statchg;
    1053           0 :         mii->mii_flags = MIIF_AUTOTSLEEP;
    1054             : 
    1055           0 :         ifmedia_init(&mii->mii_media, 0, smsc_ifmedia_upd, smsc_ifmedia_sts);
    1056           0 :         mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
    1057             : 
    1058           0 :         if (LIST_FIRST(&mii->mii_phys) == NULL) {
    1059           0 :                 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
    1060           0 :                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
    1061           0 :         } else
    1062           0 :                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
    1063             : 
    1064           0 :         if_attach(ifp);
    1065           0 :         ether_ifattach(ifp);
    1066             : 
    1067           0 :         timeout_set(&sc->sc_stat_ch, smsc_tick, sc);
    1068             : 
    1069           0 :         splx(s);
    1070           0 : }
    1071             : 
    1072             : int
    1073           0 : smsc_detach(struct device *self, int flags)
    1074             : {
    1075           0 :         struct smsc_softc *sc = (struct smsc_softc *)self;
    1076           0 :         struct ifnet *ifp = &sc->sc_ac.ac_if;
    1077             :         int s;
    1078             : 
    1079           0 :         if (timeout_initialized(&sc->sc_stat_ch))
    1080           0 :                 timeout_del(&sc->sc_stat_ch);
    1081             : 
    1082           0 :         if (sc->sc_ep[SMSC_ENDPT_TX] != NULL)
    1083           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_TX]);
    1084           0 :         if (sc->sc_ep[SMSC_ENDPT_RX] != NULL)
    1085           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
    1086           0 :         if (sc->sc_ep[SMSC_ENDPT_INTR] != NULL)
    1087           0 :                 usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_INTR]);
    1088             : 
    1089             :         /*
    1090             :          * Remove any pending tasks.  They cannot be executing because they run
    1091             :          * in the same thread as detach.
    1092             :          */
    1093           0 :         usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
    1094           0 :         usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
    1095             : 
    1096           0 :         s = splusb();
    1097             : 
    1098           0 :         if (--sc->sc_refcnt >= 0) {
    1099             :                 /* Wait for processes to go away */
    1100           0 :                 usb_detach_wait(&sc->sc_dev);
    1101           0 :         }
    1102             : 
    1103           0 :         if (ifp->if_flags & IFF_RUNNING)
    1104           0 :                 smsc_stop(sc);
    1105             : 
    1106           0 :         mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
    1107           0 :         ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
    1108           0 :         if (ifp->if_softc != NULL) {
    1109           0 :                 ether_ifdetach(ifp);
    1110           0 :                 if_detach(ifp);
    1111           0 :         }
    1112             : 
    1113             : #ifdef DIAGNOSTIC
    1114           0 :         if (sc->sc_ep[SMSC_ENDPT_TX] != NULL ||
    1115           0 :             sc->sc_ep[SMSC_ENDPT_RX] != NULL ||
    1116           0 :             sc->sc_ep[SMSC_ENDPT_INTR] != NULL)
    1117           0 :                 printf("%s: detach has active endpoints\n",
    1118           0 :                     sc->sc_dev.dv_xname);
    1119             : #endif
    1120             : 
    1121           0 :         if (--sc->sc_refcnt >= 0) {
    1122             :                 /* Wait for processes to go away. */
    1123           0 :                 usb_detach_wait(&sc->sc_dev);
    1124           0 :         }
    1125           0 :         splx(s);
    1126             : 
    1127           0 :         return (0);
    1128             : }
    1129             : 
    1130             : void
    1131           0 : smsc_tick_task(void *xsc)
    1132             : {
    1133             :         int                      s;
    1134           0 :         struct smsc_softc       *sc = xsc;
    1135             :         struct mii_data         *mii;
    1136             : 
    1137           0 :         if (sc == NULL)
    1138           0 :                 return;
    1139             : 
    1140           0 :         if (usbd_is_dying(sc->sc_udev))
    1141           0 :                 return;
    1142           0 :         mii = &sc->sc_mii;
    1143           0 :         if (mii == NULL)
    1144           0 :                 return;
    1145             : 
    1146           0 :         s = splnet();
    1147             : 
    1148           0 :         mii_tick(mii);
    1149           0 :         if ((sc->sc_flags & SMSC_FLAG_LINK) == 0)
    1150           0 :                 smsc_miibus_statchg(&sc->sc_dev);
    1151           0 :         timeout_add_sec(&sc->sc_stat_ch, 1);
    1152             : 
    1153           0 :         splx(s);
    1154           0 : }
    1155             : 
    1156             : void
    1157           0 : smsc_lock_mii(struct smsc_softc *sc)
    1158             : {
    1159           0 :         sc->sc_refcnt++;
    1160           0 :         rw_enter_write(&sc->sc_mii_lock);
    1161           0 : }
    1162             : 
    1163             : void
    1164           0 : smsc_unlock_mii(struct smsc_softc *sc)
    1165             : {
    1166           0 :         rw_exit_write(&sc->sc_mii_lock);
    1167           0 :         if (--sc->sc_refcnt < 0)
    1168           0 :                 usb_detach_wakeup(&sc->sc_dev);
    1169           0 : }
    1170             : 
    1171             : void
    1172           0 : smsc_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
    1173             : {
    1174           0 :         struct smsc_chain       *c = (struct smsc_chain *)priv;
    1175           0 :         struct smsc_softc       *sc = c->sc_sc;
    1176           0 :         struct ifnet            *ifp = &sc->sc_ac.ac_if;
    1177           0 :         u_char                  *buf = c->sc_buf;
    1178           0 :         uint32_t                total_len;
    1179             :         uint16_t                pktlen = 0;
    1180           0 :         struct mbuf_list        ml = MBUF_LIST_INITIALIZER();
    1181             :         struct mbuf             *m;
    1182             :         int                     s;
    1183             :         uint32_t                rxhdr;
    1184             : 
    1185           0 :         if (usbd_is_dying(sc->sc_udev))
    1186           0 :                 return;
    1187             : 
    1188           0 :         if (!(ifp->if_flags & IFF_RUNNING))
    1189           0 :                 return;
    1190             : 
    1191           0 :         if (status != USBD_NORMAL_COMPLETION) {
    1192           0 :                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    1193           0 :                         return;
    1194           0 :                 if (usbd_ratecheck(&sc->sc_rx_notice)) {
    1195           0 :                         printf("%s: usb errors on rx: %s\n",
    1196           0 :                             sc->sc_dev.dv_xname, usbd_errstr(status));
    1197           0 :                 }
    1198           0 :                 if (status == USBD_STALLED)
    1199           0 :                         usbd_clear_endpoint_stall_async(sc->sc_ep[SMSC_ENDPT_RX]);
    1200             :                 goto done;
    1201             :         }
    1202             : 
    1203           0 :         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
    1204             :         smsc_dbg_printf(sc, "xfer status total_len %d\n", total_len);
    1205             : 
    1206           0 :         do {
    1207           0 :                 if (total_len < sizeof(rxhdr)) {
    1208             :                         smsc_dbg_printf(sc, "total_len %d < sizeof(rxhdr) %d\n",
    1209             :                             total_len, sizeof(rxhdr));
    1210           0 :                         ifp->if_ierrors++;
    1211           0 :                         goto done;
    1212             :                 }
    1213             : 
    1214           0 :                 buf += pktlen;
    1215             : 
    1216           0 :                 memcpy(&rxhdr, buf, sizeof(rxhdr));
    1217             :                 rxhdr = letoh32(rxhdr);
    1218           0 :                 total_len -= sizeof(rxhdr);
    1219             : 
    1220           0 :                 if (rxhdr & SMSC_RX_STAT_ERROR) {
    1221             :                         smsc_dbg_printf(sc, "rx error (hdr 0x%08x)\n", rxhdr);
    1222           0 :                         ifp->if_ierrors++;
    1223           0 :                         goto done;
    1224             :                 }
    1225             : 
    1226           0 :                 pktlen = (uint16_t)SMSC_RX_STAT_FRM_LENGTH(rxhdr);
    1227             :                 smsc_dbg_printf(sc, "rxeof total_len %d pktlen %d rxhdr "
    1228             :                     "0x%08x\n", total_len, pktlen, rxhdr);
    1229           0 :                 if (pktlen > total_len) {
    1230             :                         smsc_dbg_printf(sc, "pktlen %d > total_len %d\n",
    1231             :                             pktlen, total_len);
    1232           0 :                         ifp->if_ierrors++;
    1233           0 :                         goto done;
    1234             :                 }
    1235             : 
    1236           0 :                 buf += sizeof(rxhdr);
    1237             : 
    1238           0 :                 if (total_len < pktlen)
    1239           0 :                         total_len = 0;
    1240             :                 else
    1241           0 :                         total_len -= pktlen;
    1242             :                 
    1243           0 :                 m = m_devget(buf, pktlen, ETHER_ALIGN);
    1244           0 :                 if (m == NULL) {
    1245             :                         smsc_dbg_printf(sc, "m_devget returned NULL\n");
    1246           0 :                         ifp->if_ierrors++;
    1247           0 :                         goto done;
    1248             :                 }
    1249             : 
    1250           0 :                 ml_enqueue(&ml, m);
    1251           0 :         } while (total_len > 0);
    1252             : 
    1253             : done:
    1254           0 :         s = splnet();
    1255           0 :         if_input(ifp, &ml);
    1256           0 :         splx(s);
    1257           0 :         memset(c->sc_buf, 0, sc->sc_bufsz);
    1258             : 
    1259             :         /* Setup new transfer. */
    1260           0 :         usbd_setup_xfer(xfer, sc->sc_ep[SMSC_ENDPT_RX],
    1261           0 :             c, c->sc_buf, sc->sc_bufsz,
    1262             :             USBD_SHORT_XFER_OK | USBD_NO_COPY,
    1263             :             USBD_NO_TIMEOUT, smsc_rxeof);
    1264           0 :         usbd_transfer(xfer);
    1265             : 
    1266           0 :         return;
    1267           0 : }
    1268             : 
    1269             : void
    1270           0 : smsc_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
    1271             : {
    1272             :         struct smsc_softc       *sc;
    1273             :         struct smsc_chain       *c;
    1274             :         struct ifnet            *ifp;
    1275             :         int                     s;
    1276             : 
    1277           0 :         c = priv;
    1278           0 :         sc = c->sc_sc;
    1279           0 :         ifp = &sc->sc_ac.ac_if;
    1280             : 
    1281           0 :         if (usbd_is_dying(sc->sc_udev))
    1282           0 :                 return;
    1283             : 
    1284           0 :         s = splnet();
    1285             : 
    1286           0 :         if (status != USBD_NORMAL_COMPLETION) {
    1287           0 :                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
    1288           0 :                         splx(s);
    1289           0 :                         return;
    1290             :                 }
    1291           0 :                 ifp->if_oerrors++;
    1292           0 :                 printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname,
    1293           0 :                     usbd_errstr(status));
    1294           0 :                 if (status == USBD_STALLED)
    1295           0 :                         usbd_clear_endpoint_stall_async(sc->sc_ep[SMSC_ENDPT_TX]);
    1296           0 :                 splx(s);
    1297           0 :                 return;
    1298             :         }
    1299             : 
    1300           0 :         ifp->if_timer = 0;
    1301           0 :         ifq_clr_oactive(&ifp->if_snd);
    1302             : 
    1303           0 :         m_freem(c->sc_mbuf);
    1304           0 :         c->sc_mbuf = NULL;
    1305             : 
    1306           0 :         if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
    1307           0 :                 smsc_start(ifp);
    1308             : 
    1309           0 :         splx(s);
    1310           0 : }
    1311             : 
    1312             : int
    1313           0 : smsc_tx_list_init(struct smsc_softc *sc)
    1314             : {
    1315             :         struct smsc_cdata *cd;
    1316             :         struct smsc_chain *c;
    1317             :         int i;
    1318             : 
    1319           0 :         cd = &sc->sc_cdata;
    1320           0 :         for (i = 0; i < SMSC_TX_LIST_CNT; i++) {
    1321           0 :                 c = &cd->tx_chain[i];
    1322           0 :                 c->sc_sc = sc;
    1323           0 :                 c->sc_idx = i;
    1324           0 :                 c->sc_mbuf = NULL;
    1325           0 :                 if (c->sc_xfer == NULL) {
    1326           0 :                         c->sc_xfer = usbd_alloc_xfer(sc->sc_udev);
    1327           0 :                         if (c->sc_xfer == NULL)
    1328           0 :                                 return (ENOBUFS);
    1329           0 :                         c->sc_buf = usbd_alloc_buffer(c->sc_xfer,
    1330           0 :                             sc->sc_bufsz);
    1331           0 :                         if (c->sc_buf == NULL) {
    1332           0 :                                 usbd_free_xfer(c->sc_xfer);
    1333           0 :                                 return (ENOBUFS);
    1334             :                         }
    1335             :                 }
    1336             :         }
    1337             : 
    1338           0 :         return (0);
    1339           0 : }
    1340             : 
    1341             : int
    1342           0 : smsc_rx_list_init(struct smsc_softc *sc)
    1343             : {
    1344             :         struct smsc_cdata *cd;
    1345             :         struct smsc_chain *c;
    1346             :         int i;
    1347             : 
    1348           0 :         cd = &sc->sc_cdata;
    1349           0 :         for (i = 0; i < SMSC_RX_LIST_CNT; i++) {
    1350           0 :                 c = &cd->rx_chain[i];
    1351           0 :                 c->sc_sc = sc;
    1352           0 :                 c->sc_idx = i;
    1353           0 :                 c->sc_mbuf = NULL;
    1354           0 :                 if (c->sc_xfer == NULL) {
    1355           0 :                         c->sc_xfer = usbd_alloc_xfer(sc->sc_udev);
    1356           0 :                         if (c->sc_xfer == NULL)
    1357           0 :                                 return (ENOBUFS);
    1358           0 :                         c->sc_buf = usbd_alloc_buffer(c->sc_xfer,
    1359           0 :                             sc->sc_bufsz);
    1360           0 :                         if (c->sc_buf == NULL) {
    1361           0 :                                 usbd_free_xfer(c->sc_xfer);
    1362           0 :                                 return (ENOBUFS);
    1363             :                         }
    1364             :                 }
    1365             :         }
    1366             : 
    1367           0 :         return (0);
    1368           0 : }
    1369             : 
    1370             : int
    1371           0 : smsc_encap(struct smsc_softc *sc, struct mbuf *m, int idx)
    1372             : {
    1373             :         struct smsc_chain       *c;
    1374             :         usbd_status              err;
    1375             :         uint32_t                 txhdr;
    1376             :         uint32_t                 frm_len = 0;
    1377             : 
    1378           0 :         c = &sc->sc_cdata.tx_chain[idx];
    1379             : 
    1380             :         /*
    1381             :          * Each frame is prefixed with two 32-bit values describing the
    1382             :          * length of the packet and buffer.
    1383             :          */
    1384           0 :         txhdr = SMSC_TX_CTRL_0_BUF_SIZE(m->m_pkthdr.len) | 
    1385           0 :                         SMSC_TX_CTRL_0_FIRST_SEG | SMSC_TX_CTRL_0_LAST_SEG;
    1386             :         txhdr = htole32(txhdr);
    1387           0 :         memcpy(c->sc_buf, &txhdr, sizeof(txhdr));
    1388             :         
    1389           0 :         txhdr = SMSC_TX_CTRL_1_PKT_LENGTH(m->m_pkthdr.len);
    1390             :         txhdr = htole32(txhdr);
    1391           0 :         memcpy(c->sc_buf + 4, &txhdr, sizeof(txhdr));
    1392             :         
    1393             :         frm_len += 8;
    1394             : 
    1395             :         /* Next copy in the actual packet */
    1396           0 :         m_copydata(m, 0, m->m_pkthdr.len, c->sc_buf + frm_len);
    1397           0 :         frm_len += m->m_pkthdr.len;
    1398             : 
    1399           0 :         c->sc_mbuf = m;
    1400             : 
    1401           0 :         usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_TX],
    1402           0 :             c, c->sc_buf, frm_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
    1403             :             10000, smsc_txeof);
    1404             : 
    1405           0 :         err = usbd_transfer(c->sc_xfer);
    1406           0 :         if (err != USBD_IN_PROGRESS) {
    1407           0 :                 smsc_stop(sc);
    1408           0 :                 return (EIO);
    1409             :         }
    1410             : 
    1411           0 :         sc->sc_cdata.tx_cnt++;
    1412             : 
    1413           0 :         return (0);
    1414           0 : }

Generated by: LCOV version 1.13