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

          Line data    Source code
       1             : /*      $OpenBSD: if_ure.c,v 1.8 2017/07/20 08:30:34 mpi Exp $  */
       2             : /*-
       3             :  * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
       4             :  * 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             :  *
      15             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      16             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      17             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      18             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      19             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      20             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      21             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      22             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      23             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      24             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      25             :  * SUCH DAMAGE.
      26             :  */
      27             : 
      28             : #include "bpfilter.h"
      29             : 
      30             : #include <sys/cdefs.h>
      31             : 
      32             : #include <sys/param.h>
      33             : #include <sys/systm.h>
      34             : #include <sys/sockio.h>
      35             : #include <sys/rwlock.h>
      36             : #include <sys/mbuf.h>
      37             : #include <sys/kernel.h>
      38             : #include <sys/socket.h>
      39             : #include <sys/device.h>
      40             : 
      41             : #include <machine/bus.h>
      42             : 
      43             : #include <net/if.h>
      44             : #include <net/if_media.h>
      45             : 
      46             : #if NBPFILTER > 0
      47             : #include <net/bpf.h>
      48             : #endif
      49             : 
      50             : #include <netinet/in.h>
      51             : #include <netinet/if_ether.h>
      52             : 
      53             : #include <dev/mii/miivar.h>
      54             : 
      55             : #include <dev/usb/usb.h>
      56             : #include <dev/usb/usbdi.h>
      57             : #include <dev/usb/usbdi_util.h>
      58             : #include <dev/usb/usbdivar.h>
      59             : #include <dev/usb/usbdevs.h>
      60             : 
      61             : #include <dev/ic/rtl81x9reg.h>
      62             : #include <dev/usb/if_urereg.h>
      63             : 
      64             : #ifdef URE_DEBUG
      65             : #define DPRINTF(x)      do { if (uredebug) printf x; } while (0)
      66             : #define DPRINTFN(n,x)   do { if (uredebug >= (n)) printf x; } while (0)
      67             : int     uredebug = 0;
      68             : #else
      69             : #define DPRINTF(x)
      70             : #define DPRINTFN(n,x)
      71             : #endif
      72             : 
      73             : const struct usb_devno ure_devs[] = {
      74             :         { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 },
      75             :         { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 }
      76             : };
      77             : 
      78             : int     ure_match(struct device *, void *, void *);
      79             : void    ure_attach(struct device *, struct device *, void *);
      80             : int     ure_detach(struct device *, int);
      81             : 
      82             : struct cfdriver ure_cd = {
      83             :         NULL, "ure", DV_IFNET
      84             : };
      85             : 
      86             : const struct cfattach ure_ca = {
      87             :         sizeof(struct ure_softc), ure_match, ure_attach, ure_detach
      88             : };
      89             : 
      90             : int             ure_ctl(struct ure_softc *, uint8_t, uint16_t, uint16_t,
      91             :                     void *, int);
      92             : int             ure_read_mem(struct ure_softc *, uint16_t, uint16_t, void *,
      93             :                     int);
      94             : int             ure_write_mem(struct ure_softc *, uint16_t, uint16_t, void *,
      95             :                     int);
      96             : uint8_t         ure_read_1(struct ure_softc *, uint16_t, uint16_t);
      97             : uint16_t        ure_read_2(struct ure_softc *, uint16_t, uint16_t);
      98             : uint32_t        ure_read_4(struct ure_softc *, uint16_t, uint16_t);
      99             : int             ure_write_1(struct ure_softc *, uint16_t, uint16_t, uint32_t);
     100             : int             ure_write_2(struct ure_softc *, uint16_t, uint16_t, uint32_t);
     101             : int             ure_write_4(struct ure_softc *, uint16_t, uint16_t, uint32_t);
     102             : uint16_t        ure_ocp_reg_read(struct ure_softc *, uint16_t);
     103             : void            ure_ocp_reg_write(struct ure_softc *, uint16_t, uint16_t);
     104             : 
     105             : void            ure_init(void *);
     106             : void            ure_stop(struct ure_softc *);
     107             : void            ure_start(struct ifnet *);
     108             : void            ure_reset(struct ure_softc *);
     109             : 
     110             : void            ure_miibus_statchg(struct device *);
     111             : int             ure_miibus_readreg(struct device *, int, int);
     112             : void            ure_miibus_writereg(struct device *, int, int, int);
     113             : void            ure_lock_mii(struct ure_softc *);
     114             : void            ure_unlock_mii(struct ure_softc *);
     115             : 
     116             : int             ure_encap(struct ure_softc *, struct mbuf *, int);
     117             : void            ure_rxeof(struct usbd_xfer *, void *, usbd_status);
     118             : void            ure_txeof(struct usbd_xfer *, void *, usbd_status);
     119             : int             ure_rx_list_init(struct ure_softc *);
     120             : int             ure_tx_list_init(struct ure_softc *);
     121             : 
     122             : void            ure_tick_task(void *);
     123             : void            ure_tick(void *);
     124             : 
     125             : int             ure_ifmedia_upd(struct ifnet *);
     126             : void            ure_ifmedia_sts(struct ifnet *, struct ifmediareq *);
     127             : int             ure_ioctl(struct ifnet *, u_long, caddr_t);
     128             : void            ure_rtl8152_init(struct ure_softc *);
     129             : void            ure_rtl8153_init(struct ure_softc *);
     130             : void            ure_disable_teredo(struct ure_softc *);
     131             : void            ure_init_fifo(struct ure_softc *);
     132             : 
     133             : 
     134             : 
     135             : int
     136           0 : ure_ctl(struct ure_softc *sc, uint8_t rw, uint16_t val, uint16_t index,
     137             :     void *buf, int len)
     138             : {
     139           0 :         usb_device_request_t    req;
     140             :         usbd_status             err;
     141             : 
     142           0 :         if (usbd_is_dying(sc->ure_udev))
     143           0 :                 return 0;
     144             : 
     145           0 :         if (rw == URE_CTL_WRITE)
     146           0 :                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
     147             :         else
     148           0 :                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
     149           0 :         req.bRequest = UR_SET_ADDRESS;
     150           0 :         USETW(req.wValue, val);
     151           0 :         USETW(req.wIndex, index);
     152           0 :         USETW(req.wLength, len);
     153             : 
     154             :         DPRINTFN(5, ("ure_ctl: rw %d, val 0x%04hu, index 0x%04hu, len %d\n",
     155             :             rw, val, index, len));
     156           0 :         err = usbd_do_request(sc->ure_udev, &req, buf);
     157           0 :         if (err) {
     158             :                 DPRINTF(("ure_ctl: error %d\n", err));
     159           0 :                 return -1;
     160             :         }
     161             : 
     162           0 :         return 0;
     163           0 : }
     164             : 
     165             : int
     166           0 : ure_read_mem(struct ure_softc *sc, uint16_t addr, uint16_t index,
     167             :     void *buf, int len)
     168             : {
     169             : 
     170           0 :         return (ure_ctl(sc, URE_CTL_READ, addr, index, buf, len));
     171             : }
     172             : 
     173             : int
     174           0 : ure_write_mem(struct ure_softc *sc, uint16_t addr, uint16_t index,
     175             :     void *buf, int len)
     176             : {
     177             : 
     178           0 :         return (ure_ctl(sc, URE_CTL_WRITE, addr, index, buf, len));
     179             : }
     180             : 
     181             : uint8_t
     182           0 : ure_read_1(struct ure_softc *sc, uint16_t reg, uint16_t index)
     183             : {
     184             :         uint32_t val;
     185           0 :         uint8_t temp[4];
     186             :         uint8_t shift;
     187             : 
     188           0 :         shift = (reg & 3) << 3;
     189           0 :         reg &= ~3;
     190             :         
     191           0 :         ure_read_mem(sc, reg, index, &temp, 4);
     192           0 :         val = UGETDW(temp);
     193           0 :         val >>= shift;
     194             : 
     195           0 :         return (val & 0xff);
     196           0 : }
     197             : 
     198             : uint16_t
     199           0 : ure_read_2(struct ure_softc *sc, uint16_t reg, uint16_t index)
     200             : {
     201             :         uint32_t val;
     202           0 :         uint8_t temp[4];
     203             :         uint8_t shift;
     204             : 
     205           0 :         shift = (reg & 2) << 3;
     206           0 :         reg &= ~3;
     207             : 
     208           0 :         ure_read_mem(sc, reg, index, &temp, 4);
     209           0 :         val = UGETDW(temp);
     210           0 :         val >>= shift;
     211             : 
     212           0 :         return (val & 0xffff);
     213           0 : }
     214             : 
     215             : uint32_t
     216           0 : ure_read_4(struct ure_softc *sc, uint16_t reg, uint16_t index)
     217             : {
     218           0 :         uint8_t temp[4];
     219             : 
     220           0 :         ure_read_mem(sc, reg, index, &temp, 4);
     221           0 :         return (UGETDW(temp));
     222           0 : }
     223             : 
     224             : int
     225           0 : ure_write_1(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val)
     226             : {
     227             :         uint16_t byen;
     228           0 :         uint8_t temp[4];
     229             :         uint8_t shift;
     230             : 
     231             :         byen = URE_BYTE_EN_BYTE;
     232           0 :         shift = reg & 3;
     233           0 :         val &= 0xff;
     234             : 
     235           0 :         if (reg & 3) {
     236           0 :                 byen <<= shift;
     237           0 :                 val <<= (shift << 3);
     238           0 :                 reg &= ~3;
     239           0 :         }
     240             : 
     241           0 :         USETDW(temp, val);
     242           0 :         return (ure_write_mem(sc, reg, index | byen, &temp, 4));
     243           0 : }
     244             : 
     245             : int
     246           0 : ure_write_2(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val)
     247             : {
     248             :         uint16_t byen;
     249           0 :         uint8_t temp[4];
     250             :         uint8_t shift;
     251             : 
     252             :         byen = URE_BYTE_EN_WORD;
     253           0 :         shift = reg & 2;
     254           0 :         val &= 0xffff;
     255             : 
     256           0 :         if (reg & 2) {
     257           0 :                 byen <<= shift;
     258           0 :                 val <<= (shift << 3);
     259           0 :                 reg &= ~3;
     260           0 :         }
     261             : 
     262           0 :         USETDW(temp, val);
     263           0 :         return (ure_write_mem(sc, reg, index | byen, &temp, 4));
     264           0 : }
     265             : 
     266             : int
     267           0 : ure_write_4(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val)
     268             : {
     269           0 :         uint8_t temp[4];
     270             : 
     271           0 :         USETDW(temp, val);
     272           0 :         return (ure_write_mem(sc, reg, index | URE_BYTE_EN_DWORD, &temp, 4));
     273           0 : }
     274             : 
     275             : uint16_t
     276           0 : ure_ocp_reg_read(struct ure_softc *sc, uint16_t addr)
     277             : {
     278             :         uint16_t reg;
     279             : 
     280           0 :         ure_write_2(sc, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000);
     281           0 :         reg = (addr & 0x0fff) | 0xb000;
     282             : 
     283           0 :         return (ure_read_2(sc, reg, URE_MCU_TYPE_PLA));
     284             : }
     285             : 
     286             : void
     287           0 : ure_ocp_reg_write(struct ure_softc *sc, uint16_t addr, uint16_t data)
     288             : {
     289             :         uint16_t reg;
     290             : 
     291           0 :         ure_write_2(sc, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000);
     292           0 :         reg = (addr & 0x0fff) | 0xb000;
     293             : 
     294           0 :         ure_write_2(sc, reg, URE_MCU_TYPE_PLA, data);
     295           0 : }
     296             : 
     297             : int
     298           0 : ure_miibus_readreg(struct device *dev, int phy, int reg)
     299             : {
     300           0 :         struct ure_softc        *sc = (void *)dev;
     301             :         uint16_t                val;
     302             : 
     303           0 :         if (usbd_is_dying(sc->ure_udev))
     304           0 :                 return 0;
     305             : 
     306             :         /* Let the rgephy driver read the URE_PLA_PHYSTATUS register. */
     307           0 :         if (reg == RL_GMEDIASTAT)
     308           0 :                 return ure_read_1(sc, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA);
     309             : 
     310           0 :         ure_lock_mii(sc);
     311           0 :         val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + reg * 2);
     312           0 :         ure_unlock_mii(sc);
     313             : 
     314           0 :         return val;     /* letoh16? */
     315           0 : }
     316             : 
     317             : void
     318           0 : ure_miibus_writereg(struct device *dev, int phy, int reg, int val)
     319             : {
     320           0 :         struct ure_softc        *sc = (void *)dev;
     321             : 
     322           0 :         ure_lock_mii(sc);
     323           0 :         ure_ocp_reg_write(sc, URE_OCP_BASE_MII + reg * 2, val); /* htole16? */
     324           0 :         ure_unlock_mii(sc);
     325           0 : }
     326             : 
     327             : void
     328           0 : ure_miibus_statchg(struct device *dev)
     329             : {
     330           0 :         struct ure_softc        *sc = (void *)dev;
     331           0 :         struct mii_data         *mii = &sc->ure_mii;
     332           0 :         struct ifnet            *ifp = &sc->ure_ac.ac_if;
     333             : 
     334           0 :         if ((ifp->if_flags & IFF_RUNNING) == 0)
     335           0 :                 return;
     336             : 
     337           0 :         sc->ure_flags &= ~URE_FLAG_LINK;
     338           0 :         if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
     339             :             (IFM_ACTIVE | IFM_AVALID)) {
     340           0 :                 switch (IFM_SUBTYPE(mii->mii_media_active)) {
     341             :                 case IFM_10_T:
     342             :                 case IFM_100_TX:
     343           0 :                         sc->ure_flags |= URE_FLAG_LINK;
     344           0 :                         break;
     345             :                 case IFM_1000_T:
     346           0 :                         if ((sc->ure_flags & URE_FLAG_8152) != 0)
     347             :                                 break;
     348           0 :                         sc->ure_flags |= URE_FLAG_LINK;
     349           0 :                         break;
     350             :                 default:
     351             :                         break;
     352             :                 }
     353             :         }
     354           0 : }
     355             : 
     356             : int
     357           0 : ure_ifmedia_upd(struct ifnet *ifp)
     358             : {
     359           0 :         struct ure_softc *sc = ifp->if_softc;
     360           0 :         struct mii_data *mii = &sc->ure_mii;
     361             :         int err;
     362             : 
     363           0 :         sc->ure_flags &= ~URE_FLAG_LINK;
     364           0 :         if (mii->mii_instance) {
     365             :                 struct mii_softc *miisc;
     366           0 :                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
     367           0 :                         PHY_RESET(miisc);
     368           0 :         }
     369             : 
     370           0 :         err = mii_mediachg(mii);
     371           0 :         if (err == ENXIO)
     372           0 :                 return 0;
     373             :         else
     374           0 :                 return err;
     375           0 : }
     376             : 
     377             : void
     378           0 : ure_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
     379             : {
     380           0 :         struct ure_softc *sc = ifp->if_softc;
     381           0 :         struct mii_data *mii = &sc->ure_mii;
     382             : 
     383           0 :         mii_pollstat(mii);
     384           0 :         ifmr->ifm_active = mii->mii_media_active;
     385           0 :         ifmr->ifm_status = mii->mii_media_status;
     386           0 : }
     387             : 
     388             : void
     389           0 : ure_iff(struct ure_softc *sc)
     390             : {
     391           0 :         struct ifnet            *ifp = &sc->ure_ac.ac_if;
     392             :         struct ether_multi      *enm;
     393             :         struct ether_multistep  step;
     394             :         uint32_t                hashes[2] = { 0, 0 };
     395             :         uint32_t                hash;
     396             :         uint32_t                rxmode;
     397             : 
     398           0 :         if (usbd_is_dying(sc->ure_udev))
     399           0 :                 return;
     400             : 
     401           0 :         rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA);
     402           0 :         rxmode &= ~URE_RCR_ACPT_ALL;
     403           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
     404             : 
     405             :         /*
     406             :          * Always accept frames destined to our station address.
     407             :          * Always accept broadcast frames.
     408             :          */
     409           0 :         rxmode |= URE_RCR_APM | URE_RCR_AB;
     410             : 
     411           0 :         if (ifp->if_flags & IFF_PROMISC || sc->ure_ac.ac_multirangecnt > 0) {
     412           0 :                 ifp->if_flags |= IFF_ALLMULTI;
     413           0 :                 rxmode |= URE_RCR_AM;
     414           0 :                 if (ifp->if_flags & IFF_PROMISC)
     415           0 :                         rxmode |= URE_RCR_AAP;
     416             :                 hashes[0] = hashes[1] = 0xffffffff;
     417           0 :         } else {
     418           0 :                 rxmode |= URE_RCR_AM;
     419             : 
     420           0 :                 ETHER_FIRST_MULTI(step, &sc->ure_ac, enm);
     421           0 :                 while (enm != NULL) {
     422           0 :                         hash = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN)
     423           0 :                             >> 26;
     424           0 :                         if (hash < 32)
     425           0 :                                 hashes[0] |= (1 << hash);
     426             :                         else
     427           0 :                                 hashes[1] |= (1 << (hash - 32));
     428             : 
     429           0 :                         ETHER_NEXT_MULTI(step, enm);
     430             :                 }
     431             : 
     432           0 :                 hash = swap32(hashes[0]);
     433           0 :                 hashes[0] = swap32(hashes[1]);
     434             :                 hashes[1] = hash;
     435             :         }
     436             : 
     437           0 :         ure_write_4(sc, URE_PLA_MAR0, URE_MCU_TYPE_PLA, hashes[0]);
     438           0 :         ure_write_4(sc, URE_PLA_MAR4, URE_MCU_TYPE_PLA, hashes[1]);
     439           0 :         ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
     440           0 : }
     441             : 
     442             : void
     443           0 : ure_reset(struct ure_softc *sc)
     444             : {
     445             :         int i;
     446             : 
     447           0 :         ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST);
     448             : 
     449           0 :         for (i = 0; i < URE_TIMEOUT; i++) {
     450           0 :                 if (!(ure_read_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA) &
     451             :                     URE_CR_RST))
     452             :                         break;
     453           0 :                 usbd_delay_ms(sc->ure_udev, 10);
     454             :         }
     455           0 :         if (i == URE_TIMEOUT)
     456           0 :                 printf("%s: reset never completed\n", sc->ure_dev.dv_xname);
     457           0 : }
     458             : 
     459             : void
     460           0 : ure_init(void *xsc)
     461             : {
     462           0 :         struct ure_softc        *sc = xsc;
     463             :         struct ure_chain        *c;
     464           0 :         struct ifnet            *ifp = &sc->ure_ac.ac_if;
     465             :         usbd_status             err;
     466             :         int                     s, i;
     467             : 
     468           0 :         s = splnet();
     469             : 
     470             :         /* Cancel pending I/O. */
     471           0 :         ure_stop(sc);
     472             : 
     473           0 :         if (ure_rx_list_init(sc) == ENOBUFS) {
     474           0 :                 printf("%s: rx list init failed\n", sc->ure_dev.dv_xname);
     475           0 :                 splx(s);
     476           0 :                 return;
     477             :         }
     478             : 
     479           0 :         if (ure_tx_list_init(sc) == ENOBUFS) {
     480           0 :                 printf("%s: tx list init failed\n", sc->ure_dev.dv_xname);
     481           0 :                 splx(s);
     482           0 :                 return;
     483             :         }
     484             : 
     485             :         /* Set MAC address. */
     486           0 :         ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG);
     487           0 :         ure_write_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES,
     488           0 :             sc->ure_ac.ac_enaddr, 8);
     489           0 :         ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML);
     490             : 
     491             :         /* Reset the packet filter. */
     492           0 :         ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA,
     493           0 :             ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) &
     494             :             ~URE_FMC_FCR_MCU_EN);
     495           0 :         ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA,
     496           0 :             ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) |
     497             :             URE_FMC_FCR_MCU_EN);
     498             :             
     499             :         /* Enable transmit and receive. */
     500           0 :         ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA,
     501           0 :             ure_read_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE |
     502             :             URE_CR_TE);
     503             : 
     504           0 :         ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
     505           0 :             ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) &
     506             :             ~URE_RXDY_GATED_EN);
     507             : 
     508             :         /* Load the multicast filter. */
     509           0 :         ure_iff(sc);
     510             : 
     511             :         /* Open RX and TX pipes. */
     512           0 :         err = usbd_open_pipe(sc->ure_iface, sc->ure_ed[URE_ENDPT_RX],
     513           0 :             USBD_EXCLUSIVE_USE, &sc->ure_ep[URE_ENDPT_RX]);
     514           0 :         if (err) {
     515           0 :                 printf("%s: open rx pipe failed: %s\n",
     516           0 :                     sc->ure_dev.dv_xname, usbd_errstr(err));
     517           0 :                 splx(s);
     518           0 :                 return;
     519             :         }
     520             : 
     521           0 :         err = usbd_open_pipe(sc->ure_iface, sc->ure_ed[URE_ENDPT_TX],
     522           0 :             USBD_EXCLUSIVE_USE, &sc->ure_ep[URE_ENDPT_TX]);
     523           0 :         if (err) {
     524           0 :                 printf("%s: open tx pipe failed: %s\n",
     525           0 :                     sc->ure_dev.dv_xname, usbd_errstr(err));
     526           0 :                 splx(s);
     527           0 :                 return;
     528             :         }
     529             : 
     530             :         /* Start up the receive pipe. */
     531           0 :         for (i = 0; i < URE_RX_LIST_CNT; i++) {
     532           0 :                 c = &sc->ure_cdata.rx_chain[i];
     533           0 :                 usbd_setup_xfer(c->uc_xfer, sc->ure_ep[URE_ENDPT_RX],
     534           0 :                     c, c->uc_buf, sc->ure_bufsz,
     535             :                     USBD_SHORT_XFER_OK | USBD_NO_COPY,
     536             :                     USBD_NO_TIMEOUT, ure_rxeof);
     537           0 :                 usbd_transfer(c->uc_xfer);
     538             :         }
     539             : 
     540             :         /* Indicate we are up and running. */
     541           0 :         ifp->if_flags |= IFF_RUNNING;
     542           0 :         ifq_clr_oactive(&ifp->if_snd);
     543             : 
     544           0 :         timeout_add_sec(&sc->ure_stat_ch, 1);
     545             : 
     546           0 :         splx(s);
     547           0 : }
     548             : 
     549             : void
     550           0 : ure_start(struct ifnet *ifp)
     551             : {
     552           0 :         struct ure_softc        *sc = ifp->if_softc;
     553             :         struct mbuf             *m_head = NULL;
     554             : 
     555           0 :         if ((sc->ure_flags & URE_FLAG_LINK) == 0 ||
     556           0 :             ifq_is_oactive(&ifp->if_snd)) {
     557           0 :                 return;
     558             :         }
     559             : 
     560           0 :         m_head = ifq_deq_begin(&ifp->if_snd);
     561           0 :         if (m_head == NULL) {
     562           0 :                 return;
     563             :         }
     564             : 
     565           0 :         if (ure_encap(sc, m_head, 0)) {
     566           0 :                 ifq_deq_rollback(&ifp->if_snd, m_head);
     567           0 :                 ifq_set_oactive(&ifp->if_snd);
     568           0 :                 return;
     569             :         }
     570           0 :         ifq_deq_commit(&ifp->if_snd, m_head);
     571             : 
     572             : #if NBPFILTER > 0
     573           0 :         if (ifp->if_bpf)
     574           0 :                 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
     575             : #endif
     576           0 :         ifq_set_oactive(&ifp->if_snd);
     577           0 : }
     578             : 
     579             : void
     580           0 : ure_tick(void *xsc)
     581             : {
     582           0 :         struct ure_softc *sc = xsc;
     583             : 
     584           0 :         if (sc == NULL)
     585           0 :                 return;
     586             : 
     587           0 :         if (usbd_is_dying(sc->ure_udev))
     588           0 :                 return;
     589             : 
     590           0 :         usb_add_task(sc->ure_udev, &sc->ure_tick_task);
     591           0 : }
     592             : 
     593             : void
     594           0 : ure_stop(struct ure_softc *sc)
     595             : {
     596             :         usbd_status             err;
     597             :         struct ifnet            *ifp;
     598             :         int                     i;
     599             : 
     600           0 :         ure_reset(sc);
     601             : 
     602           0 :         ifp = &sc->ure_ac.ac_if;
     603           0 :         ifp->if_timer = 0;
     604           0 :         ifp->if_flags &= ~IFF_RUNNING;
     605           0 :         ifq_clr_oactive(&ifp->if_snd);
     606             : 
     607           0 :         timeout_del(&sc->ure_stat_ch);
     608             : 
     609           0 :         if (sc->ure_ep[URE_ENDPT_RX] != NULL) {
     610           0 :                 usbd_abort_pipe(sc->ure_ep[URE_ENDPT_RX]);
     611           0 :                 err = usbd_close_pipe(sc->ure_ep[URE_ENDPT_RX]);
     612           0 :                 if (err) {
     613           0 :                         printf("%s: close rx pipe failed: %s\n",
     614           0 :                             sc->ure_dev.dv_xname, usbd_errstr(err));
     615           0 :                 }
     616           0 :                 sc->ure_ep[URE_ENDPT_RX] = NULL;
     617           0 :         }
     618             : 
     619           0 :         if (sc->ure_ep[URE_ENDPT_TX] != NULL) {
     620           0 :                 usbd_abort_pipe(sc->ure_ep[URE_ENDPT_TX]);
     621           0 :                 err = usbd_close_pipe(sc->ure_ep[URE_ENDPT_TX]);
     622           0 :                 if (err) {
     623           0 :                         printf("%s: close tx pipe failed: %s\n",
     624           0 :                             sc->ure_dev.dv_xname, usbd_errstr(err));
     625           0 :                 }
     626           0 :                 sc->ure_ep[URE_ENDPT_TX] = NULL;
     627           0 :         }
     628             : 
     629           0 :         for (i = 0; i < URE_RX_LIST_CNT; i++) {
     630           0 :                 if (sc->ure_cdata.rx_chain[i].uc_mbuf != NULL) {
     631           0 :                         m_freem(sc->ure_cdata.rx_chain[i].uc_mbuf);
     632           0 :                         sc->ure_cdata.rx_chain[i].uc_mbuf = NULL;
     633           0 :                 }
     634           0 :                 if (sc->ure_cdata.rx_chain[i].uc_xfer != NULL) {
     635           0 :                         usbd_free_xfer(sc->ure_cdata.rx_chain[i].uc_xfer);
     636           0 :                         sc->ure_cdata.rx_chain[i].uc_xfer = NULL;
     637           0 :                 }
     638             :         }
     639             : 
     640           0 :         for (i = 0; i < URE_TX_LIST_CNT; i++) {
     641           0 :                 if (sc->ure_cdata.tx_chain[i].uc_mbuf != NULL) {
     642           0 :                         m_freem(sc->ure_cdata.tx_chain[i].uc_mbuf);
     643           0 :                         sc->ure_cdata.tx_chain[i].uc_mbuf = NULL;
     644           0 :                 }
     645           0 :                 if (sc->ure_cdata.tx_chain[i].uc_xfer != NULL) {
     646           0 :                         usbd_free_xfer(sc->ure_cdata.tx_chain[i].uc_xfer);
     647           0 :                         sc->ure_cdata.tx_chain[i].uc_xfer = NULL;
     648           0 :                 }
     649             :         }
     650           0 : }
     651             : 
     652             : void
     653           0 : ure_rtl8152_init(struct ure_softc *sc)
     654             : {
     655             :         uint32_t pwrctrl;
     656             : 
     657             :         /* Disable ALDPS. */
     658           0 :         ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
     659             :             URE_DIS_SDSAVE);
     660           0 :         usbd_delay_ms(sc->ure_udev, 20);
     661             : 
     662           0 :         if (sc->ure_chip & URE_CHIP_VER_4C00) {
     663           0 :                 ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
     664           0 :                     ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
     665             :                     ~URE_LED_MODE_MASK);
     666           0 :         }
     667             : 
     668           0 :         ure_write_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB,
     669           0 :             ure_read_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) &
     670             :             ~URE_POWER_CUT);
     671           0 :         ure_write_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB,
     672           0 :             ure_read_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) &
     673             :             ~URE_RESUME_INDICATE);
     674             : 
     675           0 :         ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
     676           0 :             ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
     677           0 :             URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH);
     678           0 :         pwrctrl = ure_read_4(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA);
     679           0 :         pwrctrl &= ~URE_MCU_CLK_RATIO_MASK;
     680           0 :         pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN;
     681           0 :         ure_write_4(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl);
     682           0 :         ure_write_2(sc, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA,
     683             :             URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK |
     684             :             URE_SPDWN_LINKCHG_MSK);
     685             : 
     686             :         /* Enable Rx aggregation. */
     687           0 :         ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
     688           0 :             ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
     689             :             ~URE_RX_AGG_DISABLE);
     690             : 
     691             :         /* Disable ALDPS. */
     692           0 :         ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA |
     693             :             URE_DIS_SDSAVE);
     694           0 :         usbd_delay_ms(sc->ure_udev, 20);
     695             : 
     696           0 :         ure_init_fifo(sc);
     697             : 
     698           0 :         ure_write_1(sc, URE_USB_TX_AGG, URE_MCU_TYPE_USB,
     699             :             URE_TX_AGG_MAX_THRESHOLD);
     700           0 :         ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH);
     701           0 :         ure_write_4(sc, URE_USB_TX_DMA, URE_MCU_TYPE_USB,
     702             :             URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1);
     703           0 : }
     704             : 
     705             : void
     706           0 : ure_rtl8153_init(struct ure_softc *sc)
     707             : {
     708             :         uint16_t val;
     709           0 :         uint8_t u1u2[8];
     710             :         int i;
     711             : 
     712             :         /* Disable ALDPS. */
     713           0 :         ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
     714           0 :             ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
     715           0 :         usbd_delay_ms(sc->ure_udev, 20);
     716             : 
     717           0 :         memset(u1u2, 0x00, sizeof(u1u2));
     718           0 :         ure_write_mem(sc, URE_USB_TOLERANCE,
     719             :             URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
     720             : 
     721           0 :         for (i = 0; i < URE_TIMEOUT; i++) {
     722           0 :                 if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) &
     723             :                     URE_AUTOLOAD_DONE)
     724             :                         break;
     725           0 :                 usbd_delay_ms(sc->ure_udev, 10);
     726             :         }
     727           0 :         if (i == URE_TIMEOUT)
     728           0 :                 printf("%s: timeout waiting for chip autoload\n",
     729           0 :                     sc->ure_dev.dv_xname);
     730             : 
     731           0 :         for (i = 0; i < URE_TIMEOUT; i++) {
     732           0 :                 val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) &
     733             :                     URE_PHY_STAT_MASK;
     734           0 :                 if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN)
     735             :                         break;
     736           0 :                 usbd_delay_ms(sc->ure_udev, 10);
     737             :         }
     738           0 :         if (i == URE_TIMEOUT)
     739           0 :                 printf("%s: timeout waiting for phy to stabilize\n",
     740           0 :                     sc->ure_dev.dv_xname);
     741             :         
     742           0 :         ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB,
     743           0 :             ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) &
     744             :             ~URE_U2P3_ENABLE);
     745             : 
     746           0 :         if (sc->ure_chip & URE_CHIP_VER_5C10) {
     747           0 :                 val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB);
     748           0 :                 val &= ~URE_PWD_DN_SCALE_MASK;
     749           0 :                 val |= URE_PWD_DN_SCALE(96);
     750           0 :                 ure_write_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val);
     751             : 
     752           0 :                 ure_write_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB,
     753           0 :                     ure_read_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB) |
     754           0 :                     URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND);
     755           0 :         } else if (sc->ure_chip & URE_CHIP_VER_5C20) {
     756           0 :                 ure_write_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA,
     757           0 :                     ure_read_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) &
     758             :                     ~URE_ECM_ALDPS);
     759           0 :         }
     760           0 :         if (sc->ure_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) {
     761           0 :                 val = ure_read_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB);
     762           0 :                 if (ure_read_2(sc, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) ==
     763             :                     0)
     764           0 :                         val &= ~URE_DYNAMIC_BURST;
     765             :                 else
     766           0 :                         val |= URE_DYNAMIC_BURST;
     767           0 :                 ure_write_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val);
     768           0 :         }
     769             : 
     770           0 :         ure_write_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB,
     771           0 :             ure_read_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) |
     772             :             URE_EP4_FULL_FC);
     773             :         
     774           0 :         ure_write_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB,
     775           0 :             ure_read_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) &
     776             :             ~URE_TIMER11_EN);
     777             : 
     778           0 :         ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
     779           0 :             ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
     780             :             ~URE_LED_MODE_MASK);
     781             :             
     782           0 :         if ((sc->ure_chip & URE_CHIP_VER_5C10) &&
     783           0 :             sc->ure_udev->speed != USB_SPEED_SUPER)
     784           0 :                 val = URE_LPM_TIMER_500MS;
     785             :         else
     786             :                 val = URE_LPM_TIMER_500US;
     787           0 :         ure_write_1(sc, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB,
     788           0 :             val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM);
     789             : 
     790           0 :         val = ure_read_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB);
     791           0 :         val &= ~URE_SEN_VAL_MASK;
     792           0 :         val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE;
     793           0 :         ure_write_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val);
     794             : 
     795           0 :         ure_write_2(sc, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001);
     796             : 
     797           0 :         ure_write_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB,
     798           0 :             ure_read_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) &
     799             :             ~(URE_PWR_EN | URE_PHASE2_EN));
     800           0 :         ure_write_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB,
     801           0 :             ure_read_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB) &
     802             :             ~URE_PCUT_STATUS);
     803             : 
     804           0 :         memset(u1u2, 0xff, sizeof(u1u2));
     805           0 :         ure_write_mem(sc, URE_USB_TOLERANCE,
     806             :             URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
     807             : 
     808           0 :         ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
     809             :             URE_ALDPS_SPDWN_RATIO);
     810           0 :         ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
     811             :             URE_EEE_SPDWN_RATIO);
     812           0 :         ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
     813             :             URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN |
     814             :             URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN);
     815           0 :         ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
     816             :             URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN |
     817             :             URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN |
     818             :             URE_EEE_SPDWN_EN);
     819             : 
     820           0 :         val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
     821           0 :         if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
     822           0 :                 val |= URE_U2P3_ENABLE;
     823             :         else
     824           0 :                 val &= ~URE_U2P3_ENABLE;
     825           0 :         ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
     826             : 
     827           0 :         memset(u1u2, 0x00, sizeof(u1u2));
     828           0 :         ure_write_mem(sc, URE_USB_TOLERANCE,
     829             :             URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
     830             : 
     831             :         /* Disable ALDPS. */
     832           0 :         ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
     833           0 :             ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
     834           0 :         usbd_delay_ms(sc->ure_udev, 20);
     835             : 
     836           0 :         ure_init_fifo(sc);
     837             : 
     838             :         /* Enable Rx aggregation. */
     839           0 :         ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
     840           0 :             ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) &
     841             :             ~URE_RX_AGG_DISABLE);
     842             : 
     843           0 :         val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
     844           0 :         if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
     845           0 :                 val |= URE_U2P3_ENABLE;
     846             :         else
     847           0 :                 val &= ~URE_U2P3_ENABLE;
     848           0 :         ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
     849             : 
     850           0 :         memset(u1u2, 0xff, sizeof(u1u2));
     851           0 :         ure_write_mem(sc, URE_USB_TOLERANCE,
     852             :             URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
     853           0 : }
     854             : 
     855             : void
     856           0 : ure_disable_teredo(struct ure_softc *sc)
     857             : {
     858           0 :         ure_write_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA,
     859           0 :             ure_read_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & 
     860             :             ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN));
     861           0 :         ure_write_2(sc, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA,
     862             :             URE_WDT6_SET_MODE);
     863           0 :         ure_write_2(sc, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0);
     864           0 :         ure_write_4(sc, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0);
     865           0 : }
     866             : 
     867             : void
     868           0 : ure_init_fifo(struct ure_softc *sc)
     869             : {
     870             :         uint32_t rx_fifo1, rx_fifo2;
     871             :         int i;
     872             : 
     873           0 :         ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
     874           0 :             ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) |
     875             :             URE_RXDY_GATED_EN);
     876             : 
     877           0 :         ure_disable_teredo(sc);
     878             : 
     879           0 :         ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA,
     880           0 :             ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) &
     881             :             ~URE_RCR_ACPT_ALL);
     882             : 
     883           0 :         if (!(sc->ure_flags & URE_FLAG_8152)) {
     884           0 :                 if (sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 |
     885             :                     URE_CHIP_VER_5C20)) {
     886           0 :                                 ure_ocp_reg_write(sc, URE_OCP_ADC_CFG,
     887             :                                     URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L);
     888           0 :                 }
     889           0 :                 if (sc->ure_chip & URE_CHIP_VER_5C00) {
     890           0 :                         ure_ocp_reg_write(sc, URE_OCP_EEE_CFG,
     891           0 :                             ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) & 
     892             :                             ~URE_CTAP_SHORT_EN);
     893           0 :                 }
     894           0 :                 ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
     895           0 :                     ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) |
     896             :                     URE_EEE_CLKDIV_EN);
     897           0 :                 ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED,
     898           0 :                     ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) |
     899             :                     URE_EN_10M_BGOFF);
     900           0 :                 ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
     901           0 :                     ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) |
     902             :                     URE_EN_10M_PLLOFF);
     903           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE);
     904           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0b13);
     905           0 :                 ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
     906           0 :                     ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
     907             :                     URE_PFM_PWM_SWITCH);
     908             : 
     909             :                 /* Enable LPF corner auto tune. */
     910           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG);
     911           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0xf70f);
     912             : 
     913             :                 /* Adjust 10M amplitude. */
     914           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1);
     915           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x00af);
     916           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2);
     917           0 :                 ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0208);
     918           0 :         }
     919             : 
     920           0 :         ure_reset(sc);
     921             : 
     922           0 :         ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
     923             : 
     924           0 :         ure_write_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA,
     925           0 :             ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
     926             :             ~URE_NOW_IS_OOB);
     927             : 
     928           0 :         ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
     929           0 :             ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) &
     930             :             ~URE_MCU_BORW_EN);
     931           0 :         for (i = 0; i < URE_TIMEOUT; i++) {
     932           0 :                 if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
     933             :                     URE_LINK_LIST_READY)
     934             :                         break;
     935           0 :                 usbd_delay_ms(sc->ure_udev, 10);
     936             :         }
     937           0 :         if (i == URE_TIMEOUT)
     938           0 :                 printf("%s: timeout waiting for OOB control\n",
     939           0 :                     sc->ure_dev.dv_xname);
     940           0 :         ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA,
     941           0 :             ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) |
     942             :             URE_RE_INIT_LL);
     943           0 :         for (i = 0; i < URE_TIMEOUT; i++) {
     944           0 :                 if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) &
     945             :                     URE_LINK_LIST_READY)
     946             :                         break;
     947           0 :                 usbd_delay_ms(sc->ure_udev, 10);
     948             :         }
     949           0 :         if (i == URE_TIMEOUT)
     950           0 :                 printf("%s: timeout waiting for OOB control\n",
     951           0 :                     sc->ure_dev.dv_xname);
     952             : 
     953           0 :         ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA,
     954           0 :             ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA) &
     955             :             ~URE_CPCR_RX_VLAN);
     956           0 :         ure_write_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA,
     957           0 :             ure_read_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA) |
     958             :             URE_TCR0_AUTO_FIFO);
     959             : 
     960             :         /* Configure Rx FIFO threshold and coalescing. */
     961           0 :         ure_write_4(sc, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA,
     962             :             URE_RXFIFO_THR1_NORMAL);
     963           0 :         if (sc->ure_udev->speed == USB_SPEED_FULL) {
     964             :                 rx_fifo1 = URE_RXFIFO_THR2_FULL;
     965             :                 rx_fifo2 = URE_RXFIFO_THR3_FULL;
     966           0 :         } else {
     967             :                 rx_fifo1 = URE_RXFIFO_THR2_HIGH;
     968             :                 rx_fifo2 = URE_RXFIFO_THR3_HIGH;
     969             :         }
     970           0 :         ure_write_4(sc, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1);
     971           0 :         ure_write_4(sc, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2);
     972             : 
     973             :         /* Configure Tx FIFO threshold. */
     974           0 :         ure_write_4(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA,
     975             :             URE_TXFIFO_THR_NORMAL);
     976           0 : }
     977             : 
     978             : int
     979           0 : ure_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     980             : {
     981           0 :         struct ure_softc        *sc = ifp->if_softc;
     982           0 :         struct ifreq            *ifr = (struct ifreq *)data;
     983             :         int                     s, error = 0;
     984             : 
     985           0 :         s = splnet();
     986             : 
     987           0 :         switch (cmd) {
     988             :         case SIOCSIFADDR:
     989           0 :                 ifp->if_flags |= IFF_UP;
     990           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
     991           0 :                         ure_init(sc);
     992             :                 break;
     993             : 
     994             :         case SIOCSIFFLAGS:
     995           0 :                 if (ifp->if_flags & IFF_UP) {
     996           0 :                         if (ifp->if_flags & IFF_RUNNING)
     997           0 :                                 error = ENETRESET;
     998             :                         else
     999           0 :                                 ure_init(sc);
    1000             :                 } else {
    1001           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1002           0 :                                 ure_stop(sc);
    1003             :                 }
    1004             :                 break;
    1005             : 
    1006             :         case SIOCGIFMEDIA:
    1007             :         case SIOCSIFMEDIA:
    1008           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->ure_mii.mii_media, cmd);
    1009           0 :                 break;
    1010             : 
    1011             :         default:
    1012           0 :                 error = ether_ioctl(ifp, &sc->ure_ac, cmd, data);
    1013           0 :         }
    1014             : 
    1015           0 :         if (error == ENETRESET) {
    1016           0 :                 if (ifp->if_flags & IFF_RUNNING)
    1017           0 :                         ure_iff(sc);
    1018             :                 error = 0;
    1019           0 :         }
    1020             : 
    1021           0 :         splx(s);
    1022             : 
    1023           0 :         return (error);
    1024             : }
    1025             : 
    1026             : int
    1027           0 : ure_match(struct device *parent, void *match, void *aux)
    1028             : {
    1029           0 :         struct usb_attach_arg *uaa = aux;
    1030             : 
    1031             :         /*
    1032             :         if (uaa->configno != URE_CONFIG_IDX) 
    1033             :                 return UMATCH_NONE;
    1034             :         if (uaa->ifaceno != URE_IFACE_IDX)
    1035             :                 return UMATCH_NONE;
    1036             :         */
    1037           0 :         if (uaa->iface == NULL || uaa->configno != 1)
    1038           0 :                 return UMATCH_NONE;
    1039             :         
    1040           0 :         return (usb_lookup(ure_devs, uaa->vendor, uaa->product) != NULL ?
    1041             :             UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE);
    1042           0 : }
    1043             : 
    1044             : void
    1045           0 : ure_attach(struct device *parent, struct device *self, void *aux)
    1046             : {
    1047           0 :         struct ure_softc                *sc = (struct ure_softc *)self;
    1048           0 :         struct usb_attach_arg           *uaa = aux;
    1049             :         usb_interface_descriptor_t      *id;
    1050             :         usb_endpoint_descriptor_t       *ed;
    1051             :         struct mii_data                 *mii;
    1052           0 :         u_char                          eaddr[8]; /* 4byte padded */
    1053             :         struct ifnet                    *ifp;
    1054             :         int                             i, s;
    1055             :         uint16_t                        ver;
    1056             : 
    1057           0 :         sc->ure_udev = uaa->device;
    1058           0 :         sc->ure_iface = uaa->iface;
    1059             : 
    1060           0 :         if (uaa->product == USB_PRODUCT_REALTEK_RTL8152)
    1061           0 :                 sc->ure_flags |= URE_FLAG_8152;
    1062             : 
    1063           0 :         usb_init_task(&sc->ure_tick_task, ure_tick_task, sc,
    1064             :             USB_TASK_TYPE_GENERIC);
    1065           0 :         rw_init(&sc->ure_mii_lock, "uremii");
    1066           0 :         usb_init_task(&sc->ure_stop_task, (void (*)(void *))ure_stop, sc,
    1067             :             USB_TASK_TYPE_GENERIC);
    1068             : 
    1069           0 :         id = usbd_get_interface_descriptor(sc->ure_iface);
    1070             : 
    1071           0 :         sc->ure_bufsz = 16 * 1024;
    1072             : 
    1073           0 :         for (i = 0; i < id->bNumEndpoints; i++) {
    1074           0 :                 ed = usbd_interface2endpoint_descriptor(sc->ure_iface, i);
    1075           0 :                 if (!ed) {
    1076           0 :                         printf("%s: couldn't get ep %d\n",
    1077           0 :                             sc->ure_dev.dv_xname, i);
    1078           0 :                         return;
    1079             :                 }
    1080           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    1081           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    1082           0 :                         sc->ure_ed[URE_ENDPT_RX] = ed->bEndpointAddress;
    1083           0 :                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    1084           0 :                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    1085           0 :                         sc->ure_ed[URE_ENDPT_TX] = ed->bEndpointAddress;
    1086           0 :                 }
    1087             :         }
    1088             : 
    1089           0 :         s = splnet();
    1090             : 
    1091           0 :         sc->ure_phyno = 0;
    1092           0 :         printf("%s: ", sc->ure_dev.dv_xname);
    1093             : 
    1094           0 :         ver = ure_read_2(sc, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK;
    1095           0 :         switch (ver) {
    1096             :         case 0x4c00:
    1097           0 :                 sc->ure_chip |= URE_CHIP_VER_4C00;
    1098           0 :                 printf("ver 4c00");
    1099           0 :                 break;
    1100             :         case 0x4c10:
    1101           0 :                 sc->ure_chip |= URE_CHIP_VER_4C10;
    1102           0 :                 printf("ver 4c10");
    1103           0 :                 break;
    1104             :         case 0x5c00:
    1105           0 :                 sc->ure_chip |= URE_CHIP_VER_5C00;
    1106           0 :                 printf("ver 5c00");
    1107           0 :                 break;
    1108             :         case 0x5c10:
    1109           0 :                 sc->ure_chip |= URE_CHIP_VER_5C10;
    1110           0 :                 printf("ver 5c10");
    1111           0 :                 break;
    1112             :         case 0x5c20:
    1113           0 :                 sc->ure_chip |= URE_CHIP_VER_5C20;
    1114           0 :                 printf("ver 5c20");
    1115           0 :                 break;
    1116             :         case 0x5c30:
    1117           0 :                 sc->ure_chip |= URE_CHIP_VER_5C30;
    1118           0 :                 printf("ver 5c30");
    1119           0 :                 break;
    1120             :         default:
    1121           0 :                 printf(", unknown ver %02x", ver);
    1122             :                 /* fake addr?  or just fail? */
    1123           0 :                 break;
    1124             :         }
    1125             : 
    1126           0 :         if (sc->ure_flags & URE_FLAG_8152)
    1127           0 :                 ure_rtl8152_init(sc);
    1128             :         else
    1129           0 :                 ure_rtl8153_init(sc);
    1130             : 
    1131           0 :         if (sc->ure_chip & URE_CHIP_VER_4C00)
    1132           0 :                 ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr,
    1133             :                     sizeof(eaddr));
    1134             :         else
    1135           0 :                 ure_read_mem(sc, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
    1136             :                     sizeof(eaddr));
    1137             : 
    1138           0 :         printf(", address %s\n", ether_sprintf(eaddr));
    1139             : 
    1140           0 :         bcopy(eaddr, (char *)&sc->ure_ac.ac_enaddr, ETHER_ADDR_LEN);
    1141             : 
    1142           0 :         ifp = &sc->ure_ac.ac_if;
    1143           0 :         ifp->if_softc = sc;
    1144           0 :         strlcpy(ifp->if_xname, sc->ure_dev.dv_xname, IFNAMSIZ);
    1145           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    1146           0 :         ifp->if_ioctl = ure_ioctl;
    1147           0 :         ifp->if_start = ure_start;
    1148           0 :         ifp->if_capabilities = 0;
    1149             : 
    1150           0 :         mii = &sc->ure_mii;
    1151           0 :         mii->mii_ifp = ifp;
    1152           0 :         mii->mii_readreg = ure_miibus_readreg;
    1153           0 :         mii->mii_writereg = ure_miibus_writereg;
    1154           0 :         mii->mii_statchg = ure_miibus_statchg;
    1155           0 :         mii->mii_flags = MIIF_AUTOTSLEEP;
    1156             : 
    1157           0 :         ifmedia_init(&mii->mii_media, 0, ure_ifmedia_upd, ure_ifmedia_sts);
    1158           0 :         mii_attach(self, mii, 0xffffffff, sc->ure_phyno, MII_OFFSET_ANY, 0);
    1159             : 
    1160           0 :         if (LIST_FIRST(&mii->mii_phys) == NULL) {
    1161           0 :                 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
    1162           0 :                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
    1163           0 :         } else
    1164           0 :                 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
    1165             : 
    1166           0 :         if_attach(ifp);
    1167           0 :         ether_ifattach(ifp);
    1168             : 
    1169           0 :         timeout_set(&sc->ure_stat_ch, ure_tick, sc);
    1170             : 
    1171           0 :         splx(s);
    1172           0 : }
    1173             : 
    1174             : int
    1175           0 : ure_detach(struct device *self, int flags)
    1176             : {
    1177           0 :         struct ure_softc        *sc = (struct ure_softc *)self;
    1178           0 :         struct ifnet            *ifp = &sc->ure_ac.ac_if;
    1179             :         int                     s;
    1180             : 
    1181           0 :         if (timeout_initialized(&sc->ure_stat_ch))
    1182           0 :                 timeout_del(&sc->ure_stat_ch);
    1183             : 
    1184           0 :         if (sc->ure_ep[URE_ENDPT_TX] != NULL)
    1185           0 :                 usbd_abort_pipe(sc->ure_ep[URE_ENDPT_TX]);
    1186           0 :         if (sc->ure_ep[URE_ENDPT_RX] != NULL)
    1187           0 :                 usbd_abort_pipe(sc->ure_ep[URE_ENDPT_RX]);
    1188             : 
    1189           0 :         usb_rem_task(sc->ure_udev, &sc->ure_tick_task);
    1190           0 :         usb_rem_task(sc->ure_udev, &sc->ure_stop_task);
    1191             : 
    1192           0 :         s = splusb();
    1193             : 
    1194           0 :         if (--sc->ure_refcnt >= 0) {
    1195           0 :                 usb_detach_wait(&sc->ure_dev);
    1196           0 :         }
    1197             : 
    1198           0 :         if (ifp->if_flags & IFF_RUNNING)
    1199           0 :                 ure_stop(sc);
    1200             : 
    1201           0 :         mii_detach(&sc->ure_mii, MII_PHY_ANY, MII_OFFSET_ANY);
    1202           0 :         ifmedia_delete_instance(&sc->ure_mii.mii_media, IFM_INST_ANY);
    1203           0 :         if (ifp->if_softc != NULL) {
    1204           0 :                 ether_ifdetach(ifp);
    1205           0 :                 if_detach(ifp);
    1206           0 :         }
    1207             : 
    1208           0 :         splx(s);
    1209             : 
    1210           0 :         return 0;
    1211             : }
    1212             : 
    1213             : void
    1214           0 : ure_tick_task(void *xsc)
    1215             : {
    1216             :         int                     s;
    1217           0 :         struct ure_softc        *sc = xsc;
    1218             :         struct mii_data         *mii;
    1219             : 
    1220           0 :         if (sc == NULL)
    1221           0 :                 return;
    1222             : 
    1223           0 :         if (usbd_is_dying(sc->ure_udev))
    1224           0 :                 return;
    1225           0 :         mii = &sc->ure_mii;
    1226             : 
    1227           0 :         s = splnet();
    1228           0 :         mii_tick(mii);
    1229           0 :         if ((sc->ure_flags & URE_FLAG_LINK) == 0)
    1230           0 :                 ure_miibus_statchg(&sc->ure_dev);
    1231           0 :         timeout_add_sec(&sc->ure_stat_ch, 1);
    1232           0 :         splx(s);
    1233           0 : }
    1234             : 
    1235             : void
    1236           0 : ure_lock_mii(struct ure_softc *sc)
    1237             : {
    1238           0 :         sc->ure_refcnt++;
    1239           0 :         rw_enter_write(&sc->ure_mii_lock);
    1240           0 : }
    1241             : 
    1242             : void
    1243           0 : ure_unlock_mii(struct ure_softc *sc)
    1244             : {
    1245           0 :         rw_exit_write(&sc->ure_mii_lock);
    1246           0 :         if (--sc->ure_refcnt < 0)
    1247           0 :                 usb_detach_wakeup(&sc->ure_dev);
    1248           0 : }
    1249             : 
    1250             : void
    1251           0 : ure_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
    1252             : {
    1253           0 :         struct ure_chain        *c = (struct ure_chain *)priv;
    1254           0 :         struct ure_softc        *sc = c->uc_sc;
    1255           0 :         struct ifnet            *ifp = &sc->ure_ac.ac_if;
    1256           0 :         u_char                  *buf = c->uc_buf;
    1257           0 :         uint32_t                total_len;
    1258             :         uint16_t                pktlen = 0;
    1259           0 :         struct mbuf_list        ml = MBUF_LIST_INITIALIZER();
    1260             :         struct mbuf             *m;
    1261             :         int                     s;
    1262           0 :         struct ure_rxpkt        rxhdr;
    1263             :         
    1264           0 :         if (usbd_is_dying(sc->ure_udev))
    1265           0 :                 return;
    1266             : 
    1267           0 :         if (!(ifp->if_flags & IFF_RUNNING))
    1268           0 :                 return;
    1269             : 
    1270           0 :         if (status != USBD_NORMAL_COMPLETION) {
    1271           0 :                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    1272           0 :                         return;
    1273           0 :                 if (usbd_ratecheck(&sc->ure_rx_notice)) {
    1274           0 :                         printf("%s: usb errors on rx: %s\n",
    1275           0 :                                 sc->ure_dev.dv_xname, usbd_errstr(status));
    1276           0 :                 }
    1277           0 :                 if (status == USBD_STALLED)
    1278           0 :                         usbd_clear_endpoint_stall_async(sc->ure_ep[URE_ENDPT_RX]);
    1279             :                 goto done;
    1280             :         }
    1281             : 
    1282           0 :         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
    1283             :         DPRINTFN(3, ("received %d bytes\n", total_len));
    1284             : 
    1285           0 :         do {
    1286           0 :                 if (total_len < sizeof(rxhdr)) {
    1287             :                         DPRINTF(("too few bytes left for a packet header\n"));
    1288           0 :                         ifp->if_ierrors++;
    1289           0 :                         goto done;
    1290             :                 }
    1291             : 
    1292           0 :                 buf += roundup(pktlen, 8);
    1293             : 
    1294           0 :                 memcpy(&rxhdr, buf, sizeof(rxhdr));
    1295           0 :                 total_len -= sizeof(rxhdr);
    1296             : 
    1297           0 :                 pktlen = lemtoh32(&rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK;
    1298             :                 DPRINTFN(4, ("next packet is %d bytes\n", pktlen));
    1299           0 :                 if (pktlen > total_len) {
    1300             :                         DPRINTF(("not enough bytes left for next packet\n"));
    1301           0 :                         ifp->if_ierrors++;
    1302           0 :                         goto done;
    1303             :                 }
    1304             : 
    1305           0 :                 total_len -= roundup(pktlen, 8);
    1306           0 :                 buf += sizeof(rxhdr);
    1307             : 
    1308           0 :                 m = m_devget(buf, pktlen, ETHER_ALIGN);
    1309           0 :                 if (m == NULL) {
    1310             :                         DPRINTF(("unable to allocate mbuf for next packet\n"));
    1311           0 :                         ifp->if_ierrors++;
    1312           0 :                         goto done;
    1313             :                 }
    1314             : 
    1315           0 :                 ml_enqueue(&ml, m);
    1316           0 :         } while (total_len > 0);
    1317             : 
    1318             : done:
    1319           0 :         s = splnet();
    1320           0 :         if_input(ifp, &ml);
    1321           0 :         splx(s);
    1322           0 :         memset(c->uc_buf, 0, sc->ure_bufsz);
    1323             : 
    1324           0 :         usbd_setup_xfer(xfer, sc->ure_ep[URE_ENDPT_RX], c, c->uc_buf,
    1325           0 :             sc->ure_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
    1326             :             USBD_NO_TIMEOUT, ure_rxeof);
    1327           0 :         usbd_transfer(xfer);
    1328           0 : }
    1329             : 
    1330             : 
    1331             : void
    1332           0 : ure_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
    1333             : {
    1334             :         struct ure_softc        *sc;
    1335             :         struct ure_chain        *c;
    1336             :         struct ifnet            *ifp;
    1337             :         int                     s;
    1338             : 
    1339           0 :         c = priv;
    1340           0 :         sc = c->uc_sc;
    1341           0 :         ifp = &sc->ure_ac.ac_if;
    1342             : 
    1343           0 :         if (usbd_is_dying(sc->ure_udev))
    1344           0 :                 return;
    1345             : 
    1346             :         DPRINTFN(2, ("tx completion\n"));
    1347             : 
    1348           0 :         s = splnet();
    1349             : 
    1350           0 :         if (status != USBD_NORMAL_COMPLETION) {
    1351           0 :                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
    1352           0 :                         splx(s);
    1353           0 :                         return;
    1354             :                 }
    1355           0 :                 ifp->if_oerrors++;
    1356           0 :                 printf("%s: usb error on tx: %s\n", sc->ure_dev.dv_xname,
    1357           0 :                     usbd_errstr(status));
    1358           0 :                 if (status == USBD_STALLED)
    1359           0 :                         usbd_clear_endpoint_stall_async(sc->ure_ep[URE_ENDPT_TX]);
    1360           0 :                 splx(s);
    1361           0 :                 return;
    1362             :         }
    1363             : 
    1364           0 :         ifp->if_timer = 0;
    1365           0 :         ifq_clr_oactive(&ifp->if_snd);
    1366             : 
    1367           0 :         m_freem(c->uc_mbuf);
    1368           0 :         c->uc_mbuf = NULL;
    1369             : 
    1370           0 :         if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
    1371           0 :                 ure_start(ifp);
    1372             : 
    1373           0 :         splx(s);
    1374             :         
    1375           0 : }
    1376             : 
    1377             : int
    1378           0 : ure_tx_list_init(struct ure_softc *sc)
    1379             : {
    1380             :         struct ure_cdata *cd;
    1381             :         struct ure_chain *c;
    1382             :         int i;
    1383             : 
    1384           0 :         cd = &sc->ure_cdata;
    1385           0 :         for (i = 0; i < URE_TX_LIST_CNT; i++) {
    1386           0 :                 c = &cd->tx_chain[i];
    1387           0 :                 c->uc_sc = sc;
    1388           0 :                 c->uc_idx = i;
    1389           0 :                 c->uc_mbuf = NULL;
    1390           0 :                 if (c->uc_xfer == NULL) {
    1391           0 :                         c->uc_xfer = usbd_alloc_xfer(sc->ure_udev);
    1392           0 :                         if (c->uc_xfer == NULL)
    1393           0 :                                 return ENOBUFS;
    1394           0 :                         c->uc_buf = usbd_alloc_buffer(c->uc_xfer,
    1395           0 :                             sc->ure_bufsz);
    1396           0 :                         if (c->uc_buf == NULL) {
    1397           0 :                                 usbd_free_xfer(c->uc_xfer);
    1398           0 :                                 return ENOBUFS;
    1399             :                         }
    1400             :                 }
    1401             :         }
    1402             : 
    1403           0 :         return 0;
    1404           0 : }
    1405             : 
    1406             : int
    1407           0 : ure_rx_list_init(struct ure_softc *sc)
    1408             : {
    1409             :         struct ure_cdata *cd;
    1410             :         struct ure_chain *c;
    1411             :         int i;
    1412             : 
    1413           0 :         cd = &sc->ure_cdata;
    1414           0 :         for (i = 0; i < URE_RX_LIST_CNT; i++) {
    1415           0 :                 c = &cd->rx_chain[i];
    1416           0 :                 c->uc_sc = sc;
    1417           0 :                 c->uc_idx = i;
    1418           0 :                 c->uc_mbuf = NULL;
    1419           0 :                 if (c->uc_xfer == NULL) {
    1420           0 :                         c->uc_xfer = usbd_alloc_xfer(sc->ure_udev);
    1421           0 :                         if (c->uc_xfer == NULL)
    1422           0 :                                 return ENOBUFS;
    1423           0 :                         c->uc_buf = usbd_alloc_buffer(c->uc_xfer,
    1424           0 :                             sc->ure_bufsz);
    1425           0 :                         if (c->uc_buf == NULL) {
    1426           0 :                                 usbd_free_xfer(c->uc_xfer);
    1427           0 :                                 return ENOBUFS;
    1428             :                         }
    1429             :                 }
    1430             :         }
    1431             : 
    1432           0 :         return 0;
    1433           0 : }
    1434             : 
    1435             : int
    1436           0 : ure_encap(struct ure_softc *sc, struct mbuf *m, int idx)
    1437             : {
    1438             :         struct ure_chain        *c;
    1439             :         usbd_status             err;
    1440             :         struct ure_txpkt        txhdr;
    1441             :         uint32_t                frm_len = 0;
    1442             :         u_char                  *buf;
    1443             : 
    1444           0 :         c = &sc->ure_cdata.tx_chain[idx];
    1445           0 :         buf = c->uc_buf;
    1446             : 
    1447             :         /* header */
    1448           0 :         htolem32(&txhdr.ure_pktlen, m->m_pkthdr.len | URE_TXPKT_TX_FS |
    1449             :             URE_TXPKT_TX_LS);
    1450             :         txhdr.ure_rsvd0 = 0;
    1451           0 :         memcpy(buf, &txhdr, sizeof(txhdr));
    1452           0 :         buf += sizeof(txhdr);
    1453             :         frm_len = sizeof(txhdr);
    1454             : 
    1455             :         /* packet */
    1456           0 :         m_copydata(m, 0, m->m_pkthdr.len, buf);
    1457           0 :         frm_len += m->m_pkthdr.len;
    1458             : 
    1459           0 :         c->uc_mbuf = m;
    1460             : 
    1461             :         DPRINTFN(2, ("tx %d bytes\n", frm_len));
    1462           0 :         usbd_setup_xfer(c->uc_xfer, sc->ure_ep[URE_ENDPT_TX], c, c->uc_buf,
    1463             :             frm_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, ure_txeof);
    1464             : 
    1465           0 :         err = usbd_transfer(c->uc_xfer);
    1466           0 :         if (err != USBD_IN_PROGRESS) {
    1467           0 :                 ure_stop(sc);
    1468           0 :                 return EIO;
    1469             :         }
    1470             : 
    1471           0 :         sc->ure_cdata.tx_cnt++;
    1472           0 :         return 0;
    1473           0 : }

Generated by: LCOV version 1.13