LCOV - code coverage report
Current view: top level - dev/pci - if_vge.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 756 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_vge.c,v 1.71 2017/01/22 10:17:38 dlg Exp $ */
       2             : /*      $FreeBSD: if_vge.c,v 1.3 2004/09/11 22:13:25 wpaul Exp $        */
       3             : /*
       4             :  * Copyright (c) 2004
       5             :  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  * 3. All advertising materials mentioning features or use of this software
      16             :  *    must display the following acknowledgement:
      17             :  *      This product includes software developed by Bill Paul.
      18             :  * 4. Neither the name of the author nor the names of any co-contributors
      19             :  *    may be used to endorse or promote products derived from this software
      20             :  *    without specific prior written permission.
      21             :  *
      22             :  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
      23             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      24             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      25             :  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
      26             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      27             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      28             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      29             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      30             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      31             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      32             :  * THE POSSIBILITY OF SUCH DAMAGE.
      33             :  */
      34             : 
      35             : /*
      36             :  * VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver.
      37             :  *
      38             :  * Written by Bill Paul <wpaul@windriver.com>
      39             :  * Senior Networking Software Engineer
      40             :  * Wind River Systems
      41             :  *
      42             :  * Ported to OpenBSD by Peter Valchev <pvalchev@openbsd.org>
      43             :  */
      44             : 
      45             : /*
      46             :  * The VIA Networking VT6122 is a 32bit, 33/66MHz PCI device that
      47             :  * combines a tri-speed ethernet MAC and PHY, with the following
      48             :  * features:
      49             :  *
      50             :  *      o Jumbo frame support up to 16K
      51             :  *      o Transmit and receive flow control
      52             :  *      o IPv4 checksum offload
      53             :  *      o VLAN tag insertion and stripping
      54             :  *      o TCP large send
      55             :  *      o 64-bit multicast hash table filter
      56             :  *      o 64 entry CAM filter
      57             :  *      o 16K RX FIFO and 48K TX FIFO memory
      58             :  *      o Interrupt moderation
      59             :  *
      60             :  * The VT6122 supports up to four transmit DMA queues. The descriptors
      61             :  * in the transmit ring can address up to 7 data fragments; frames which
      62             :  * span more than 7 data buffers must be coalesced, but in general the
      63             :  * BSD TCP/IP stack rarely generates frames more than 2 or 3 fragments
      64             :  * long. The receive descriptors address only a single buffer.
      65             :  *
      66             :  * There are two peculiar design issues with the VT6122. One is that
      67             :  * receive data buffers must be aligned on a 32-bit boundary. This is
      68             :  * not a problem where the VT6122 is used as a LOM device in x86-based
      69             :  * systems, but on architectures that generate unaligned access traps, we
      70             :  * have to do some copying.
      71             :  *
      72             :  * The other issue has to do with the way 64-bit addresses are handled.
      73             :  * The DMA descriptors only allow you to specify 48 bits of addressing
      74             :  * information. The remaining 16 bits are specified using one of the
      75             :  * I/O registers. If you only have a 32-bit system, then this isn't
      76             :  * an issue, but if you have a 64-bit system and more than 4GB of
      77             :  * memory, you must have to make sure your network data buffers reside
      78             :  * in the same 48-bit 'segment.'
      79             :  *
      80             :  * Special thanks to Ryan Fu at VIA Networking for providing documentation
      81             :  * and sample NICs for testing.
      82             :  */
      83             : 
      84             : #include "bpfilter.h"
      85             : #include "vlan.h"
      86             : 
      87             : #include <sys/param.h>
      88             : #include <sys/endian.h>
      89             : #include <sys/systm.h>
      90             : #include <sys/sockio.h>
      91             : #include <sys/mbuf.h>
      92             : #include <sys/malloc.h>
      93             : #include <sys/kernel.h>
      94             : #include <sys/device.h>
      95             : #include <sys/timeout.h>
      96             : #include <sys/socket.h>
      97             : 
      98             : #include <net/if.h>
      99             : #include <net/if_media.h>
     100             : 
     101             : #include <netinet/in.h>
     102             : #include <netinet/if_ether.h>
     103             : 
     104             : #if NBPFILTER > 0
     105             : #include <net/bpf.h>
     106             : #endif
     107             : 
     108             : #include <dev/mii/miivar.h>
     109             : 
     110             : #include <dev/pci/pcireg.h>
     111             : #include <dev/pci/pcivar.h>
     112             : #include <dev/pci/pcidevs.h>
     113             : 
     114             : #include <dev/pci/if_vgereg.h>
     115             : #include <dev/pci/if_vgevar.h>
     116             : 
     117             : int vge_probe           (struct device *, void *, void *);
     118             : void vge_attach         (struct device *, struct device *, void *);
     119             : int vge_detach          (struct device *, int);
     120             : 
     121             : int vge_encap           (struct vge_softc *, struct mbuf *, int);
     122             : 
     123             : int vge_allocmem                (struct vge_softc *);
     124             : void vge_freemem        (struct vge_softc *);
     125             : int vge_newbuf          (struct vge_softc *, int, struct mbuf *);
     126             : int vge_rx_list_init    (struct vge_softc *);
     127             : int vge_tx_list_init    (struct vge_softc *);
     128             : void vge_rxeof          (struct vge_softc *);
     129             : void vge_txeof          (struct vge_softc *);
     130             : int vge_intr            (void *);
     131             : void vge_tick           (void *);
     132             : void vge_start          (struct ifnet *);
     133             : int vge_ioctl           (struct ifnet *, u_long, caddr_t);
     134             : int vge_init            (struct ifnet *);
     135             : void vge_stop           (struct vge_softc *);
     136             : void vge_watchdog       (struct ifnet *);
     137             : int vge_ifmedia_upd     (struct ifnet *);
     138             : void vge_ifmedia_sts    (struct ifnet *, struct ifmediareq *);
     139             : 
     140             : #ifdef VGE_EEPROM
     141             : void vge_eeprom_getword (struct vge_softc *, int, u_int16_t *);
     142             : #endif
     143             : void vge_read_eeprom    (struct vge_softc *, caddr_t, int, int, int);
     144             : 
     145             : void vge_miipoll_start  (struct vge_softc *);
     146             : void vge_miipoll_stop   (struct vge_softc *);
     147             : int vge_miibus_readreg  (struct device *, int, int);
     148             : void vge_miibus_writereg (struct device *, int, int, int);
     149             : void vge_miibus_statchg (struct device *);
     150             : 
     151             : void vge_cam_clear      (struct vge_softc *);
     152             : int vge_cam_set         (struct vge_softc *, uint8_t *);
     153             : void vge_iff            (struct vge_softc *);
     154             : void vge_reset          (struct vge_softc *);
     155             : 
     156             : struct cfattach vge_ca = {
     157             :         sizeof(struct vge_softc), vge_probe, vge_attach, vge_detach
     158             : };
     159             : 
     160             : struct cfdriver vge_cd = {
     161             :         NULL, "vge", DV_IFNET
     162             : };
     163             : 
     164             : #define VGE_PCI_LOIO             0x10
     165             : #define VGE_PCI_LOMEM            0x14
     166             : 
     167             : int vge_debug = 0;
     168             : #define DPRINTF(x)      if (vge_debug) printf x
     169             : #define DPRINTFN(n, x)  if (vge_debug >= (n)) printf x
     170             : 
     171             : const struct pci_matchid vge_devices[] = {
     172             :         { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT612x },
     173             : };
     174             : 
     175             : #ifdef VGE_EEPROM
     176             : /*
     177             :  * Read a word of data stored in the EEPROM at address 'addr.'
     178             :  */
     179             : void
     180             : vge_eeprom_getword(struct vge_softc *sc, int addr, u_int16_t *dest)
     181             : {
     182             :         int                     i;
     183             :         u_int16_t               word = 0;
     184             : 
     185             :         /*
     186             :          * Enter EEPROM embedded programming mode. In order to
     187             :          * access the EEPROM at all, we first have to set the
     188             :          * EELOAD bit in the CHIPCFG2 register.
     189             :          */
     190             :         CSR_SETBIT_1(sc, VGE_CHIPCFG2, VGE_CHIPCFG2_EELOAD);
     191             :         CSR_SETBIT_1(sc, VGE_EECSR, VGE_EECSR_EMBP/*|VGE_EECSR_ECS*/);
     192             : 
     193             :         /* Select the address of the word we want to read */
     194             :         CSR_WRITE_1(sc, VGE_EEADDR, addr);
     195             : 
     196             :         /* Issue read command */
     197             :         CSR_SETBIT_1(sc, VGE_EECMD, VGE_EECMD_ERD);
     198             : 
     199             :         /* Wait for the done bit to be set. */
     200             :         for (i = 0; i < VGE_TIMEOUT; i++) {
     201             :                 if (CSR_READ_1(sc, VGE_EECMD) & VGE_EECMD_EDONE)
     202             :                         break;
     203             :         }
     204             : 
     205             :         if (i == VGE_TIMEOUT) {
     206             :                 printf("%s: EEPROM read timed out\n", sc->vge_dev.dv_xname);
     207             :                 *dest = 0;
     208             :                 return;
     209             :         }
     210             : 
     211             :         /* Read the result */
     212             :         word = CSR_READ_2(sc, VGE_EERDDAT);
     213             : 
     214             :         /* Turn off EEPROM access mode. */
     215             :         CSR_CLRBIT_1(sc, VGE_EECSR, VGE_EECSR_EMBP/*|VGE_EECSR_ECS*/);
     216             :         CSR_CLRBIT_1(sc, VGE_CHIPCFG2, VGE_CHIPCFG2_EELOAD);
     217             : 
     218             :         *dest = word;
     219             : }
     220             : #endif
     221             : 
     222             : /*
     223             :  * Read a sequence of words from the EEPROM.
     224             :  */
     225             : void
     226           0 : vge_read_eeprom(struct vge_softc *sc, caddr_t dest, int off, int cnt,
     227             :     int swap)
     228             : {
     229             :         int                     i;
     230             : #ifdef VGE_EEPROM
     231             :         u_int16_t               word = 0, *ptr;
     232             : 
     233             :         for (i = 0; i < cnt; i++) {
     234             :                 vge_eeprom_getword(sc, off + i, &word);
     235             :                 ptr = (u_int16_t *)(dest + (i * 2));
     236             :                 if (swap)
     237             :                         *ptr = ntohs(word);
     238             :                 else
     239             :                         *ptr = word;
     240             :         }
     241             : #else
     242           0 :         for (i = 0; i < ETHER_ADDR_LEN; i++)
     243           0 :                 dest[i] = CSR_READ_1(sc, VGE_PAR0 + i);
     244             : #endif
     245           0 : }
     246             : 
     247             : void
     248           0 : vge_miipoll_stop(struct vge_softc *sc)
     249             : {
     250             :         int                     i;
     251             : 
     252           0 :         CSR_WRITE_1(sc, VGE_MIICMD, 0);
     253             : 
     254           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     255           0 :                 DELAY(1);
     256           0 :                 if (CSR_READ_1(sc, VGE_MIISTS) & VGE_MIISTS_IIDL)
     257             :                         break;
     258             :         }
     259             : 
     260           0 :         if (i == VGE_TIMEOUT)
     261           0 :                 printf("%s: failed to idle MII autopoll\n", sc->vge_dev.dv_xname);
     262           0 : }
     263             : 
     264             : void
     265           0 : vge_miipoll_start(struct vge_softc *sc)
     266             : {
     267             :         int                     i;
     268             : 
     269             :         /* First, make sure we're idle. */
     270             : 
     271           0 :         CSR_WRITE_1(sc, VGE_MIICMD, 0);
     272           0 :         CSR_WRITE_1(sc, VGE_MIIADDR, VGE_MIIADDR_SWMPL);
     273             : 
     274           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     275           0 :                 DELAY(1);
     276           0 :                 if (CSR_READ_1(sc, VGE_MIISTS) & VGE_MIISTS_IIDL)
     277             :                         break;
     278             :         }
     279             : 
     280           0 :         if (i == VGE_TIMEOUT) {
     281           0 :                 printf("%s: failed to idle MII autopoll\n", sc->vge_dev.dv_xname);
     282           0 :                 return;
     283             :         }
     284             : 
     285             :         /* Now enable auto poll mode. */
     286             : 
     287           0 :         CSR_WRITE_1(sc, VGE_MIICMD, VGE_MIICMD_MAUTO);
     288             : 
     289             :         /* And make sure it started. */
     290             : 
     291           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     292           0 :                 DELAY(1);
     293           0 :                 if ((CSR_READ_1(sc, VGE_MIISTS) & VGE_MIISTS_IIDL) == 0)
     294             :                         break;
     295             :         }
     296             : 
     297           0 :         if (i == VGE_TIMEOUT)
     298           0 :                 printf("%s: failed to start MII autopoll\n", sc->vge_dev.dv_xname);
     299           0 : }
     300             : 
     301             : int
     302           0 : vge_miibus_readreg(struct device *dev, int phy, int reg)
     303             : {
     304           0 :         struct vge_softc        *sc = (struct vge_softc *)dev;
     305             :         int                     i, s;
     306             :         u_int16_t               rval = 0;
     307             : 
     308           0 :         if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
     309           0 :                 return(0);
     310             : 
     311           0 :         s = splnet();
     312             : 
     313           0 :         vge_miipoll_stop(sc);
     314             : 
     315             :         /* Specify the register we want to read. */
     316           0 :         CSR_WRITE_1(sc, VGE_MIIADDR, reg);
     317             : 
     318             :         /* Issue read command. */
     319           0 :         CSR_SETBIT_1(sc, VGE_MIICMD, VGE_MIICMD_RCMD);
     320             : 
     321             :         /* Wait for the read command bit to self-clear. */
     322           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     323           0 :                 DELAY(1);
     324           0 :                 if ((CSR_READ_1(sc, VGE_MIICMD) & VGE_MIICMD_RCMD) == 0)
     325             :                         break;
     326             :         }
     327             : 
     328           0 :         if (i == VGE_TIMEOUT)
     329           0 :                 printf("%s: MII read timed out\n", sc->vge_dev.dv_xname);
     330             :         else
     331           0 :                 rval = CSR_READ_2(sc, VGE_MIIDATA);
     332             : 
     333           0 :         vge_miipoll_start(sc);
     334           0 :         splx(s);
     335             : 
     336           0 :         return (rval);
     337           0 : }
     338             : 
     339             : void
     340           0 : vge_miibus_writereg(struct device *dev, int phy, int reg, int data)
     341             : {
     342           0 :         struct vge_softc        *sc = (struct vge_softc *)dev;
     343             :         int                     i, s;
     344             : 
     345           0 :         if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
     346           0 :                 return;
     347             : 
     348           0 :         s = splnet();
     349           0 :         vge_miipoll_stop(sc);
     350             : 
     351             :         /* Specify the register we want to write. */
     352           0 :         CSR_WRITE_1(sc, VGE_MIIADDR, reg);
     353             : 
     354             :         /* Specify the data we want to write. */
     355           0 :         CSR_WRITE_2(sc, VGE_MIIDATA, data);
     356             : 
     357             :         /* Issue write command. */
     358           0 :         CSR_SETBIT_1(sc, VGE_MIICMD, VGE_MIICMD_WCMD);
     359             : 
     360             :         /* Wait for the write command bit to self-clear. */
     361           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     362           0 :                 DELAY(1);
     363           0 :                 if ((CSR_READ_1(sc, VGE_MIICMD) & VGE_MIICMD_WCMD) == 0)
     364             :                         break;
     365             :         }
     366             : 
     367           0 :         if (i == VGE_TIMEOUT) {
     368           0 :                 printf("%s: MII write timed out\n", sc->vge_dev.dv_xname);
     369           0 :         }
     370             : 
     371           0 :         vge_miipoll_start(sc);
     372           0 :         splx(s);
     373           0 : }
     374             : 
     375             : void
     376           0 : vge_cam_clear(struct vge_softc *sc)
     377             : {
     378             :         int                     i;
     379             : 
     380             :         /*
     381             :          * Turn off all the mask bits. This tells the chip
     382             :          * that none of the entries in the CAM filter are valid.
     383             :          * desired entries will be enabled as we fill the filter in.
     384             :          */
     385             : 
     386           0 :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
     387           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_CAMMASK);
     388           0 :         CSR_WRITE_1(sc, VGE_CAMADDR, VGE_CAMADDR_ENABLE);
     389           0 :         for (i = 0; i < 8; i++)
     390           0 :                 CSR_WRITE_1(sc, VGE_CAM0 + i, 0);
     391             : 
     392             :         /* Clear the VLAN filter too. */
     393             : 
     394           0 :         CSR_WRITE_1(sc, VGE_CAMADDR, VGE_CAMADDR_ENABLE|VGE_CAMADDR_AVSEL|0);
     395           0 :         for (i = 0; i < 8; i++)
     396           0 :                 CSR_WRITE_1(sc, VGE_CAM0 + i, 0);
     397             : 
     398           0 :         CSR_WRITE_1(sc, VGE_CAMADDR, 0);
     399           0 :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
     400           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_MAR);
     401             : 
     402           0 :         sc->vge_camidx = 0;
     403           0 : }
     404             : 
     405             : int
     406           0 : vge_cam_set(struct vge_softc *sc, uint8_t *addr)
     407             : {
     408             :         int                     i, error = 0;
     409             : 
     410           0 :         if (sc->vge_camidx == VGE_CAM_MAXADDRS)
     411           0 :                 return(ENOSPC);
     412             : 
     413             :         /* Select the CAM data page. */
     414           0 :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
     415           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_CAMDATA);
     416             : 
     417             :         /* Set the filter entry we want to update and enable writing. */
     418           0 :         CSR_WRITE_1(sc, VGE_CAMADDR, VGE_CAMADDR_ENABLE|sc->vge_camidx);
     419             : 
     420             :         /* Write the address to the CAM registers */
     421           0 :         for (i = 0; i < ETHER_ADDR_LEN; i++)
     422           0 :                 CSR_WRITE_1(sc, VGE_CAM0 + i, addr[i]);
     423             : 
     424             :         /* Issue a write command. */
     425           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_WRITE);
     426             : 
     427             :         /* Wake for it to clear. */
     428           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     429           0 :                 DELAY(1);
     430           0 :                 if ((CSR_READ_1(sc, VGE_CAMCTL) & VGE_CAMCTL_WRITE) == 0)
     431             :                         break;
     432             :         }
     433             : 
     434           0 :         if (i == VGE_TIMEOUT) {
     435           0 :                 printf("%s: setting CAM filter failed\n", sc->vge_dev.dv_xname);
     436             :                 error = EIO;
     437           0 :                 goto fail;
     438             :         }
     439             : 
     440             :         /* Select the CAM mask page. */
     441           0 :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
     442           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_CAMMASK);
     443             : 
     444             :         /* Set the mask bit that enables this filter. */
     445           0 :         CSR_SETBIT_1(sc, VGE_CAM0 + (sc->vge_camidx/8),
     446             :             1<<(sc->vge_camidx & 7));
     447             : 
     448           0 :         sc->vge_camidx++;
     449             : 
     450             : fail:
     451             :         /* Turn off access to CAM. */
     452           0 :         CSR_WRITE_1(sc, VGE_CAMADDR, 0);
     453           0 :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
     454           0 :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_MAR);
     455             : 
     456           0 :         return (error);
     457           0 : }
     458             : 
     459             : /*
     460             :  * We use the 64-entry CAM filter for perfect filtering.
     461             :  * If there's more than 64 multicast addresses, we use the
     462             :  * hash filter instead.
     463             :  */
     464             : void
     465           0 : vge_iff(struct vge_softc *sc)
     466             : {
     467           0 :         struct arpcom           *ac = &sc->arpcom;
     468           0 :         struct ifnet            *ifp = &ac->ac_if;
     469             :         struct ether_multi      *enm;
     470             :         struct ether_multistep  step;
     471           0 :         u_int32_t               h = 0, hashes[2];
     472             :         u_int8_t                rxctl;
     473             :         int                     error;
     474             : 
     475           0 :         vge_cam_clear(sc);
     476           0 :         rxctl = CSR_READ_1(sc, VGE_RXCTL);
     477           0 :         rxctl &= ~(VGE_RXCTL_RX_BCAST | VGE_RXCTL_RX_MCAST |
     478             :             VGE_RXCTL_RX_PROMISC | VGE_RXCTL_RX_UCAST);
     479           0 :         bzero(hashes, sizeof(hashes));
     480           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
     481             : 
     482             :         /*
     483             :          * Always accept broadcast frames.
     484             :          * Always accept frames destined to our station address.
     485             :          */
     486           0 :         rxctl |= VGE_RXCTL_RX_BCAST | VGE_RXCTL_RX_UCAST;
     487             : 
     488           0 :         if ((ifp->if_flags & IFF_PROMISC) == 0)
     489           0 :                 rxctl |= VGE_RXCTL_RX_MCAST;
     490             : 
     491           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
     492           0 :                 ifp->if_flags |= IFF_ALLMULTI;
     493           0 :                 if (ifp->if_flags & IFF_PROMISC)
     494           0 :                         rxctl |= VGE_RXCTL_RX_PROMISC;
     495           0 :                 hashes[0] = hashes[1] = 0xFFFFFFFF;
     496           0 :         } else if (ac->ac_multicnt > VGE_CAM_MAXADDRS) {
     497           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
     498           0 :                 while (enm != NULL) {
     499           0 :                         h = ether_crc32_be(enm->enm_addrlo,
     500           0 :                             ETHER_ADDR_LEN) >> 26;
     501             : 
     502           0 :                         hashes[h >> 5] |= 1 << (h & 0x1f);
     503             : 
     504           0 :                         ETHER_NEXT_MULTI(step, enm);
     505             :                 }
     506             :         } else {
     507           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
     508           0 :                 while (enm != NULL) {
     509           0 :                         error = vge_cam_set(sc, enm->enm_addrlo);
     510           0 :                         if (error)
     511             :                                 break;
     512             : 
     513           0 :                         ETHER_NEXT_MULTI(step, enm);
     514             :                 }
     515             :         }
     516             : 
     517           0 :         CSR_WRITE_4(sc, VGE_MAR0, hashes[0]);
     518           0 :         CSR_WRITE_4(sc, VGE_MAR1, hashes[1]);
     519           0 :         CSR_WRITE_1(sc, VGE_RXCTL, rxctl);
     520           0 : }
     521             : 
     522             : void
     523           0 : vge_reset(struct vge_softc *sc)
     524             : {
     525             :         int                     i;
     526             : 
     527           0 :         CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_SOFTRESET);
     528             : 
     529           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     530           0 :                 DELAY(5);
     531           0 :                 if ((CSR_READ_1(sc, VGE_CRS1) & VGE_CR1_SOFTRESET) == 0)
     532             :                         break;
     533             :         }
     534             : 
     535           0 :         if (i == VGE_TIMEOUT) {
     536           0 :                 printf("%s: soft reset timed out", sc->vge_dev.dv_xname);
     537           0 :                 CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_STOP_FORCE);
     538           0 :                 DELAY(2000);
     539           0 :         }
     540             : 
     541           0 :         DELAY(5000);
     542             : 
     543           0 :         CSR_SETBIT_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
     544             : 
     545           0 :         for (i = 0; i < VGE_TIMEOUT; i++) {
     546           0 :                 DELAY(5);
     547           0 :                 if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
     548             :                         break;
     549             :         }
     550             : 
     551           0 :         CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
     552           0 : }
     553             : 
     554             : /*
     555             :  * Probe for a VIA gigabit chip. Check the PCI vendor and device
     556             :  * IDs against our list and return a device name if we find a match.
     557             :  */
     558             : int
     559           0 : vge_probe(struct device *dev, void *match, void *aux)
     560             : {
     561           0 :         return (pci_matchbyid((struct pci_attach_args *)aux, vge_devices,
     562             :             nitems(vge_devices)));
     563             : }
     564             : 
     565             : /*
     566             :  * Allocate memory for RX/TX rings
     567             :  */
     568             : int
     569           0 : vge_allocmem(struct vge_softc *sc)
     570             : {
     571           0 :         int                     nseg, rseg;
     572             :         int                     i, error;
     573             : 
     574             :         nseg = 32;
     575             : 
     576             :         /* Allocate DMA'able memory for the TX ring */
     577             : 
     578           0 :         error = bus_dmamap_create(sc->sc_dmat, VGE_TX_LIST_SZ, 1,
     579             :             VGE_TX_LIST_SZ, 0, BUS_DMA_ALLOCNOW,
     580             :             &sc->vge_ldata.vge_tx_list_map);
     581           0 :         if (error)
     582           0 :                 return (ENOMEM);
     583           0 :         error = bus_dmamem_alloc(sc->sc_dmat, VGE_TX_LIST_SZ,
     584             :             ETHER_ALIGN, 0,
     585             :             &sc->vge_ldata.vge_tx_listseg, 1, &rseg, BUS_DMA_NOWAIT);
     586           0 :         if (error) {
     587           0 :                 printf("%s: can't alloc TX list\n", sc->vge_dev.dv_xname);
     588           0 :                 return (ENOMEM);
     589             :         }
     590             : 
     591             :         /* Load the map for the TX ring. */
     592           0 :         error = bus_dmamem_map(sc->sc_dmat, &sc->vge_ldata.vge_tx_listseg,
     593             :              1, VGE_TX_LIST_SZ,
     594             :              (caddr_t *)&sc->vge_ldata.vge_tx_list, BUS_DMA_NOWAIT);
     595           0 :         memset(sc->vge_ldata.vge_tx_list, 0, VGE_TX_LIST_SZ);
     596           0 :         if (error) {
     597           0 :                 printf("%s: can't map TX dma buffers\n",
     598           0 :                     sc->vge_dev.dv_xname);
     599           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_tx_listseg, rseg);
     600           0 :                 return (ENOMEM);
     601             :         }
     602             : 
     603           0 :         error = bus_dmamap_load(sc->sc_dmat, sc->vge_ldata.vge_tx_list_map,
     604             :             sc->vge_ldata.vge_tx_list, VGE_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
     605           0 :         if (error) {
     606           0 :                 printf("%s: can't load TX dma map\n", sc->vge_dev.dv_xname);
     607           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->vge_ldata.vge_tx_list_map);
     608           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->vge_ldata.vge_tx_list,
     609             :                     VGE_TX_LIST_SZ);
     610           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_tx_listseg, rseg);
     611           0 :                 return (ENOMEM);
     612             :         }
     613             : 
     614             :         /* Create DMA maps for TX buffers */
     615             : 
     616           0 :         for (i = 0; i < VGE_TX_DESC_CNT; i++) {
     617           0 :                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES * nseg,
     618             :                     VGE_TX_FRAGS, MCLBYTES, 0, BUS_DMA_ALLOCNOW,
     619             :                     &sc->vge_ldata.vge_tx_dmamap[i]);
     620           0 :                 if (error) {
     621           0 :                         printf("%s: can't create DMA map for TX\n",
     622           0 :                             sc->vge_dev.dv_xname);
     623           0 :                         return (ENOMEM);
     624             :                 }
     625             :         }
     626             : 
     627             :         /* Allocate DMA'able memory for the RX ring */
     628             : 
     629           0 :         error = bus_dmamap_create(sc->sc_dmat, VGE_RX_LIST_SZ, 1,
     630             :             VGE_RX_LIST_SZ, 0, BUS_DMA_ALLOCNOW,
     631             :             &sc->vge_ldata.vge_rx_list_map);
     632           0 :         if (error)
     633           0 :                 return (ENOMEM);
     634           0 :         error = bus_dmamem_alloc(sc->sc_dmat, VGE_RX_LIST_SZ, VGE_RING_ALIGN,
     635             :             0, &sc->vge_ldata.vge_rx_listseg, 1, &rseg, BUS_DMA_NOWAIT);
     636           0 :         if (error) {
     637           0 :                 printf("%s: can't alloc RX list\n", sc->vge_dev.dv_xname);
     638           0 :                 return (ENOMEM);
     639             :         }
     640             : 
     641             :         /* Load the map for the RX ring. */
     642             : 
     643           0 :         error = bus_dmamem_map(sc->sc_dmat, &sc->vge_ldata.vge_rx_listseg,
     644             :              1, VGE_RX_LIST_SZ,
     645             :              (caddr_t *)&sc->vge_ldata.vge_rx_list, BUS_DMA_NOWAIT);
     646           0 :         memset(sc->vge_ldata.vge_rx_list, 0, VGE_RX_LIST_SZ);
     647           0 :         if (error) {
     648           0 :                 printf("%s: can't map RX dma buffers\n",
     649           0 :                     sc->vge_dev.dv_xname);
     650           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_rx_listseg, rseg);
     651           0 :                 return (ENOMEM);
     652             :         }
     653           0 :         error = bus_dmamap_load(sc->sc_dmat, sc->vge_ldata.vge_rx_list_map,
     654             :             sc->vge_ldata.vge_rx_list, VGE_RX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
     655           0 :         if (error) {
     656           0 :                 printf("%s: can't load RX dma map\n", sc->vge_dev.dv_xname);
     657           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->vge_ldata.vge_rx_list_map);
     658           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->vge_ldata.vge_rx_list,
     659             :                     VGE_RX_LIST_SZ);
     660           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_rx_listseg, rseg);
     661           0 :                 return (ENOMEM);
     662             :         }
     663             : 
     664             :         /* Create DMA maps for RX buffers */
     665             : 
     666           0 :         for (i = 0; i < VGE_RX_DESC_CNT; i++) {
     667           0 :                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES * nseg, nseg,
     668             :                     MCLBYTES, 0, BUS_DMA_ALLOCNOW,
     669             :                     &sc->vge_ldata.vge_rx_dmamap[i]);
     670           0 :                 if (error) {
     671           0 :                         printf("%s: can't create DMA map for RX\n",
     672           0 :                             sc->vge_dev.dv_xname);
     673           0 :                         return (ENOMEM);
     674             :                 }
     675             :         }
     676             : 
     677           0 :         return (0);
     678           0 : }
     679             : 
     680             : void
     681           0 : vge_freemem(struct vge_softc *sc)
     682             : {
     683             :         int i;
     684             : 
     685           0 :         for (i = 0; i < VGE_RX_DESC_CNT; i++)
     686           0 :                 bus_dmamap_destroy(sc->sc_dmat,
     687             :                     sc->vge_ldata.vge_rx_dmamap[i]);
     688             : 
     689           0 :         bus_dmamap_unload(sc->sc_dmat, sc->vge_ldata.vge_rx_list_map);
     690           0 :         bus_dmamap_destroy(sc->sc_dmat, sc->vge_ldata.vge_rx_list_map);
     691           0 :         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->vge_ldata.vge_rx_list,
     692             :             VGE_RX_LIST_SZ);
     693           0 :         bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_rx_listseg, 1);
     694             : 
     695           0 :         for (i = 0; i < VGE_TX_DESC_CNT; i++)
     696           0 :                 bus_dmamap_destroy(sc->sc_dmat,
     697             :                     sc->vge_ldata.vge_tx_dmamap[i]);
     698             : 
     699           0 :         bus_dmamap_unload(sc->sc_dmat, sc->vge_ldata.vge_tx_list_map);
     700           0 :         bus_dmamap_destroy(sc->sc_dmat, sc->vge_ldata.vge_tx_list_map);
     701           0 :         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->vge_ldata.vge_tx_list,
     702             :             VGE_TX_LIST_SZ);
     703           0 :         bus_dmamem_free(sc->sc_dmat, &sc->vge_ldata.vge_tx_listseg, 1);
     704           0 : }
     705             : 
     706             : /*
     707             :  * Attach the interface. Allocate softc structures, do ifmedia
     708             :  * setup and ethernet/BPF attach.
     709             :  */
     710             : void
     711           0 : vge_attach(struct device *parent, struct device *self, void *aux)
     712             : {
     713           0 :         u_char                  eaddr[ETHER_ADDR_LEN];
     714           0 :         struct vge_softc        *sc = (struct vge_softc *)self;
     715           0 :         struct pci_attach_args  *pa = aux;
     716           0 :         pci_chipset_tag_t       pc = pa->pa_pc;
     717           0 :         pci_intr_handle_t       ih;
     718             :         const char              *intrstr = NULL;
     719             :         struct ifnet            *ifp;
     720             :         int                     error = 0;
     721             : 
     722             :         /*
     723             :          * Map control/status registers.
     724             :          */
     725           0 :         if (pci_mapreg_map(pa, VGE_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
     726           0 :             &sc->vge_btag, &sc->vge_bhandle, NULL, &sc->vge_bsize, 0)) {
     727           0 :                 if (pci_mapreg_map(pa, VGE_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
     728             :                     &sc->vge_btag, &sc->vge_bhandle, NULL, &sc->vge_bsize, 0)) {
     729           0 :                         printf(": can't map mem or i/o space\n");
     730           0 :                         return;
     731             :                 }
     732             :         }
     733             : 
     734             :         /* Allocate interrupt */
     735           0 :         if (pci_intr_map(pa, &ih)) {
     736           0 :                 printf(": couldn't map interrupt\n");
     737           0 :                 return;
     738             :         }
     739           0 :         intrstr = pci_intr_string(pc, ih);
     740           0 :         sc->vge_intrhand = pci_intr_establish(pc, ih, IPL_NET, vge_intr, sc,
     741           0 :             sc->vge_dev.dv_xname);
     742           0 :         if (sc->vge_intrhand == NULL) {
     743           0 :                 printf(": couldn't establish interrupt");
     744           0 :                 if (intrstr != NULL)
     745           0 :                         printf(" at %s", intrstr);
     746           0 :                 return;
     747             :         }
     748           0 :         printf(": %s", intrstr);
     749             : 
     750           0 :         sc->sc_dmat = pa->pa_dmat;
     751           0 :         sc->sc_pc = pa->pa_pc;
     752             : 
     753             :         /* Reset the adapter. */
     754           0 :         vge_reset(sc);
     755             : 
     756             :         /*
     757             :          * Get station address from the EEPROM.
     758             :          */
     759           0 :         vge_read_eeprom(sc, eaddr, VGE_EE_EADDR, 3, 1);
     760             : 
     761           0 :         bcopy(eaddr, &sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
     762             : 
     763           0 :         printf(", address %s\n",
     764           0 :             ether_sprintf(sc->arpcom.ac_enaddr));
     765             : 
     766           0 :         error = vge_allocmem(sc);
     767             : 
     768           0 :         if (error)
     769           0 :                 return;
     770             : 
     771           0 :         ifp = &sc->arpcom.ac_if;
     772           0 :         ifp->if_softc = sc;
     773           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     774           0 :         ifp->if_ioctl = vge_ioctl;
     775           0 :         ifp->if_start = vge_start;
     776           0 :         ifp->if_watchdog = vge_watchdog;
     777             : #ifdef VGE_JUMBO
     778             :         ifp->if_hardmtu = VGE_JUMBO_MTU;
     779             : #endif
     780           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN);
     781             : 
     782           0 :         ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
     783             :                                 IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
     784             : 
     785             : #if NVLAN > 0
     786           0 :         ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
     787             : #endif
     788             : 
     789             :         /* Set interface name */
     790           0 :         strlcpy(ifp->if_xname, sc->vge_dev.dv_xname, IFNAMSIZ);
     791             : 
     792             :         /* Do MII setup */
     793           0 :         sc->sc_mii.mii_ifp = ifp;
     794           0 :         sc->sc_mii.mii_readreg = vge_miibus_readreg;
     795           0 :         sc->sc_mii.mii_writereg = vge_miibus_writereg;
     796           0 :         sc->sc_mii.mii_statchg = vge_miibus_statchg;
     797           0 :         ifmedia_init(&sc->sc_mii.mii_media, 0,
     798             :             vge_ifmedia_upd, vge_ifmedia_sts);
     799           0 :         mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
     800             :             MII_OFFSET_ANY, MIIF_DOPAUSE);
     801           0 :         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
     802           0 :                 printf("%s: no PHY found!\n", sc->vge_dev.dv_xname);
     803           0 :                 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
     804             :                     0, NULL);
     805           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
     806           0 :         } else
     807           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
     808             : 
     809           0 :         timeout_set(&sc->timer_handle, vge_tick, sc);
     810             : 
     811             :         /*
     812             :          * Call MI attach routine.
     813             :          */
     814           0 :         if_attach(ifp);
     815           0 :         ether_ifattach(ifp);
     816           0 : }
     817             : 
     818             : int
     819           0 : vge_detach(struct device *self, int flags)
     820             : {
     821           0 :         struct vge_softc *sc = (void *)self;
     822           0 :         struct ifnet *ifp = &sc->arpcom.ac_if;
     823             : 
     824           0 :         pci_intr_disestablish(sc->sc_pc, sc->vge_intrhand);
     825             : 
     826           0 :         vge_stop(sc);
     827             : 
     828             :         /* Detach all PHYs */
     829           0 :         mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
     830             : 
     831             :         /* Delete any remaining media. */
     832           0 :         ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
     833             : 
     834           0 :         ether_ifdetach(ifp);
     835           0 :         if_detach(ifp);
     836             : 
     837           0 :         vge_freemem(sc);
     838             : 
     839           0 :         bus_space_unmap(sc->vge_btag, sc->vge_bhandle, sc->vge_bsize);
     840           0 :         return (0);
     841             : }
     842             : 
     843             : int
     844           0 : vge_newbuf(struct vge_softc *sc, int idx, struct mbuf *m)
     845             : {
     846             :         struct mbuf             *m_new = NULL;
     847             :         struct vge_rx_desc      *r;
     848           0 :         bus_dmamap_t            rxmap = sc->vge_ldata.vge_rx_dmamap[idx];
     849             :         int                     i;
     850             : 
     851           0 :         if (m == NULL) {
     852             :                 /* Allocate a new mbuf */
     853           0 :                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
     854           0 :                 if (m_new == NULL)
     855           0 :                         return (ENOBUFS);
     856             : 
     857             :                 /* Allocate a cluster */
     858           0 :                 MCLGET(m_new, M_DONTWAIT);
     859           0 :                 if (!(m_new->m_flags & M_EXT)) {
     860           0 :                         m_freem(m_new);
     861           0 :                         return (ENOBUFS);
     862             :                 }
     863             : 
     864             :                 m = m_new;
     865           0 :         } else
     866           0 :                 m->m_data = m->m_ext.ext_buf;
     867             : 
     868           0 :         m->m_len = m->m_pkthdr.len = MCLBYTES;
     869             :         /* Fix-up alignment so payload is doubleword-aligned */
     870             :         /* XXX m_adj(m, ETHER_ALIGN); */
     871             : 
     872           0 :         if (bus_dmamap_load_mbuf(sc->sc_dmat, rxmap, m, BUS_DMA_NOWAIT))
     873           0 :                 return (ENOBUFS);
     874             : 
     875           0 :         if (rxmap->dm_nsegs > 1)
     876             :                 goto out;
     877             : 
     878             :         /* Map the segments into RX descriptors */
     879           0 :         r = &sc->vge_ldata.vge_rx_list[idx];
     880             : 
     881           0 :         if (letoh32(r->vge_sts) & VGE_RDSTS_OWN) {
     882           0 :                 printf("%s: tried to map a busy RX descriptor\n",
     883           0 :                     sc->vge_dev.dv_xname);
     884           0 :                 goto out;
     885             :         }
     886           0 :         r->vge_buflen = htole16(VGE_BUFLEN(rxmap->dm_segs[0].ds_len) | VGE_RXDESC_I);
     887           0 :         r->vge_addrlo = htole32(VGE_ADDR_LO(rxmap->dm_segs[0].ds_addr));
     888           0 :         r->vge_addrhi = htole16(VGE_ADDR_HI(rxmap->dm_segs[0].ds_addr) & 0xFFFF);
     889           0 :         r->vge_sts = htole32(0);
     890           0 :         r->vge_ctl = htole32(0);
     891             : 
     892             :         /*
     893             :          * Note: the manual fails to document the fact that for
     894             :          * proper operation, the driver needs to replenish the RX
     895             :          * DMA ring 4 descriptors at a time (rather than one at a
     896             :          * time, like most chips). We can allocate the new buffers
     897             :          * but we should not set the OWN bits until we're ready
     898             :          * to hand back 4 of them in one shot.
     899             :          */
     900             : #define VGE_RXCHUNK 4
     901           0 :         sc->vge_rx_consumed++;
     902           0 :         if (sc->vge_rx_consumed == VGE_RXCHUNK) {
     903           0 :                 for (i = idx; i != idx - sc->vge_rx_consumed; i--)
     904           0 :                         sc->vge_ldata.vge_rx_list[i].vge_sts |=
     905             :                             htole32(VGE_RDSTS_OWN);
     906           0 :                 sc->vge_rx_consumed = 0;
     907           0 :         }
     908             : 
     909           0 :         sc->vge_ldata.vge_rx_mbuf[idx] = m;
     910             : 
     911           0 :         bus_dmamap_sync(sc->sc_dmat, rxmap, 0,
     912             :             rxmap->dm_mapsize, BUS_DMASYNC_PREREAD);
     913             : 
     914           0 :         return (0);
     915             : out:
     916           0 :         DPRINTF(("vge_newbuf: out of memory\n"));
     917           0 :         if (m_new != NULL)
     918           0 :                 m_freem(m_new);
     919           0 :         return (ENOMEM);
     920           0 : }
     921             : 
     922             : int
     923           0 : vge_tx_list_init(struct vge_softc *sc)
     924             : {
     925           0 :         bzero(sc->vge_ldata.vge_tx_list, VGE_TX_LIST_SZ);
     926           0 :         bzero(&sc->vge_ldata.vge_tx_mbuf,
     927             :             (VGE_TX_DESC_CNT * sizeof(struct mbuf *)));
     928             : 
     929           0 :         bus_dmamap_sync(sc->sc_dmat,
     930             :             sc->vge_ldata.vge_tx_list_map, 0,
     931             :             sc->vge_ldata.vge_tx_list_map->dm_mapsize,
     932             :             BUS_DMASYNC_PREWRITE);
     933           0 :         sc->vge_ldata.vge_tx_prodidx = 0;
     934           0 :         sc->vge_ldata.vge_tx_considx = 0;
     935           0 :         sc->vge_ldata.vge_tx_free = VGE_TX_DESC_CNT;
     936             : 
     937           0 :         return (0);
     938             : }
     939             : 
     940             : /* Init RX descriptors and allocate mbufs with vge_newbuf()
     941             :  * A ring is used, and last descriptor points to first. */
     942             : int
     943           0 : vge_rx_list_init(struct vge_softc *sc)
     944             : {
     945             :         int                     i;
     946             : 
     947           0 :         bzero(sc->vge_ldata.vge_rx_list, VGE_RX_LIST_SZ);
     948           0 :         bzero(&sc->vge_ldata.vge_rx_mbuf,
     949             :             (VGE_RX_DESC_CNT * sizeof(struct mbuf *)));
     950             : 
     951           0 :         sc->vge_rx_consumed = 0;
     952             : 
     953           0 :         for (i = 0; i < VGE_RX_DESC_CNT; i++) {
     954           0 :                 if (vge_newbuf(sc, i, NULL) == ENOBUFS)
     955           0 :                         return (ENOBUFS);
     956             :         }
     957             : 
     958             :         /* Flush the RX descriptors */
     959             : 
     960           0 :         bus_dmamap_sync(sc->sc_dmat,
     961             :             sc->vge_ldata.vge_rx_list_map,
     962             :             0, sc->vge_ldata.vge_rx_list_map->dm_mapsize,
     963             :             BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
     964             : 
     965           0 :         sc->vge_ldata.vge_rx_prodidx = 0;
     966           0 :         sc->vge_rx_consumed = 0;
     967           0 :         sc->vge_head = sc->vge_tail = NULL;
     968             : 
     969           0 :         return (0);
     970           0 : }
     971             : 
     972             : /*
     973             :  * RX handler. We support the reception of jumbo frames that have
     974             :  * been fragmented across multiple 2K mbuf cluster buffers.
     975             :  */
     976             : void
     977           0 : vge_rxeof(struct vge_softc *sc)
     978             : {
     979           0 :         struct mbuf_list        ml = MBUF_LIST_INITIALIZER();
     980             :         struct mbuf             *m;
     981             :         struct ifnet            *ifp;
     982             :         int                     i, total_len;
     983             :         int                     lim = 0;
     984             :         struct vge_rx_desc      *cur_rx;
     985             :         u_int32_t               rxstat, rxctl;
     986             : 
     987           0 :         ifp = &sc->arpcom.ac_if;
     988           0 :         i = sc->vge_ldata.vge_rx_prodidx;
     989             : 
     990             :         /* Invalidate the descriptor memory */
     991             : 
     992           0 :         bus_dmamap_sync(sc->sc_dmat,
     993             :             sc->vge_ldata.vge_rx_list_map,
     994             :             0, sc->vge_ldata.vge_rx_list_map->dm_mapsize,
     995             :             BUS_DMASYNC_POSTREAD);
     996             : 
     997           0 :         while (!VGE_OWN(&sc->vge_ldata.vge_rx_list[i])) {
     998             :                 struct mbuf *m0 = NULL;
     999             : 
    1000           0 :                 cur_rx = &sc->vge_ldata.vge_rx_list[i];
    1001           0 :                 m = sc->vge_ldata.vge_rx_mbuf[i];
    1002           0 :                 total_len = VGE_RXBYTES(cur_rx);
    1003           0 :                 rxstat = letoh32(cur_rx->vge_sts);
    1004           0 :                 rxctl = letoh32(cur_rx->vge_ctl);
    1005             : 
    1006             :                 /* Invalidate the RX mbuf and unload its map */
    1007             : 
    1008           0 :                 bus_dmamap_sync(sc->sc_dmat,
    1009             :                     sc->vge_ldata.vge_rx_dmamap[i],
    1010             :                     0, sc->vge_ldata.vge_rx_dmamap[i]->dm_mapsize,
    1011             :                     BUS_DMASYNC_POSTWRITE);
    1012           0 :                 bus_dmamap_unload(sc->sc_dmat,
    1013             :                     sc->vge_ldata.vge_rx_dmamap[i]);
    1014             : 
    1015             :                 /*
    1016             :                  * If the 'start of frame' bit is set, this indicates
    1017             :                  * either the first fragment in a multi-fragment receive,
    1018             :                  * or an intermediate fragment. Either way, we want to
    1019             :                  * accumulate the buffers.
    1020             :                  */
    1021           0 :                 if (rxstat & VGE_RXPKT_SOF) {
    1022           0 :                         DPRINTF(("vge_rxeof: SOF\n"));
    1023           0 :                         m->m_len = MCLBYTES;
    1024           0 :                         if (sc->vge_head == NULL)
    1025           0 :                                 sc->vge_head = sc->vge_tail = m;
    1026             :                         else {
    1027           0 :                                 m->m_flags &= ~M_PKTHDR;
    1028           0 :                                 sc->vge_tail->m_next = m;
    1029           0 :                                 sc->vge_tail = m;
    1030             :                         }
    1031           0 :                         vge_newbuf(sc, i, NULL);
    1032           0 :                         VGE_RX_DESC_INC(i);
    1033           0 :                         continue;
    1034             :                 }
    1035             : 
    1036             :                 /*
    1037             :                  * Bad/error frames will have the RXOK bit cleared.
    1038             :                  * However, there's one error case we want to allow:
    1039             :                  * if a VLAN tagged frame arrives and the chip can't
    1040             :                  * match it against the CAM filter, it considers this
    1041             :                  * a 'VLAN CAM filter miss' and clears the 'RXOK' bit.
    1042             :                  * We don't want to drop the frame though: our VLAN
    1043             :                  * filtering is done in software.
    1044             :                  */
    1045           0 :                 if (!(rxstat & VGE_RDSTS_RXOK) && !(rxstat & VGE_RDSTS_VIDM)
    1046           0 :                     && !(rxstat & VGE_RDSTS_CSUMERR)) {
    1047           0 :                         ifp->if_ierrors++;
    1048             :                         /*
    1049             :                          * If this is part of a multi-fragment packet,
    1050             :                          * discard all the pieces.
    1051             :                          */
    1052           0 :                         if (sc->vge_head != NULL) {
    1053           0 :                                 m_freem(sc->vge_head);
    1054           0 :                                 sc->vge_head = sc->vge_tail = NULL;
    1055           0 :                         }
    1056           0 :                         vge_newbuf(sc, i, m);
    1057           0 :                         VGE_RX_DESC_INC(i);
    1058           0 :                         continue;
    1059             :                 }
    1060             : 
    1061             :                 /*
    1062             :                  * If allocating a replacement mbuf fails,
    1063             :                  * reload the current one.
    1064             :                  */
    1065             : 
    1066           0 :                 if (vge_newbuf(sc, i, NULL) == ENOBUFS) {
    1067           0 :                         if (sc->vge_head != NULL) {
    1068           0 :                                 m_freem(sc->vge_head);
    1069           0 :                                 sc->vge_head = sc->vge_tail = NULL;
    1070           0 :                         }
    1071             : 
    1072           0 :                         m0 = m_devget(mtod(m, char *),
    1073           0 :                             total_len - ETHER_CRC_LEN, ETHER_ALIGN);
    1074           0 :                         vge_newbuf(sc, i, m);
    1075           0 :                         if (m0 == NULL) {
    1076           0 :                                 ifp->if_ierrors++;
    1077           0 :                                 continue;
    1078             :                         }
    1079             :                         m = m0;
    1080             : 
    1081           0 :                         VGE_RX_DESC_INC(i);
    1082           0 :                         continue;
    1083             :                 }
    1084             : 
    1085           0 :                 VGE_RX_DESC_INC(i);
    1086             : 
    1087           0 :                 if (sc->vge_head != NULL) {
    1088           0 :                         m->m_len = total_len % MCLBYTES;
    1089             :                         /*
    1090             :                          * Special case: if there's 4 bytes or less
    1091             :                          * in this buffer, the mbuf can be discarded:
    1092             :                          * the last 4 bytes is the CRC, which we don't
    1093             :                          * care about anyway.
    1094             :                          */
    1095           0 :                         if (m->m_len <= ETHER_CRC_LEN) {
    1096           0 :                                 sc->vge_tail->m_len -=
    1097           0 :                                     (ETHER_CRC_LEN - m->m_len);
    1098           0 :                                 m_freem(m);
    1099           0 :                         } else {
    1100           0 :                                 m->m_len -= ETHER_CRC_LEN;
    1101           0 :                                 m->m_flags &= ~M_PKTHDR;
    1102           0 :                                 sc->vge_tail->m_next = m;
    1103             :                         }
    1104           0 :                         m = sc->vge_head;
    1105           0 :                         sc->vge_head = sc->vge_tail = NULL;
    1106           0 :                         m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
    1107           0 :                 } else
    1108           0 :                         m->m_pkthdr.len = m->m_len =
    1109           0 :                             (total_len - ETHER_CRC_LEN);
    1110             : 
    1111             : #ifdef __STRICT_ALIGNMENT
    1112             :                 bcopy(m->m_data, m->m_data + ETHER_ALIGN, total_len);
    1113             :                 m->m_data += ETHER_ALIGN;
    1114             : #endif
    1115             :                 /* Do RX checksumming */
    1116             : 
    1117             :                 /* Check IP header checksum */
    1118           0 :                 if ((rxctl & VGE_RDCTL_IPPKT) &&
    1119           0 :                     (rxctl & VGE_RDCTL_IPCSUMOK))
    1120           0 :                         m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
    1121             : 
    1122             :                 /* Check TCP/UDP checksum */
    1123           0 :                 if ((rxctl & (VGE_RDCTL_TCPPKT|VGE_RDCTL_UDPPKT)) &&
    1124           0 :                     (rxctl & VGE_RDCTL_PROTOCSUMOK))
    1125           0 :                         m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
    1126             : 
    1127             : #if NVLAN > 0
    1128           0 :                 if (rxstat & VGE_RDSTS_VTAG) {
    1129           0 :                         m->m_pkthdr.ether_vtag = swap16(rxctl & VGE_RDCTL_VLANID);
    1130           0 :                         m->m_flags |= M_VLANTAG;
    1131           0 :                 }
    1132             : #endif
    1133             : 
    1134           0 :                 ml_enqueue(&ml, m);
    1135             : 
    1136           0 :                 lim++;
    1137           0 :                 if (lim == VGE_RX_DESC_CNT)
    1138           0 :                         break;
    1139           0 :         }
    1140             : 
    1141           0 :         if_input(ifp, &ml);
    1142             : 
    1143             :         /* Flush the RX DMA ring */
    1144           0 :         bus_dmamap_sync(sc->sc_dmat,
    1145             :             sc->vge_ldata.vge_rx_list_map,
    1146             :             0, sc->vge_ldata.vge_rx_list_map->dm_mapsize,
    1147             :             BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
    1148             : 
    1149           0 :         sc->vge_ldata.vge_rx_prodidx = i;
    1150           0 :         CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, lim);
    1151           0 : }
    1152             : 
    1153             : void
    1154           0 : vge_txeof(struct vge_softc *sc)
    1155             : {
    1156             :         struct ifnet            *ifp;
    1157             :         u_int32_t               txstat;
    1158             :         int                     idx;
    1159             : 
    1160           0 :         ifp = &sc->arpcom.ac_if;
    1161           0 :         idx = sc->vge_ldata.vge_tx_considx;
    1162             : 
    1163             :         /* Invalidate the TX descriptor list */
    1164             : 
    1165           0 :         bus_dmamap_sync(sc->sc_dmat,
    1166             :             sc->vge_ldata.vge_tx_list_map,
    1167             :             0, sc->vge_ldata.vge_tx_list_map->dm_mapsize,
    1168             :             BUS_DMASYNC_POSTREAD);
    1169             : 
    1170             :         /* Transmitted frames can be now free'd from the TX list */
    1171           0 :         while (idx != sc->vge_ldata.vge_tx_prodidx) {
    1172           0 :                 txstat = letoh32(sc->vge_ldata.vge_tx_list[idx].vge_sts);
    1173           0 :                 if (txstat & VGE_TDSTS_OWN)
    1174             :                         break;
    1175             : 
    1176           0 :                 m_freem(sc->vge_ldata.vge_tx_mbuf[idx]);
    1177           0 :                 sc->vge_ldata.vge_tx_mbuf[idx] = NULL;
    1178           0 :                 bus_dmamap_unload(sc->sc_dmat,
    1179             :                     sc->vge_ldata.vge_tx_dmamap[idx]);
    1180           0 :                 if (txstat & (VGE_TDSTS_EXCESSCOLL|VGE_TDSTS_COLL))
    1181           0 :                         ifp->if_collisions++;
    1182           0 :                 if (txstat & VGE_TDSTS_TXERR)
    1183           0 :                         ifp->if_oerrors++;
    1184             : 
    1185           0 :                 sc->vge_ldata.vge_tx_free++;
    1186           0 :                 VGE_TX_DESC_INC(idx);
    1187             :         }
    1188             : 
    1189             :         /* No changes made to the TX ring, so no flush needed */
    1190             : 
    1191           0 :         if (idx != sc->vge_ldata.vge_tx_considx) {
    1192           0 :                 sc->vge_ldata.vge_tx_considx = idx;
    1193           0 :                 ifq_clr_oactive(&ifp->if_snd);
    1194           0 :                 ifp->if_timer = 0;
    1195           0 :         }
    1196             : 
    1197             :         /*
    1198             :          * If not all descriptors have been released reaped yet,
    1199             :          * reload the timer so that we will eventually get another
    1200             :          * interrupt that will cause us to re-enter this routine.
    1201             :          * This is done in case the transmitter has gone idle.
    1202             :          */
    1203           0 :         if (sc->vge_ldata.vge_tx_free != VGE_TX_DESC_CNT)
    1204           0 :                 CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
    1205           0 : }
    1206             : 
    1207             : void
    1208           0 : vge_tick(void *xsc)
    1209             : {
    1210           0 :         struct vge_softc        *sc = xsc;
    1211           0 :         struct ifnet            *ifp = &sc->arpcom.ac_if;
    1212           0 :         struct mii_data         *mii = &sc->sc_mii;
    1213             :         int s;
    1214             : 
    1215           0 :         s = splnet();
    1216             : 
    1217           0 :         mii_tick(mii);
    1218             : 
    1219           0 :         if (sc->vge_link) {
    1220           0 :                 if (!(mii->mii_media_status & IFM_ACTIVE)) {
    1221           0 :                         sc->vge_link = 0;
    1222           0 :                         ifp->if_link_state = LINK_STATE_DOWN;
    1223           0 :                         if_link_state_change(ifp);
    1224           0 :                 }
    1225             :         } else {
    1226           0 :                 if (mii->mii_media_status & IFM_ACTIVE &&
    1227           0 :                     IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
    1228           0 :                         sc->vge_link = 1;
    1229           0 :                         if (mii->mii_media_status & IFM_FDX)
    1230           0 :                                 ifp->if_link_state = LINK_STATE_FULL_DUPLEX;
    1231             :                         else
    1232           0 :                                 ifp->if_link_state = LINK_STATE_HALF_DUPLEX;
    1233           0 :                         if_link_state_change(ifp);
    1234           0 :                         if (!IFQ_IS_EMPTY(&ifp->if_snd))
    1235           0 :                                 vge_start(ifp);
    1236             :                 }
    1237             :         }
    1238           0 :         timeout_add_sec(&sc->timer_handle, 1);
    1239           0 :         splx(s);
    1240           0 : }
    1241             : 
    1242             : int
    1243           0 : vge_intr(void *arg)
    1244             : {
    1245           0 :         struct vge_softc        *sc = arg;
    1246             :         struct ifnet            *ifp;
    1247             :         u_int32_t               status;
    1248             :         int                     claimed = 0;
    1249             : 
    1250           0 :         ifp = &sc->arpcom.ac_if;
    1251             : 
    1252           0 :         if (!(ifp->if_flags & IFF_UP))
    1253           0 :                 return 0;
    1254             : 
    1255             :         /* Disable interrupts */
    1256           0 :         CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK);
    1257             : 
    1258           0 :         for (;;) {
    1259           0 :                 status = CSR_READ_4(sc, VGE_ISR);
    1260           0 :                 DPRINTFN(3, ("vge_intr: status=%#x\n", status));
    1261             : 
    1262             :                 /* If the card has gone away the read returns 0xffffffff. */
    1263           0 :                 if (status == 0xFFFFFFFF)
    1264             :                         break;
    1265             : 
    1266           0 :                 if (status) {
    1267           0 :                         CSR_WRITE_4(sc, VGE_ISR, status);
    1268           0 :                 }
    1269             : 
    1270           0 :                 if ((status & VGE_INTRS) == 0)
    1271             :                         break;
    1272             : 
    1273             :                 claimed = 1;
    1274             : 
    1275           0 :                 if (status & (VGE_ISR_RXOK|VGE_ISR_RXOK_HIPRIO))
    1276           0 :                         vge_rxeof(sc);
    1277             : 
    1278           0 :                 if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) {
    1279           0 :                         DPRINTFN(2, ("vge_intr: RX error, recovering\n"));
    1280           0 :                         vge_rxeof(sc);
    1281           0 :                         CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
    1282           0 :                         CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
    1283           0 :                 }
    1284             : 
    1285           0 :                 if (status & (VGE_ISR_TXOK0|VGE_ISR_TIMER0))
    1286           0 :                         vge_txeof(sc);
    1287             : 
    1288           0 :                 if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL)) {
    1289           0 :                         DPRINTFN(2, ("DMA_STALL\n"));
    1290           0 :                         vge_init(ifp);
    1291           0 :                 }
    1292             : 
    1293           0 :                 if (status & VGE_ISR_LINKSTS) {
    1294           0 :                         timeout_del(&sc->timer_handle);
    1295           0 :                         vge_tick(sc);
    1296           0 :                 }
    1297             :         }
    1298             : 
    1299             :         /* Re-enable interrupts */
    1300           0 :         CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
    1301             : 
    1302           0 :         if (!IFQ_IS_EMPTY(&ifp->if_snd))
    1303           0 :                 vge_start(ifp);
    1304             : 
    1305           0 :         return (claimed);
    1306           0 : }
    1307             : 
    1308             : /*
    1309             :  * Encapsulate an mbuf chain into the TX ring by combining it w/
    1310             :  * the descriptors.
    1311             :  */
    1312             : int
    1313           0 : vge_encap(struct vge_softc *sc, struct mbuf *m_head, int idx)
    1314             : {
    1315             :         bus_dmamap_t            txmap;
    1316             :         struct vge_tx_desc      *d = NULL;
    1317             :         struct vge_tx_frag      *f;
    1318             :         int                     error, frag;
    1319             :         u_int32_t               vge_flags;
    1320             :         unsigned int            len;
    1321             : 
    1322             :         vge_flags = 0;
    1323             : 
    1324           0 :         if (m_head->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
    1325           0 :                 vge_flags |= VGE_TDCTL_IPCSUM;
    1326           0 :         if (m_head->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
    1327           0 :                 vge_flags |= VGE_TDCTL_TCPCSUM;
    1328           0 :         if (m_head->m_pkthdr.csum_flags & M_UDP_CSUM_OUT)
    1329           0 :                 vge_flags |= VGE_TDCTL_UDPCSUM;
    1330             : 
    1331           0 :         txmap = sc->vge_ldata.vge_tx_dmamap[idx];
    1332           0 :         error = bus_dmamap_load_mbuf(sc->sc_dmat, txmap,
    1333             :             m_head, BUS_DMA_NOWAIT);
    1334           0 :         switch (error) {
    1335             :         case 0:
    1336             :                 break;
    1337             :         case EFBIG: /* mbuf chain is too fragmented */
    1338           0 :                 if ((error = m_defrag(m_head, M_DONTWAIT)) == 0 &&
    1339           0 :                     (error = bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m_head,
    1340           0 :                     BUS_DMA_NOWAIT)) == 0)
    1341             :                         break;
    1342             :         default:
    1343           0 :                 return (error);
    1344             :         }
    1345             : 
    1346           0 :         d = &sc->vge_ldata.vge_tx_list[idx];
    1347             :         /* If owned by chip, fail */
    1348           0 :         if (letoh32(d->vge_sts) & VGE_TDSTS_OWN)
    1349           0 :                 return (ENOBUFS);
    1350             : 
    1351           0 :         for (frag = 0; frag < txmap->dm_nsegs; frag++) {
    1352           0 :                 f = &d->vge_frag[frag];
    1353           0 :                 f->vge_buflen = htole16(VGE_BUFLEN(txmap->dm_segs[frag].ds_len));
    1354           0 :                 f->vge_addrlo = htole32(VGE_ADDR_LO(txmap->dm_segs[frag].ds_addr));
    1355           0 :                 f->vge_addrhi = htole16(VGE_ADDR_HI(txmap->dm_segs[frag].ds_addr) & 0xFFFF);
    1356             :         }
    1357             : 
    1358             :         /* This chip does not do auto-padding */
    1359           0 :         if (m_head->m_pkthdr.len < VGE_MIN_FRAMELEN) {
    1360           0 :                 f = &d->vge_frag[frag];
    1361             : 
    1362           0 :                 f->vge_buflen = htole16(VGE_BUFLEN(VGE_MIN_FRAMELEN -
    1363             :                     m_head->m_pkthdr.len));
    1364           0 :                 f->vge_addrlo = htole32(VGE_ADDR_LO(txmap->dm_segs[0].ds_addr));
    1365           0 :                 f->vge_addrhi = htole16(VGE_ADDR_HI(txmap->dm_segs[0].ds_addr) & 0xFFFF);
    1366             :                 len = VGE_MIN_FRAMELEN;
    1367           0 :                 frag++;
    1368           0 :         } else
    1369             :                 len = m_head->m_pkthdr.len;
    1370             : 
    1371             :         /* For some reason, we need to tell the card fragment + 1 */
    1372           0 :         frag++;
    1373             : 
    1374           0 :         bus_dmamap_sync(sc->sc_dmat, txmap, 0, txmap->dm_mapsize,
    1375             :             BUS_DMASYNC_PREWRITE);
    1376             : 
    1377           0 :         d->vge_sts = htole32(len << 16);
    1378           0 :         d->vge_ctl = htole32(vge_flags|(frag << 28) | VGE_TD_LS_NORM);
    1379             : 
    1380           0 :         if (len > ETHERMTU + ETHER_HDR_LEN)
    1381           0 :                 d->vge_ctl |= htole32(VGE_TDCTL_JUMBO);
    1382             : 
    1383             : #if NVLAN > 0
    1384             :         /* Set up hardware VLAN tagging. */
    1385           0 :         if (m_head->m_flags & M_VLANTAG) {
    1386           0 :                 d->vge_ctl |= htole32(m_head->m_pkthdr.ether_vtag |
    1387             :                     VGE_TDCTL_VTAG);
    1388           0 :         }
    1389             : #endif
    1390             : 
    1391           0 :         sc->vge_ldata.vge_tx_dmamap[idx] = txmap;
    1392           0 :         sc->vge_ldata.vge_tx_mbuf[idx] = m_head;
    1393           0 :         sc->vge_ldata.vge_tx_free--;
    1394           0 :         sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
    1395             : 
    1396             :         idx++;
    1397           0 :         return (0);
    1398           0 : }
    1399             : 
    1400             : /*
    1401             :  * Main transmit routine.
    1402             :  */
    1403             : void
    1404           0 : vge_start(struct ifnet *ifp)
    1405             : {
    1406             :         struct vge_softc        *sc;
    1407             :         struct mbuf             *m_head = NULL;
    1408             :         int                     idx, pidx = 0;
    1409             : 
    1410           0 :         sc = ifp->if_softc;
    1411             : 
    1412           0 :         if (!sc->vge_link || ifq_is_oactive(&ifp->if_snd))
    1413           0 :                 return;
    1414             : 
    1415           0 :         if (IFQ_IS_EMPTY(&ifp->if_snd))
    1416           0 :                 return;
    1417             : 
    1418           0 :         idx = sc->vge_ldata.vge_tx_prodidx;
    1419             : 
    1420           0 :         pidx = idx - 1;
    1421           0 :         if (pidx < 0)
    1422             :                 pidx = VGE_TX_DESC_CNT - 1;
    1423             : 
    1424           0 :         for (;;) {
    1425           0 :                 if (sc->vge_ldata.vge_tx_mbuf[idx] != NULL) {
    1426           0 :                         ifq_set_oactive(&ifp->if_snd);
    1427           0 :                         break;
    1428             :                 }
    1429             : 
    1430           0 :                 IFQ_DEQUEUE(&ifp->if_snd, m_head);
    1431           0 :                 if (m_head == NULL)
    1432             :                         break;
    1433             : 
    1434           0 :                 if (vge_encap(sc, m_head, idx)) {
    1435           0 :                         m_freem(m_head);
    1436           0 :                         ifp->if_oerrors++;
    1437           0 :                         continue;
    1438             :                 }
    1439             : 
    1440             :                 /*
    1441             :                  * If there's a BPF listener, bounce a copy of this frame
    1442             :                  * to him.
    1443             :                  */
    1444             : #if NBPFILTER > 0
    1445           0 :                 if (ifp->if_bpf)
    1446           0 :                         bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
    1447             : #endif
    1448             : 
    1449           0 :                 sc->vge_ldata.vge_tx_list[pidx].vge_frag[0].vge_buflen |=
    1450             :                     htole16(VGE_TXDESC_Q);
    1451             : 
    1452             :                 pidx = idx;
    1453           0 :                 VGE_TX_DESC_INC(idx);
    1454             :         }
    1455             : 
    1456           0 :         if (idx == sc->vge_ldata.vge_tx_prodidx) {
    1457           0 :                 return;
    1458             :         }
    1459             : 
    1460             :         /* Flush the TX descriptors */
    1461             : 
    1462           0 :         bus_dmamap_sync(sc->sc_dmat,
    1463             :             sc->vge_ldata.vge_tx_list_map,
    1464             :             0, sc->vge_ldata.vge_tx_list_map->dm_mapsize,
    1465             :             BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
    1466             : 
    1467             :         /* Issue a transmit command. */
    1468           0 :         CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_WAK0);
    1469             : 
    1470           0 :         sc->vge_ldata.vge_tx_prodidx = idx;
    1471             : 
    1472             :         /*
    1473             :          * Use the countdown timer for interrupt moderation.
    1474             :          * 'TX done' interrupts are disabled. Instead, we reset the
    1475             :          * countdown timer, which will begin counting until it hits
    1476             :          * the value in the SSTIMER register, and then trigger an
    1477             :          * interrupt. Each time we set the TIMER0_ENABLE bit, the
    1478             :          * the timer count is reloaded. Only when the transmitter
    1479             :          * is idle will the timer hit 0 and an interrupt fire.
    1480             :          */
    1481           0 :         CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE);
    1482             : 
    1483             :         /*
    1484             :          * Set a timeout in case the chip goes out to lunch.
    1485             :          */
    1486           0 :         ifp->if_timer = 5;
    1487           0 : }
    1488             : 
    1489             : int
    1490           0 : vge_init(struct ifnet *ifp)
    1491             : {
    1492           0 :         struct vge_softc        *sc = ifp->if_softc;
    1493             :         int                     i;
    1494             : 
    1495             :         /*
    1496             :          * Cancel pending I/O and free all RX/TX buffers.
    1497             :          */
    1498           0 :         vge_stop(sc);
    1499           0 :         vge_reset(sc);
    1500             : 
    1501             :         /* Initialize RX descriptors list */
    1502           0 :         if (vge_rx_list_init(sc) == ENOBUFS) {
    1503           0 :                 printf("%s: init failed: no memory for RX buffers\n",
    1504           0 :                     sc->vge_dev.dv_xname);
    1505           0 :                 vge_stop(sc);
    1506           0 :                 return (ENOBUFS);
    1507             :         }
    1508             :         /* Initialize TX descriptors */
    1509           0 :         if (vge_tx_list_init(sc) == ENOBUFS) {
    1510           0 :                 printf("%s: init failed: no memory for TX buffers\n",
    1511           0 :                     sc->vge_dev.dv_xname);
    1512           0 :                 vge_stop(sc);
    1513           0 :                 return (ENOBUFS);
    1514             :         }
    1515             : 
    1516             :         /* Set our station address */
    1517           0 :         for (i = 0; i < ETHER_ADDR_LEN; i++)
    1518           0 :                 CSR_WRITE_1(sc, VGE_PAR0 + i, sc->arpcom.ac_enaddr[i]);
    1519             : 
    1520             :         /* Set receive FIFO threshold */
    1521           0 :         CSR_CLRBIT_1(sc, VGE_RXCFG, VGE_RXCFG_FIFO_THR);
    1522           0 :         CSR_SETBIT_1(sc, VGE_RXCFG, VGE_RXFIFOTHR_128BYTES);
    1523             : 
    1524           0 :         if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) {
    1525             :                 /*
    1526             :                  * Allow transmission and reception of VLAN tagged
    1527             :                  * frames.
    1528             :                  */
    1529           0 :                 CSR_CLRBIT_1(sc, VGE_RXCFG, VGE_RXCFG_VTAGOPT);
    1530           0 :                 CSR_SETBIT_1(sc, VGE_RXCFG, VGE_VTAG_OPT2);
    1531           0 :         }
    1532             : 
    1533             :         /* Set DMA burst length */
    1534           0 :         CSR_CLRBIT_1(sc, VGE_DMACFG0, VGE_DMACFG0_BURSTLEN);
    1535           0 :         CSR_SETBIT_1(sc, VGE_DMACFG0, VGE_DMABURST_128);
    1536             : 
    1537           0 :         CSR_SETBIT_1(sc, VGE_TXCFG, VGE_TXCFG_ARB_PRIO|VGE_TXCFG_NONBLK);
    1538             : 
    1539             :         /* Set collision backoff algorithm */
    1540           0 :         CSR_CLRBIT_1(sc, VGE_CHIPCFG1, VGE_CHIPCFG1_CRANDOM|
    1541             :             VGE_CHIPCFG1_CAP|VGE_CHIPCFG1_MBA|VGE_CHIPCFG1_BAKOPT);
    1542           0 :         CSR_SETBIT_1(sc, VGE_CHIPCFG1, VGE_CHIPCFG1_OFSET);
    1543             : 
    1544             :         /* Disable LPSEL field in priority resolution */
    1545           0 :         CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_LPSEL_DIS);
    1546             : 
    1547             :         /*
    1548             :          * Load the addresses of the DMA queues into the chip.
    1549             :          * Note that we only use one transmit queue.
    1550             :          */
    1551           0 :         CSR_WRITE_4(sc, VGE_TXDESC_ADDR_LO0,
    1552             :             VGE_ADDR_LO(sc->vge_ldata.vge_tx_listseg.ds_addr));
    1553           0 :         CSR_WRITE_2(sc, VGE_TXDESCNUM, VGE_TX_DESC_CNT - 1);
    1554             : 
    1555           0 :         CSR_WRITE_4(sc, VGE_RXDESC_ADDR_LO,
    1556             :             VGE_ADDR_LO(sc->vge_ldata.vge_rx_listseg.ds_addr));
    1557           0 :         CSR_WRITE_2(sc, VGE_RXDESCNUM, VGE_RX_DESC_CNT - 1);
    1558           0 :         CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, VGE_RX_DESC_CNT);
    1559             : 
    1560             :         /* Enable and wake up the RX descriptor queue */
    1561           0 :         CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_RUN);
    1562           0 :         CSR_WRITE_1(sc, VGE_RXQCSRS, VGE_RXQCSR_WAK);
    1563             : 
    1564             :         /* Enable the TX descriptor queue */
    1565           0 :         CSR_WRITE_2(sc, VGE_TXQCSRS, VGE_TXQCSR_RUN0);
    1566             : 
    1567             :         /* Set up the receive filter -- allow large frames for VLANs. */
    1568           0 :         CSR_WRITE_1(sc, VGE_RXCTL, VGE_RXCTL_RX_GIANT);
    1569             : 
    1570             :         /* Program promiscuous mode and multicast filters. */
    1571           0 :         vge_iff(sc);
    1572             : 
    1573             :         /* Initialize pause timer. */
    1574           0 :         CSR_WRITE_2(sc, VGE_TX_PAUSE_TIMER, 0xFFFF);
    1575             :         /*
    1576             :          * Initialize flow control parameters.
    1577             :          *  TX XON high threshold : 48
    1578             :          *  TX pause low threshold : 24
    1579             :          *  Disable half-duplex flow control
    1580             :          */
    1581           0 :         CSR_WRITE_1(sc, VGE_CRC2, 0xFF);
    1582           0 :         CSR_WRITE_1(sc, VGE_CRS2, VGE_CR2_XON_ENABLE | 0x0B);
    1583             : 
    1584             :         /* Enable jumbo frame reception (if desired) */
    1585             : 
    1586             :         /* Start the MAC. */
    1587           0 :         CSR_WRITE_1(sc, VGE_CRC0, VGE_CR0_STOP);
    1588           0 :         CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_NOPOLL);
    1589           0 :         CSR_WRITE_1(sc, VGE_CRS0,
    1590             :             VGE_CR0_TX_ENABLE|VGE_CR0_RX_ENABLE|VGE_CR0_START);
    1591             : 
    1592             :         /*
    1593             :          * Configure one-shot timer for microsecond
    1594             :          * resulution and load it for 500 usecs.
    1595             :          */
    1596           0 :         CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_TIMER0_RES);
    1597           0 :         CSR_WRITE_2(sc, VGE_SSTIMER, 400);
    1598             : 
    1599             :         /*
    1600             :          * Configure interrupt moderation for receive. Enable
    1601             :          * the holdoff counter and load it, and set the RX
    1602             :          * suppression count to the number of descriptors we
    1603             :          * want to allow before triggering an interrupt.
    1604             :          * The holdoff timer is in units of 20 usecs.
    1605             :          */
    1606             : 
    1607             : #ifdef notyet
    1608             :         CSR_WRITE_1(sc, VGE_INTCTL1, VGE_INTCTL_TXINTSUP_DISABLE);
    1609             :         /* Select the interrupt holdoff timer page. */
    1610             :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
    1611             :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_INTHLDOFF);
    1612             :         CSR_WRITE_1(sc, VGE_INTHOLDOFF, 10); /* ~200 usecs */
    1613             : 
    1614             :         /* Enable use of the holdoff timer. */
    1615             :         CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_HOLDOFF);
    1616             :         CSR_WRITE_1(sc, VGE_INTCTL1, VGE_INTCTL_SC_RELOAD);
    1617             : 
    1618             :         /* Select the RX suppression threshold page. */
    1619             :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
    1620             :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_RXSUPPTHR);
    1621             :         CSR_WRITE_1(sc, VGE_RXSUPPTHR, 64); /* interrupt after 64 packets */
    1622             : 
    1623             :         /* Restore the page select bits. */
    1624             :         CSR_CLRBIT_1(sc, VGE_CAMCTL, VGE_CAMCTL_PAGESEL);
    1625             :         CSR_SETBIT_1(sc, VGE_CAMCTL, VGE_PAGESEL_MAR);
    1626             : #endif
    1627             : 
    1628             :         /*
    1629             :          * Enable interrupts.
    1630             :          */
    1631           0 :         CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS);
    1632           0 :         CSR_WRITE_4(sc, VGE_ISR, 0);
    1633           0 :         CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
    1634             : 
    1635             :         /* Restore BMCR state */
    1636           0 :         mii_mediachg(&sc->sc_mii);
    1637             : 
    1638           0 :         ifp->if_flags |= IFF_RUNNING;
    1639           0 :         ifq_clr_oactive(&ifp->if_snd);
    1640             : 
    1641           0 :         sc->vge_link = 0;
    1642             : 
    1643           0 :         if (!timeout_pending(&sc->timer_handle))
    1644           0 :                 timeout_add_sec(&sc->timer_handle, 1);
    1645             : 
    1646           0 :         return (0);
    1647           0 : }
    1648             : 
    1649             : /*
    1650             :  * Set media options.
    1651             :  */
    1652             : int
    1653           0 : vge_ifmedia_upd(struct ifnet *ifp)
    1654             : {
    1655           0 :         struct vge_softc *sc = ifp->if_softc;
    1656             : 
    1657           0 :         return (mii_mediachg(&sc->sc_mii));
    1658             : }
    1659             : 
    1660             : /*
    1661             :  * Report current media status.
    1662             :  */
    1663             : void
    1664           0 : vge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
    1665             : {
    1666           0 :         struct vge_softc *sc = ifp->if_softc;
    1667             : 
    1668           0 :         mii_pollstat(&sc->sc_mii);
    1669           0 :         ifmr->ifm_active = sc->sc_mii.mii_media_active;
    1670           0 :         ifmr->ifm_status = sc->sc_mii.mii_media_status;
    1671           0 : }
    1672             : 
    1673             : void
    1674           0 : vge_miibus_statchg(struct device *dev)
    1675             : {
    1676           0 :         struct vge_softc        *sc = (struct vge_softc *)dev;
    1677             :         struct mii_data         *mii;
    1678             :         struct ifmedia_entry    *ife;
    1679             : 
    1680           0 :         mii = &sc->sc_mii;
    1681           0 :         ife = mii->mii_media.ifm_cur;
    1682             : 
    1683             :         /*
    1684             :          * If the user manually selects a media mode, we need to turn
    1685             :          * on the forced MAC mode bit in the DIAGCTL register. If the
    1686             :          * user happens to choose a full duplex mode, we also need to
    1687             :          * set the 'force full duplex' bit. This applies only to
    1688             :          * 10Mbps and 100Mbps speeds. In autoselect mode, forced MAC
    1689             :          * mode is disabled, and in 1000baseT mode, full duplex is
    1690             :          * always implied, so we turn on the forced mode bit but leave
    1691             :          * the FDX bit cleared.
    1692             :          */
    1693             : 
    1694           0 :         switch (IFM_SUBTYPE(ife->ifm_media)) {
    1695             :         case IFM_AUTO:
    1696           0 :                 CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
    1697           0 :                 CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
    1698           0 :                 break;
    1699             :         case IFM_1000_T:
    1700           0 :                 CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
    1701           0 :                 CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
    1702           0 :                 break;
    1703             :         case IFM_100_TX:
    1704             :         case IFM_10_T:
    1705           0 :                 CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE);
    1706           0 :                 if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
    1707           0 :                         CSR_SETBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
    1708           0 :                 } else {
    1709           0 :                         CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE);
    1710             :                 }
    1711             :                 break;
    1712             :         default:
    1713           0 :                 printf("%s: unknown media type: %llx\n",
    1714           0 :                     sc->vge_dev.dv_xname, IFM_SUBTYPE(ife->ifm_media));
    1715           0 :                 break;
    1716             :         }
    1717             : 
    1718             :         /*
    1719             :          * 802.3x flow control
    1720             :         */
    1721           0 :         CSR_WRITE_1(sc, VGE_CRC2, VGE_CR2_FDX_TXFLOWCTL_ENABLE |
    1722             :             VGE_CR2_FDX_RXFLOWCTL_ENABLE);
    1723           0 :         if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
    1724           0 :                 CSR_WRITE_1(sc, VGE_CRS2, VGE_CR2_FDX_TXFLOWCTL_ENABLE);
    1725           0 :         if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
    1726           0 :                 CSR_WRITE_1(sc, VGE_CRS2, VGE_CR2_FDX_RXFLOWCTL_ENABLE);
    1727           0 : }
    1728             : 
    1729             : int
    1730           0 : vge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
    1731             : {
    1732           0 :         struct vge_softc        *sc = ifp->if_softc;
    1733           0 :         struct ifreq            *ifr = (struct ifreq *) data;
    1734             :         int                     s, error = 0;
    1735             : 
    1736           0 :         s = splnet();
    1737             : 
    1738           0 :         switch (command) {
    1739             :         case SIOCSIFADDR:
    1740           0 :                 ifp->if_flags |= IFF_UP;
    1741           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
    1742           0 :                         vge_init(ifp);
    1743             :                 break;
    1744             : 
    1745             :         case SIOCSIFFLAGS:
    1746           0 :                 if (ifp->if_flags & IFF_UP) {
    1747           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1748           0 :                                 error = ENETRESET;
    1749             :                         else
    1750           0 :                                 vge_init(ifp);
    1751             :                 } else {
    1752           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1753           0 :                                 vge_stop(sc);
    1754             :                 }
    1755             :                 break;
    1756             : 
    1757             :         case SIOCGIFMEDIA:
    1758             :         case SIOCSIFMEDIA:
    1759           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
    1760           0 :                 break;
    1761             : 
    1762             :         default:
    1763           0 :                 error = ether_ioctl(ifp, &sc->arpcom, command, data);
    1764           0 :         }
    1765             : 
    1766           0 :         if (error == ENETRESET) {
    1767           0 :                 if (ifp->if_flags & IFF_RUNNING)
    1768           0 :                         vge_iff(sc);
    1769             :                 error = 0;
    1770           0 :         }
    1771             : 
    1772           0 :         splx(s);
    1773           0 :         return (error);
    1774             : }
    1775             : 
    1776             : void
    1777           0 : vge_watchdog(struct ifnet *ifp)
    1778             : {
    1779           0 :         struct vge_softc *sc = ifp->if_softc;
    1780             :         int s;
    1781             : 
    1782           0 :         s = splnet();
    1783           0 :         printf("%s: watchdog timeout\n", sc->vge_dev.dv_xname);
    1784           0 :         ifp->if_oerrors++;
    1785             : 
    1786           0 :         vge_txeof(sc);
    1787           0 :         vge_rxeof(sc);
    1788             : 
    1789           0 :         vge_init(ifp);
    1790             : 
    1791           0 :         splx(s);
    1792           0 : }
    1793             : 
    1794             : /*
    1795             :  * Stop the adapter and free any mbufs allocated to the
    1796             :  * RX and TX lists.
    1797             :  */
    1798             : void
    1799           0 : vge_stop(struct vge_softc *sc)
    1800             : {
    1801             :         int                     i;
    1802             :         struct ifnet            *ifp;
    1803             : 
    1804           0 :         ifp = &sc->arpcom.ac_if;
    1805           0 :         ifp->if_timer = 0;
    1806             : 
    1807           0 :         timeout_del(&sc->timer_handle);
    1808             : 
    1809           0 :         ifp->if_flags &= ~IFF_RUNNING;
    1810           0 :         ifq_clr_oactive(&ifp->if_snd);
    1811             : 
    1812           0 :         CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK);
    1813           0 :         CSR_WRITE_1(sc, VGE_CRS0, VGE_CR0_STOP);
    1814           0 :         CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF);
    1815           0 :         CSR_WRITE_2(sc, VGE_TXQCSRC, 0xFFFF);
    1816           0 :         CSR_WRITE_1(sc, VGE_RXQCSRC, 0xFF);
    1817           0 :         CSR_WRITE_4(sc, VGE_RXDESC_ADDR_LO, 0);
    1818             : 
    1819           0 :         if (sc->vge_head != NULL) {
    1820           0 :                 m_freem(sc->vge_head);
    1821           0 :                 sc->vge_head = sc->vge_tail = NULL;
    1822           0 :         }
    1823             : 
    1824             :         /* Free the TX list buffers. */
    1825           0 :         for (i = 0; i < VGE_TX_DESC_CNT; i++) {
    1826           0 :                 if (sc->vge_ldata.vge_tx_mbuf[i] != NULL) {
    1827           0 :                         bus_dmamap_unload(sc->sc_dmat,
    1828             :                             sc->vge_ldata.vge_tx_dmamap[i]);
    1829           0 :                         m_freem(sc->vge_ldata.vge_tx_mbuf[i]);
    1830           0 :                         sc->vge_ldata.vge_tx_mbuf[i] = NULL;
    1831           0 :                 }
    1832             :         }
    1833             : 
    1834             :         /* Free the RX list buffers. */
    1835           0 :         for (i = 0; i < VGE_RX_DESC_CNT; i++) {
    1836           0 :                 if (sc->vge_ldata.vge_rx_mbuf[i] != NULL) {
    1837           0 :                         bus_dmamap_unload(sc->sc_dmat,
    1838             :                             sc->vge_ldata.vge_rx_dmamap[i]);
    1839           0 :                         m_freem(sc->vge_ldata.vge_rx_mbuf[i]);
    1840           0 :                         sc->vge_ldata.vge_rx_mbuf[i] = NULL;
    1841           0 :                 }
    1842             :         }
    1843           0 : }

Generated by: LCOV version 1.13