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

          Line data    Source code
       1             : /*      $OpenBSD: fxp.c,v 1.131 2017/01/22 10:17:38 dlg Exp $   */
       2             : /*      $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $       */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1995, David Greenman
       6             :  * All rights reserved.
       7             :  *
       8             :  * Modifications to support NetBSD:
       9             :  * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
      10             :  *
      11             :  * Redistribution and use in source and binary forms, with or without
      12             :  * modification, are permitted provided that the following conditions
      13             :  * are met:
      14             :  * 1. Redistributions of source code must retain the above copyright
      15             :  *    notice unmodified, this list of conditions, and the following
      16             :  *    disclaimer.
      17             :  * 2. Redistributions in binary form must reproduce the above copyright
      18             :  *    notice, this list of conditions and the following disclaimer in the
      19             :  *    documentation and/or other materials provided with the distribution.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  *
      33             :  *      Id: if_fxp.c,v 1.55 1998/08/04 08:53:12 dg Exp
      34             :  */
      35             : 
      36             : /*
      37             :  * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
      38             :  */
      39             : 
      40             : #include "bpfilter.h"
      41             : 
      42             : #include <sys/param.h>
      43             : #include <sys/systm.h>
      44             : #include <sys/mbuf.h>
      45             : #include <sys/malloc.h>
      46             : #include <sys/kernel.h>
      47             : #include <sys/socket.h>
      48             : #include <sys/syslog.h>
      49             : #include <sys/timeout.h>
      50             : 
      51             : #include <net/if.h>
      52             : #include <net/if_media.h>
      53             : 
      54             : #include <netinet/in.h>
      55             : 
      56             : #if NBPFILTER > 0
      57             : #include <net/bpf.h>
      58             : #endif
      59             : 
      60             : #include <sys/ioctl.h>
      61             : #include <sys/errno.h>
      62             : #include <sys/device.h>
      63             : 
      64             : #include <netinet/if_ether.h>
      65             : 
      66             : #include <machine/cpu.h>
      67             : #include <machine/bus.h>
      68             : #include <machine/intr.h>
      69             : 
      70             : #include <dev/mii/miivar.h>
      71             : 
      72             : #include <dev/ic/fxpreg.h>
      73             : #include <dev/ic/fxpvar.h>
      74             : 
      75             : /*
      76             :  * NOTE!  On the Alpha, we have an alignment constraint.  The
      77             :  * card DMAs the packet immediately following the RFA.  However,
      78             :  * the first thing in the packet is a 14-byte Ethernet header.
      79             :  * This means that the packet is misaligned.  To compensate,
      80             :  * we actually offset the RFA 2 bytes into the cluster.  This
      81             :  * aligns the packet after the Ethernet header at a 32-bit
      82             :  * boundary.  HOWEVER!  This means that the RFA is misaligned!
      83             :  */
      84             : #define RFA_ALIGNMENT_FUDGE     (2 + sizeof(bus_dmamap_t *))
      85             : 
      86             : /*
      87             :  * Inline function to copy a 16-bit aligned 32-bit quantity.
      88             :  */
      89             : static __inline void fxp_lwcopy(volatile u_int32_t *,
      90             :         volatile u_int32_t *);
      91             : 
      92             : static __inline void
      93           0 : fxp_lwcopy(volatile u_int32_t *src, volatile u_int32_t *dst)
      94             : {
      95           0 :         volatile u_int16_t *a = (u_int16_t *)src;
      96           0 :         volatile u_int16_t *b = (u_int16_t *)dst;
      97             : 
      98           0 :         b[0] = a[0];
      99           0 :         b[1] = a[1];
     100           0 : }
     101             : 
     102             : /*
     103             :  * Template for default configuration parameters.
     104             :  * See struct fxp_cb_config for the bit definitions.
     105             :  * Note, cb_command is filled in later.
     106             :  */
     107             : static u_char fxp_cb_config_template[] = {
     108             :         0x0, 0x0,               /* cb_status */
     109             :         0x0, 0x0,               /* cb_command */
     110             :         0xff, 0xff, 0xff, 0xff, /* link_addr */
     111             :         0x16,   /*  0 Byte count. */
     112             :         0x08,   /*  1 Fifo limit */
     113             :         0x00,   /*  2 Adaptive ifs */
     114             :         0x00,   /*  3 ctrl0 */
     115             :         0x00,   /*  4 rx_dma_bytecount */
     116             :         0x80,   /*  5 tx_dma_bytecount */
     117             :         0xb2,   /*  6 ctrl 1*/
     118             :         0x03,   /*  7 ctrl 2*/
     119             :         0x01,   /*  8 mediatype */
     120             :         0x00,   /*  9 void2 */
     121             :         0x26,   /* 10 ctrl3 */
     122             :         0x00,   /* 11 linear priority */
     123             :         0x60,   /* 12 interfrm_spacing */
     124             :         0x00,   /* 13 void31 */
     125             :         0xf2,   /* 14 void32 */
     126             :         0x48,   /* 15 promiscuous */
     127             :         0x00,   /* 16 void41 */
     128             :         0x40,   /* 17 void42 */
     129             :         0xf3,   /* 18 stripping */
     130             :         0x00,   /* 19 fdx_pin */
     131             :         0x3f,   /* 20 multi_ia */
     132             :         0x05    /* 21 mc_all */
     133             : };
     134             : 
     135             : void fxp_eeprom_shiftin(struct fxp_softc *, int, int);
     136             : void fxp_eeprom_putword(struct fxp_softc *, int, u_int16_t);
     137             : void fxp_write_eeprom(struct fxp_softc *, u_short *, int, int);
     138             : int fxp_mediachange(struct ifnet *);
     139             : void fxp_mediastatus(struct ifnet *, struct ifmediareq *);
     140             : void fxp_scb_wait(struct fxp_softc *);
     141             : void fxp_start(struct ifnet *);
     142             : int fxp_ioctl(struct ifnet *, u_long, caddr_t);
     143             : void fxp_load_ucode(struct fxp_softc *);
     144             : void fxp_watchdog(struct ifnet *);
     145             : int fxp_add_rfabuf(struct fxp_softc *, struct mbuf *);
     146             : int fxp_mdi_read(struct device *, int, int);
     147             : void fxp_mdi_write(struct device *, int, int, int);
     148             : void fxp_autosize_eeprom(struct fxp_softc *);
     149             : void fxp_statchg(struct device *);
     150             : void fxp_read_eeprom(struct fxp_softc *, u_int16_t *,
     151             :                                     int, int);
     152             : void fxp_stats_update(void *);
     153             : void fxp_mc_setup(struct fxp_softc *, int);
     154             : void fxp_scb_cmd(struct fxp_softc *, u_int16_t);
     155             : 
     156             : /*
     157             :  * Set initial transmit threshold at 64 (512 bytes). This is
     158             :  * increased by 64 (512 bytes) at a time, to maximum of 192
     159             :  * (1536 bytes), if an underrun occurs.
     160             :  */
     161             : static int tx_threshold = 64;
     162             : 
     163             : /*
     164             :  * Interrupts coalescing code params
     165             :  */
     166             : int fxp_int_delay = FXP_INT_DELAY;
     167             : int fxp_bundle_max = FXP_BUNDLE_MAX;
     168             : int fxp_min_size_mask = FXP_MIN_SIZE_MASK;
     169             : 
     170             : /*
     171             :  * TxCB list index mask. This is used to do list wrap-around.
     172             :  */
     173             : #define FXP_TXCB_MASK   (FXP_NTXCB - 1)
     174             : 
     175             : /*
     176             :  * Maximum number of seconds that the receiver can be idle before we
     177             :  * assume it's dead and attempt to reset it by reprogramming the
     178             :  * multicast filter. This is part of a work-around for a bug in the
     179             :  * NIC. See fxp_stats_update().
     180             :  */
     181             : #define FXP_MAX_RX_IDLE 15
     182             : 
     183             : /*
     184             :  * Wait for the previous command to be accepted (but not necessarily
     185             :  * completed).
     186             :  */
     187             : void
     188           0 : fxp_scb_wait(struct fxp_softc *sc)
     189             : {
     190             :         int i = FXP_CMD_TMO;
     191             : 
     192           0 :         while ((CSR_READ_2(sc, FXP_CSR_SCB_COMMAND) & 0xff) && --i)
     193           0 :                 DELAY(2);
     194           0 :         if (i == 0)
     195           0 :                 printf("%s: warning: SCB timed out\n", sc->sc_dev.dv_xname);
     196           0 : }
     197             : 
     198             : void
     199           0 : fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length)
     200             : {
     201             :         u_int16_t reg;
     202             :         int x;
     203             : 
     204             :         /*
     205             :          * Shift in data.
     206             :          */
     207           0 :         for (x = 1 << (length - 1); x; x >>= 1) {
     208           0 :                 if (data & x)
     209           0 :                         reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
     210             :                 else
     211             :                         reg = FXP_EEPROM_EECS;
     212           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     213           0 :                 DELAY(1);
     214           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
     215           0 :                 DELAY(1);
     216           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     217           0 :                 DELAY(1);
     218             :         }
     219           0 : }
     220             : 
     221             : void
     222           0 : fxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data)
     223             : {
     224             :         int i;
     225             : 
     226             :         /*
     227             :          * Erase/write enable.
     228             :          */
     229           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     230           0 :         fxp_eeprom_shiftin(sc, 0x4, 3);
     231           0 :         fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size);
     232           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     233           0 :         DELAY(1);
     234             :         /*
     235             :          * Shift in write opcode, address, data.
     236             :          */
     237           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     238           0 :         fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
     239           0 :         fxp_eeprom_shiftin(sc, offset, sc->eeprom_size);
     240           0 :         fxp_eeprom_shiftin(sc, data, 16);
     241           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     242           0 :         DELAY(1);
     243             :         /*
     244             :          * Wait for EEPROM to finish up.
     245             :          */
     246           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     247           0 :         DELAY(1);
     248           0 :         for (i = 0; i < 1000; i++) {
     249           0 :                 if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
     250             :                         break;
     251           0 :                 DELAY(50);
     252             :         }
     253           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     254           0 :         DELAY(1);
     255             :         /*
     256             :          * Erase/write disable.
     257             :          */
     258           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     259           0 :         fxp_eeprom_shiftin(sc, 0x4, 3);
     260           0 :         fxp_eeprom_shiftin(sc, 0, sc->eeprom_size);
     261           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     262           0 :         DELAY(1);
     263           0 : }
     264             : 
     265             : void
     266           0 : fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
     267             : {
     268             :         int i;
     269             : 
     270           0 :         for (i = 0; i < words; i++)
     271           0 :                 fxp_eeprom_putword(sc, offset + i, data[i]);
     272           0 : }
     273             : 
     274             : /*************************************************************
     275             :  * Operating system-specific autoconfiguration glue
     276             :  *************************************************************/
     277             : 
     278             : struct cfdriver fxp_cd = {
     279             :         NULL, "fxp", DV_IFNET
     280             : };
     281             : 
     282             : int
     283           0 : fxp_activate(struct device *self, int act)
     284             : {
     285           0 :         struct fxp_softc *sc = (struct fxp_softc *)self;
     286           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;        
     287             :         int rv = 0;
     288             : 
     289           0 :         switch (act) {
     290             :         case DVACT_SUSPEND:
     291           0 :                 if (ifp->if_flags & IFF_RUNNING)
     292           0 :                         fxp_stop(sc, 1, 0);
     293           0 :                 rv = config_activate_children(self, act);
     294           0 :                 break;
     295             :         case DVACT_WAKEUP:
     296           0 :                 if (ifp->if_flags & IFF_UP)
     297           0 :                         fxp_wakeup(sc);
     298             :                 break;
     299             :         default:
     300           0 :                 rv = config_activate_children(self, act);
     301           0 :                 break;
     302             :         }
     303           0 :         return (rv);
     304             : }
     305             : 
     306             : void
     307           0 : fxp_wakeup(struct fxp_softc *sc)
     308             : {
     309           0 :         int s = splnet();
     310             : 
     311             :         /* force reload of the microcode */
     312           0 :         sc->sc_flags &= ~FXPF_UCODELOADED;
     313             : 
     314           0 :         fxp_init(sc);
     315           0 :         splx(s);
     316           0 : }
     317             : 
     318             : /*************************************************************
     319             :  * End of operating system-specific autoconfiguration glue
     320             :  *************************************************************/
     321             : 
     322             : /*
     323             :  * Do generic parts of attach.
     324             :  */
     325             : int
     326           0 : fxp_attach(struct fxp_softc *sc, const char *intrstr)
     327             : {
     328             :         struct ifnet *ifp;
     329             :         struct mbuf *m;
     330             :         bus_dmamap_t rxmap;
     331           0 :         u_int16_t data;
     332           0 :         u_int8_t enaddr[6];
     333             :         int i, err;
     334             : 
     335             :         /*
     336             :          * Reset to a stable state.
     337             :          */
     338           0 :         CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
     339           0 :         DELAY(10);
     340             : 
     341           0 :         if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct fxp_ctrl),
     342             :             PAGE_SIZE, 0, &sc->sc_cb_seg, 1, &sc->sc_cb_nseg,
     343             :             BUS_DMA_NOWAIT | BUS_DMA_ZERO))
     344             :                 goto fail;
     345           0 :         if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg,
     346             :             sizeof(struct fxp_ctrl), (caddr_t *)&sc->sc_ctrl,
     347             :             BUS_DMA_NOWAIT)) {
     348           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
     349           0 :                 goto fail;
     350             :         }
     351           0 :         if (bus_dmamap_create(sc->sc_dmat, sizeof(struct fxp_ctrl),
     352             :             1, sizeof(struct fxp_ctrl), 0, BUS_DMA_NOWAIT,
     353             :             &sc->tx_cb_map)) {
     354           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
     355             :                     sizeof(struct fxp_ctrl));
     356           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
     357           0 :                 goto fail;
     358             :         }
     359           0 :         if (bus_dmamap_load(sc->sc_dmat, sc->tx_cb_map, (caddr_t)sc->sc_ctrl,
     360             :             sizeof(struct fxp_ctrl), NULL, BUS_DMA_NOWAIT)) {
     361           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
     362           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
     363             :                     sizeof(struct fxp_ctrl));
     364           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
     365           0 :                 goto fail;
     366             :         }
     367             : 
     368           0 :         for (i = 0; i < FXP_NTXCB; i++) {
     369           0 :                 if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
     370           0 :                     FXP_NTXSEG, MCLBYTES, 0, 0, &sc->txs[i].tx_map)) != 0) {
     371           0 :                         printf("%s: unable to create tx dma map %d, error %d\n",
     372           0 :                             sc->sc_dev.dv_xname, i, err);
     373           0 :                         goto fail;
     374             :                 }
     375           0 :                 sc->txs[i].tx_mbuf = NULL;
     376           0 :                 sc->txs[i].tx_cb = sc->sc_ctrl->tx_cb + i;
     377           0 :                 sc->txs[i].tx_off = offsetof(struct fxp_ctrl, tx_cb[i]);
     378           0 :                 sc->txs[i].tx_next = &sc->txs[(i + 1) & FXP_TXCB_MASK];
     379             :         }
     380             : 
     381             :         /*
     382             :          * Pre-allocate some receive buffers.
     383             :          */
     384           0 :         sc->sc_rxfree = 0;
     385           0 :         for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
     386           0 :                 if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
     387           0 :                     MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
     388           0 :                         printf("%s: unable to create rx dma map %d, error %d\n",
     389           0 :                             sc->sc_dev.dv_xname, i, err);
     390           0 :                         goto fail;
     391             :                 }
     392           0 :                 sc->rx_bufs++;
     393             :         }
     394           0 :         for (i = 0; i < FXP_NRFABUFS_MIN; i++)
     395           0 :                 if (fxp_add_rfabuf(sc, NULL) != 0)
     396             :                         goto fail;
     397             : 
     398             :         /*
     399             :          * Find out how large of an SEEPROM we have.
     400             :          */
     401           0 :         fxp_autosize_eeprom(sc);
     402             : 
     403             :         /*
     404             :          * Get info about the primary PHY
     405             :          */
     406           0 :         fxp_read_eeprom(sc, (u_int16_t *)&data, FXP_EEPROM_REG_PHY, 1);
     407           0 :         sc->phy_primary_addr = data & 0xff;
     408           0 :         sc->phy_primary_device = (data >> 8) & 0x3f;
     409           0 :         sc->phy_10Mbps_only = data >> 15;
     410             : 
     411             :         /*
     412             :          * Only 82558 and newer cards can do this.
     413             :          */
     414           0 :         if (sc->sc_revision >= FXP_REV_82558_A4) {
     415           0 :                 sc->sc_int_delay = fxp_int_delay;
     416           0 :                 sc->sc_bundle_max = fxp_bundle_max;
     417           0 :                 sc->sc_min_size_mask = fxp_min_size_mask;
     418           0 :         }
     419             :         /*
     420             :          * Read MAC address.
     421             :          */
     422           0 :         fxp_read_eeprom(sc, (u_int16_t *)enaddr, FXP_EEPROM_REG_MAC, 3);
     423             : 
     424           0 :         ifp = &sc->sc_arpcom.ac_if;
     425           0 :         bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
     426           0 :         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
     427           0 :         ifp->if_softc = sc;
     428           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     429           0 :         ifp->if_ioctl = fxp_ioctl;
     430           0 :         ifp->if_start = fxp_start;
     431           0 :         ifp->if_watchdog = fxp_watchdog;
     432           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, FXP_NTXCB - 1);
     433             : 
     434           0 :         ifp->if_capabilities = IFCAP_VLAN_MTU;
     435             : 
     436           0 :         printf(": %s, address %s\n", intrstr,
     437           0 :             ether_sprintf(sc->sc_arpcom.ac_enaddr));
     438             : 
     439           0 :         if (sc->sc_flags & FXPF_DISABLE_STANDBY) {
     440           0 :                 fxp_read_eeprom(sc, &data, FXP_EEPROM_REG_ID, 1);
     441           0 :                 if (data & FXP_EEPROM_REG_ID_STB) {
     442           0 :                         u_int16_t cksum;
     443             : 
     444           0 :                         printf("%s: Disabling dynamic standby mode in EEPROM",
     445             :                             sc->sc_dev.dv_xname);
     446           0 :                         data &= ~FXP_EEPROM_REG_ID_STB;
     447           0 :                         fxp_write_eeprom(sc, &data, FXP_EEPROM_REG_ID, 1);
     448           0 :                         printf(", New ID 0x%x", data);
     449           0 :                         cksum = 0;
     450           0 :                         for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
     451           0 :                                 fxp_read_eeprom(sc, &data, i, 1);
     452           0 :                                 cksum += data;
     453             :                         }
     454             :                         i = (1 << sc->eeprom_size) - 1;
     455           0 :                         cksum = 0xBABA - cksum;
     456           0 :                         fxp_read_eeprom(sc, &data, i, 1);
     457           0 :                         fxp_write_eeprom(sc, &cksum, i, 1);
     458           0 :                         printf(", cksum @ 0x%x: 0x%x -> 0x%x\n",
     459           0 :                             i, data, cksum);
     460           0 :                 }
     461             :         }
     462             : 
     463             :         /* Receiver lock-up workaround detection. */
     464           0 :         fxp_read_eeprom(sc, &data, FXP_EEPROM_REG_COMPAT, 1);
     465           0 :         if ((data & (FXP_EEPROM_REG_COMPAT_MC10|FXP_EEPROM_REG_COMPAT_MC100))
     466           0 :             != (FXP_EEPROM_REG_COMPAT_MC10|FXP_EEPROM_REG_COMPAT_MC100))
     467           0 :                 sc->sc_flags |= FXPF_RECV_WORKAROUND;
     468             : 
     469             :         /*
     470             :          * Initialize our media structures and probe the MII.
     471             :          */
     472           0 :         sc->sc_mii.mii_ifp = ifp;
     473           0 :         sc->sc_mii.mii_readreg = fxp_mdi_read;
     474           0 :         sc->sc_mii.mii_writereg = fxp_mdi_write;
     475           0 :         sc->sc_mii.mii_statchg = fxp_statchg;
     476           0 :         ifmedia_init(&sc->sc_mii.mii_media, 0, fxp_mediachange,
     477             :             fxp_mediastatus);
     478           0 :         mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
     479             :             MII_OFFSET_ANY, MIIF_NOISOLATE);
     480             :         /* If no phy found, just use auto mode */
     481           0 :         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
     482           0 :                 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
     483             :                     0, NULL);
     484           0 :                 printf("%s: no phy found, using manual mode\n",
     485             :                     sc->sc_dev.dv_xname);
     486           0 :         }
     487             : 
     488           0 :         if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL, 0))
     489           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
     490           0 :         else if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0))
     491           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
     492             :         else
     493           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_10_T);
     494             : 
     495             :         /*
     496             :          * Attach the interface.
     497             :          */
     498           0 :         if_attach(ifp);
     499           0 :         ether_ifattach(ifp);
     500             : 
     501             :         /*
     502             :          * Initialize timeout for statistics update.
     503             :          */
     504           0 :         timeout_set(&sc->stats_update_to, fxp_stats_update, sc);
     505             : 
     506           0 :         return (0);
     507             : 
     508             :  fail:
     509           0 :         printf("%s: Failed to malloc memory\n", sc->sc_dev.dv_xname);
     510           0 :         if (sc->tx_cb_map != NULL) {
     511           0 :                 bus_dmamap_unload(sc->sc_dmat, sc->tx_cb_map);
     512           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
     513           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
     514             :                     sizeof(struct fxp_cb_tx) * FXP_NTXCB);
     515           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
     516           0 :         }
     517           0 :         m = sc->rfa_headm;
     518           0 :         while (m != NULL) {
     519           0 :                 rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
     520           0 :                 bus_dmamap_unload(sc->sc_dmat, rxmap);
     521           0 :                 FXP_RXMAP_PUT(sc, rxmap);
     522           0 :                 m = m_free(m);
     523             :         }
     524           0 :         return (ENOMEM);
     525           0 : }
     526             : 
     527             : /*
     528             :  * From NetBSD:
     529             :  *
     530             :  * Figure out EEPROM size.
     531             :  *
     532             :  * 559's can have either 64-word or 256-word EEPROMs, the 558
     533             :  * datasheet only talks about 64-word EEPROMs, and the 557 datasheet
     534             :  * talks about the existence of 16 to 256 word EEPROMs.
     535             :  *
     536             :  * The only known sizes are 64 and 256, where the 256 version is used
     537             :  * by CardBus cards to store CIS information.
     538             :  *
     539             :  * The address is shifted in msb-to-lsb, and after the last
     540             :  * address-bit the EEPROM is supposed to output a `dummy zero' bit,
     541             :  * after which follows the actual data. We try to detect this zero, by
     542             :  * probing the data-out bit in the EEPROM control register just after
     543             :  * having shifted in a bit. If the bit is zero, we assume we've
     544             :  * shifted enough address bits. The data-out should be tri-state,
     545             :  * before this, which should translate to a logical one.
     546             :  *
     547             :  * Other ways to do this would be to try to read a register with known
     548             :  * contents with a varying number of address bits, but no such
     549             :  * register seem to be available. The high bits of register 10 are 01
     550             :  * on the 558 and 559, but apparently not on the 557.
     551             :  *
     552             :  * The Linux driver computes a checksum on the EEPROM data, but the
     553             :  * value of this checksum is not very well documented.
     554             :  */
     555             : void
     556           0 : fxp_autosize_eeprom(struct fxp_softc *sc)
     557             : {
     558             :         u_int16_t reg;
     559             :         int x;
     560             : 
     561           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     562             :         /*
     563             :          * Shift in read opcode.
     564             :          */
     565           0 :         for (x = 3; x > 0; x--) {
     566           0 :                 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
     567             :                         reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
     568           0 :                 } else {
     569             :                         reg = FXP_EEPROM_EECS;
     570             :                 }
     571           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     572           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
     573             :                     reg | FXP_EEPROM_EESK);
     574           0 :                 DELAY(4);
     575           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     576           0 :                 DELAY(4);
     577             :         }
     578             :         /*
     579             :          * Shift in address.
     580             :          * Wait for the dummy zero following a correct address shift.
     581             :          */
     582           0 :         for (x = 1; x <= 8; x++) {
     583           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     584           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
     585             :                         FXP_EEPROM_EECS | FXP_EEPROM_EESK);
     586           0 :                 DELAY(4);
     587           0 :                 if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) == 0)
     588             :                         break;
     589           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     590           0 :                 DELAY(4);
     591             :         }
     592           0 :         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     593           0 :         DELAY(4);
     594           0 :         sc->eeprom_size = x;
     595           0 : }
     596             : 
     597             : /*
     598             :  * Read from the serial EEPROM. Basically, you manually shift in
     599             :  * the read opcode (one bit at a time) and then shift in the address,
     600             :  * and then you shift out the data (all of this one bit at a time).
     601             :  * The word size is 16 bits, so you have to provide the address for
     602             :  * every 16 bits of data.
     603             :  */
     604             : void
     605           0 : fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset,
     606             :     int words)
     607             : {
     608             :         u_int16_t reg;
     609             :         int i, x;
     610             : 
     611           0 :         for (i = 0; i < words; i++) {
     612           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
     613             :                 /*
     614             :                  * Shift in read opcode.
     615             :                  */
     616           0 :                 for (x = 3; x > 0; x--) {
     617           0 :                         if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
     618             :                                 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
     619           0 :                         } else {
     620             :                                 reg = FXP_EEPROM_EECS;
     621             :                         }
     622           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     623           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
     624             :                             reg | FXP_EEPROM_EESK);
     625           0 :                         DELAY(4);
     626           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     627           0 :                         DELAY(4);
     628             :                 }
     629             :                 /*
     630             :                  * Shift in address.
     631             :                  */
     632           0 :                 for (x = sc->eeprom_size; x > 0; x--) {
     633           0 :                         if ((i + offset) & (1 << (x - 1))) {
     634             :                                 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
     635           0 :                         } else {
     636             :                                 reg = FXP_EEPROM_EECS;
     637             :                         }
     638           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     639           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
     640             :                             reg | FXP_EEPROM_EESK);
     641           0 :                         DELAY(4);
     642           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     643           0 :                         DELAY(4);
     644             :                 }
     645             :                 reg = FXP_EEPROM_EECS;
     646           0 :                 data[i] = 0;
     647             :                 /*
     648             :                  * Shift out data.
     649             :                  */
     650           0 :                 for (x = 16; x > 0; x--) {
     651           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
     652             :                             reg | FXP_EEPROM_EESK);
     653           0 :                         DELAY(4);
     654           0 :                         if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) &
     655             :                             FXP_EEPROM_EEDO)
     656           0 :                                 data[i] |= (1 << (x - 1));
     657           0 :                         CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
     658           0 :                         DELAY(4);
     659             :                 }
     660           0 :                 data[i] = letoh16(data[i]);
     661           0 :                 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
     662           0 :                 DELAY(4);
     663             :         }
     664           0 : }
     665             : 
     666             : /*
     667             :  * Start packet transmission on the interface.
     668             :  */
     669             : void
     670           0 : fxp_start(struct ifnet *ifp)
     671             : {
     672           0 :         struct fxp_softc *sc = ifp->if_softc;
     673           0 :         struct fxp_txsw *txs = sc->sc_cbt_prod;
     674             :         struct fxp_cb_tx *txc;
     675             :         struct mbuf *m0;
     676           0 :         int cnt = sc->sc_cbt_cnt, seg, error;
     677             : 
     678           0 :         if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
     679           0 :                 return;
     680             : 
     681           0 :         while (1) {
     682           0 :                 if (cnt >= (FXP_NTXCB - 2)) {
     683           0 :                         ifq_set_oactive(&ifp->if_snd);
     684           0 :                         break;
     685             :                 }
     686             : 
     687           0 :                 txs = txs->tx_next;
     688             : 
     689           0 :                 m0 = ifq_dequeue(&ifp->if_snd);
     690           0 :                 if (m0 == NULL)
     691             :                         break;
     692             : 
     693           0 :                 error = bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
     694             :                     m0, BUS_DMA_NOWAIT);
     695           0 :                 switch (error) {
     696             :                 case 0:
     697             :                         break;
     698             :                 case EFBIG:
     699           0 :                         if (m_defrag(m0, M_DONTWAIT) == 0 &&
     700           0 :                             bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
     701           0 :                             m0, BUS_DMA_NOWAIT) == 0)
     702             :                                 break;
     703             :                         /* FALLTHROUGH */
     704             :                 default:
     705           0 :                         ifp->if_oerrors++;
     706           0 :                         m_freem(m0);
     707             :                         /* try next packet */
     708           0 :                         continue;
     709             :                 }
     710             : 
     711           0 :                 txs->tx_mbuf = m0;
     712             : 
     713             : #if NBPFILTER > 0
     714           0 :                 if (ifp->if_bpf)
     715           0 :                         bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
     716             : #endif
     717             : 
     718           0 :                 FXP_MBUF_SYNC(sc, txs->tx_map, BUS_DMASYNC_PREWRITE);
     719             : 
     720           0 :                 txc = txs->tx_cb;
     721           0 :                 txc->tbd_number = txs->tx_map->dm_nsegs;
     722           0 :                 txc->cb_status = 0;
     723           0 :                 txc->cb_command = htole16(FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF);
     724           0 :                 txc->tx_threshold = tx_threshold;
     725           0 :                 for (seg = 0; seg < txs->tx_map->dm_nsegs; seg++) {
     726           0 :                         txc->tbd[seg].tb_addr =
     727           0 :                             htole32(txs->tx_map->dm_segs[seg].ds_addr);
     728           0 :                         txc->tbd[seg].tb_size =
     729           0 :                             htole32(txs->tx_map->dm_segs[seg].ds_len);
     730             :                 }
     731           0 :                 FXP_TXCB_SYNC(sc, txs,
     732             :                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     733             : 
     734           0 :                 ++cnt;
     735           0 :                 sc->sc_cbt_prod = txs;
     736             :         }
     737             : 
     738           0 :         if (cnt != sc->sc_cbt_cnt) {
     739             :                 /* We enqueued at least one. */
     740           0 :                 ifp->if_timer = 5;
     741             : 
     742           0 :                 txs = sc->sc_cbt_prod;
     743           0 :                 txs = txs->tx_next;
     744           0 :                 sc->sc_cbt_prod = txs;
     745           0 :                 txs->tx_cb->cb_command =
     746             :                     htole16(FXP_CB_COMMAND_I | FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S);
     747           0 :                 FXP_TXCB_SYNC(sc, txs,
     748             :                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     749             : 
     750           0 :                 FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
     751             :                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
     752           0 :                 sc->sc_cbt_prev->tx_cb->cb_command &=
     753             :                     htole16(~(FXP_CB_COMMAND_S | FXP_CB_COMMAND_I));
     754           0 :                 FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
     755             :                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     756             : 
     757           0 :                 sc->sc_cbt_prev = txs;
     758             : 
     759           0 :                 fxp_scb_wait(sc);
     760           0 :                 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
     761             : 
     762           0 :                 sc->sc_cbt_cnt = cnt + 1;
     763           0 :         }
     764           0 : }
     765             : 
     766             : /*
     767             :  * Process interface interrupts.
     768             :  */
     769             : int
     770           0 : fxp_intr(void *arg)
     771             : {
     772           0 :         struct fxp_softc *sc = arg;
     773           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     774           0 :         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
     775             :         u_int16_t statack;
     776             :         bus_dmamap_t rxmap;
     777             :         int claimed = 0;
     778             :         int rnr = 0;
     779             : 
     780             :         /*
     781             :          * If the interface isn't running, don't try to
     782             :          * service the interrupt.. just ack it and bail.
     783             :          */
     784           0 :         if ((ifp->if_flags & IFF_RUNNING) == 0) {
     785           0 :                 statack = CSR_READ_2(sc, FXP_CSR_SCB_STATUS);
     786           0 :                 if (statack) {
     787             :                         claimed = 1;
     788           0 :                         CSR_WRITE_2(sc, FXP_CSR_SCB_STATUS,
     789             :                             statack & FXP_SCB_STATACK_MASK);
     790           0 :                 }
     791           0 :                 return claimed;
     792             :         }
     793             : 
     794           0 :         while ((statack = CSR_READ_2(sc, FXP_CSR_SCB_STATUS)) &
     795             :             FXP_SCB_STATACK_MASK) {
     796             :                 claimed = 1;
     797           0 :                 rnr = (statack & (FXP_SCB_STATACK_RNR | 
     798             :                                   FXP_SCB_STATACK_SWI)) ? 1 : 0;
     799             :                 /*
     800             :                  * First ACK all the interrupts in this pass.
     801             :                  */
     802           0 :                 CSR_WRITE_2(sc, FXP_CSR_SCB_STATUS,
     803             :                     statack & FXP_SCB_STATACK_MASK);
     804             : 
     805             :                 /*
     806             :                  * Free any finished transmit mbuf chains.
     807             :                  */
     808           0 :                 if (statack & (FXP_SCB_STATACK_CXTNO|FXP_SCB_STATACK_CNA)) {
     809           0 :                         int txcnt = sc->sc_cbt_cnt;
     810           0 :                         struct fxp_txsw *txs = sc->sc_cbt_cons;
     811             : 
     812           0 :                         FXP_TXCB_SYNC(sc, txs,
     813             :                             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
     814             : 
     815           0 :                         while ((txcnt > 0) &&
     816           0 :                            ((txs->tx_cb->cb_status & htole16(FXP_CB_STATUS_C)) ||
     817           0 :                            (txs->tx_cb->cb_command & htole16(FXP_CB_COMMAND_NOP)))) {
     818           0 :                                 if (txs->tx_mbuf != NULL) {
     819           0 :                                         FXP_MBUF_SYNC(sc, txs->tx_map,
     820             :                                             BUS_DMASYNC_POSTWRITE);
     821           0 :                                         bus_dmamap_unload(sc->sc_dmat,
     822             :                                             txs->tx_map);
     823           0 :                                         m_freem(txs->tx_mbuf);
     824           0 :                                         txs->tx_mbuf = NULL;
     825           0 :                                 }
     826           0 :                                 --txcnt;
     827           0 :                                 txs = txs->tx_next;
     828           0 :                                 FXP_TXCB_SYNC(sc, txs,
     829             :                                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
     830             :                         }
     831           0 :                         sc->sc_cbt_cnt = txcnt;
     832             :                         /* Did we transmit any packets? */
     833           0 :                         if (sc->sc_cbt_cons != txs)
     834           0 :                                 ifq_clr_oactive(&ifp->if_snd);
     835           0 :                         ifp->if_timer = sc->sc_cbt_cnt ? 5 : 0;
     836           0 :                         sc->sc_cbt_cons = txs;
     837             : 
     838           0 :                         if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
     839             :                                 /*
     840             :                                  * Try to start more packets transmitting.
     841             :                                  */
     842           0 :                                 fxp_start(ifp);
     843           0 :                         }
     844           0 :                 }
     845             :                 /*
     846             :                  * Process receiver interrupts. If a Receive Unit
     847             :                  * not ready (RNR) condition exists, get whatever
     848             :                  * packets we can and re-start the receiver.
     849             :                  */
     850           0 :                 if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR |
     851             :                                FXP_SCB_STATACK_SWI)) {
     852             :                         struct mbuf *m;
     853           0 :                         u_int8_t *rfap;
     854             : rcvloop:
     855           0 :                         m = sc->rfa_headm;
     856           0 :                         rfap = m->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
     857           0 :                         rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
     858           0 :                         bus_dmamap_sync(sc->sc_dmat, rxmap,
     859             :                             0, MCLBYTES, BUS_DMASYNC_POSTREAD |
     860             :                             BUS_DMASYNC_POSTWRITE);
     861             : 
     862           0 :                         if (*(u_int16_t *)(rfap +
     863           0 :                             offsetof(struct fxp_rfa, rfa_status)) &
     864             :                             htole16(FXP_RFA_STATUS_C)) {
     865           0 :                                 if (*(u_int16_t *)(rfap +
     866           0 :                                     offsetof(struct fxp_rfa, rfa_status)) &
     867             :                                     htole16(FXP_RFA_STATUS_RNR))
     868           0 :                                         rnr = 1;
     869             : 
     870             :                                 /*
     871             :                                  * Remove first packet from the chain.
     872             :                                  */
     873           0 :                                 sc->rfa_headm = m->m_next;
     874           0 :                                 m->m_next = NULL;
     875             : 
     876             :                                 /*
     877             :                                  * Add a new buffer to the receive chain.
     878             :                                  * If this fails, the old buffer is recycled
     879             :                                  * instead.
     880             :                                  */
     881           0 :                                 if (fxp_add_rfabuf(sc, m) == 0) {
     882             :                                         u_int16_t total_len;
     883             : 
     884           0 :                                         total_len = htole16(*(u_int16_t *)(rfap +
     885             :                                             offsetof(struct fxp_rfa,
     886           0 :                                             actual_size))) &
     887             :                                             (MCLBYTES - 1);
     888           0 :                                         if (total_len <
     889             :                                             sizeof(struct ether_header)) {
     890           0 :                                                 m_freem(m);
     891           0 :                                                 goto rcvloop;
     892             :                                         }
     893           0 :                                         if (*(u_int16_t *)(rfap +
     894             :                                             offsetof(struct fxp_rfa,
     895           0 :                                             rfa_status)) &
     896             :                                             htole16(FXP_RFA_STATUS_CRC)) {
     897           0 :                                                 m_freem(m);
     898           0 :                                                 goto rcvloop;
     899             :                                         }
     900             : 
     901           0 :                                         m->m_pkthdr.len = m->m_len = total_len;
     902           0 :                                         ml_enqueue(&ml, m);
     903           0 :                                 }
     904           0 :                                 goto rcvloop;
     905             :                         }
     906           0 :                 }
     907           0 :                 if (rnr) {
     908           0 :                         rxmap = *((bus_dmamap_t *)
     909           0 :                             sc->rfa_headm->m_ext.ext_buf);
     910           0 :                         fxp_scb_wait(sc);
     911           0 :                         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
     912             :                                     rxmap->dm_segs[0].ds_addr +
     913             :                                     RFA_ALIGNMENT_FUDGE);
     914           0 :                         fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
     915             : 
     916           0 :                 }
     917             :         }
     918             : 
     919           0 :         if_input(ifp, &ml);
     920             : 
     921           0 :         return (claimed);
     922           0 : }
     923             : 
     924             : /*
     925             :  * Update packet in/out/collision statistics. The i82557 doesn't
     926             :  * allow you to access these counters without doing a fairly
     927             :  * expensive DMA to get _all_ of the statistics it maintains, so
     928             :  * we do this operation here only once per second. The statistics
     929             :  * counters in the kernel are updated from the previous dump-stats
     930             :  * DMA and then a new dump-stats DMA is started. The on-chip
     931             :  * counters are zeroed when the DMA completes. If we can't start
     932             :  * the DMA immediately, we don't wait - we just prepare to read
     933             :  * them again next time.
     934             :  */
     935             : void
     936           0 : fxp_stats_update(void *arg)
     937             : {
     938           0 :         struct fxp_softc *sc = arg;
     939           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     940           0 :         struct fxp_stats *sp = &sc->sc_ctrl->stats;
     941             :         int s;
     942             : 
     943           0 :         FXP_STATS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
     944           0 :         ifp->if_collisions += letoh32(sp->tx_total_collisions);
     945           0 :         if (sp->rx_good) {
     946           0 :                 sc->rx_idle_secs = 0;
     947           0 :         } else if (sc->sc_flags & FXPF_RECV_WORKAROUND)
     948           0 :                 sc->rx_idle_secs++;
     949           0 :         ifp->if_ierrors +=
     950           0 :             letoh32(sp->rx_crc_errors) +
     951           0 :             letoh32(sp->rx_alignment_errors) +
     952           0 :             letoh32(sp->rx_rnr_errors) +
     953           0 :             letoh32(sp->rx_overrun_errors);
     954             :         /*
     955             :          * If any transmit underruns occurred, bump up the transmit
     956             :          * threshold by another 512 bytes (64 * 8).
     957             :          */
     958           0 :         if (sp->tx_underruns) {
     959           0 :                 ifp->if_oerrors += letoh32(sp->tx_underruns);
     960           0 :                 if (tx_threshold < 192)
     961           0 :                         tx_threshold += 64;
     962             :         }
     963           0 :         s = splnet();
     964             :         /*
     965             :          * If we haven't received any packets in FXP_MAX_RX_IDLE seconds,
     966             :          * then assume the receiver has locked up and attempt to clear
     967             :          * the condition by reprogramming the multicast filter. This is
     968             :          * a work-around for a bug in the 82557 where the receiver locks
     969             :          * up if it gets certain types of garbage in the synchronization
     970             :          * bits prior to the packet header. This bug is supposed to only
     971             :          * occur in 10Mbps mode, but has been seen to occur in 100Mbps
     972             :          * mode as well (perhaps due to a 10/100 speed transition).
     973             :          */
     974           0 :         if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
     975           0 :                 sc->rx_idle_secs = 0;
     976           0 :                 fxp_init(sc);
     977           0 :                 splx(s);
     978           0 :                 return;
     979             :         }
     980             :         /*
     981             :          * If there is no pending command, start another stats
     982             :          * dump. Otherwise punt for now.
     983             :          */
     984           0 :         FXP_STATS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     985           0 :         if (!(CSR_READ_2(sc, FXP_CSR_SCB_COMMAND) & 0xff)) {
     986             :                 /*
     987             :                  * Start another stats dump.
     988             :                  */
     989           0 :                 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
     990           0 :         } else {
     991             :                 /*
     992             :                  * A previous command is still waiting to be accepted.
     993             :                  * Just zero our copy of the stats and wait for the
     994             :                  * next timer event to update them.
     995             :                  */
     996           0 :                 sp->tx_good = 0;
     997           0 :                 sp->tx_underruns = 0;
     998           0 :                 sp->tx_total_collisions = 0;
     999             : 
    1000           0 :                 sp->rx_good = 0;
    1001           0 :                 sp->rx_crc_errors = 0;
    1002           0 :                 sp->rx_alignment_errors = 0;
    1003           0 :                 sp->rx_rnr_errors = 0;
    1004           0 :                 sp->rx_overrun_errors = 0;
    1005             :         }
    1006             : 
    1007             :         /* Tick the MII clock. */
    1008           0 :         mii_tick(&sc->sc_mii);
    1009             : 
    1010           0 :         splx(s);
    1011             :         /*
    1012             :          * Schedule another timeout one second from now.
    1013             :          */
    1014           0 :         timeout_add_sec(&sc->stats_update_to, 1);
    1015           0 : }
    1016             : 
    1017             : void
    1018           0 : fxp_detach(struct fxp_softc *sc)
    1019             : {
    1020           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1021             : 
    1022             :         /* Get rid of our timeouts and mbufs */
    1023           0 :         fxp_stop(sc, 1, 1);
    1024             : 
    1025             :         /* Detach any PHYs we might have. */
    1026           0 :         if (LIST_FIRST(&sc->sc_mii.mii_phys) != NULL)
    1027           0 :                 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
    1028             : 
    1029             :         /* Delete any remaining media. */
    1030           0 :         ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
    1031             : 
    1032           0 :         ether_ifdetach(ifp);
    1033           0 :         if_detach(ifp);
    1034             : 
    1035             : #ifndef SMALL_KERNEL
    1036           0 :         if (sc->sc_ucodebuf)
    1037           0 :                 free(sc->sc_ucodebuf, M_DEVBUF, sc->sc_ucodelen);
    1038             : #endif
    1039           0 : }
    1040             : 
    1041             : /*
    1042             :  * Stop the interface. Cancels the statistics updater and resets
    1043             :  * the interface.
    1044             :  */
    1045             : void
    1046           0 : fxp_stop(struct fxp_softc *sc, int drain, int softonly)
    1047             : {
    1048           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1049             :         int i;
    1050             : 
    1051             :         /*
    1052             :          * Cancel stats updater.
    1053             :          */
    1054           0 :         timeout_del(&sc->stats_update_to);
    1055             : 
    1056             :         /*
    1057             :          * Turn down interface (done early to avoid bad interactions
    1058             :          * between panics, and the watchdog timer)
    1059             :          */
    1060           0 :         ifp->if_timer = 0;
    1061           0 :         ifp->if_flags &= ~IFF_RUNNING;
    1062           0 :         ifq_clr_oactive(&ifp->if_snd);
    1063             : 
    1064           0 :         if (!softonly)
    1065           0 :                 mii_down(&sc->sc_mii);
    1066             : 
    1067             :         /*
    1068             :          * Issue software reset.
    1069             :          */
    1070           0 :         if (!softonly) {
    1071           0 :                 CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
    1072           0 :                 DELAY(10);
    1073           0 :         }
    1074             : 
    1075             :         /*
    1076             :          * Release any xmit buffers.
    1077             :          */
    1078           0 :         for (i = 0; i < FXP_NTXCB; i++) {
    1079           0 :                 if (sc->txs[i].tx_mbuf != NULL) {
    1080           0 :                         bus_dmamap_unload(sc->sc_dmat, sc->txs[i].tx_map);
    1081           0 :                         m_freem(sc->txs[i].tx_mbuf);
    1082           0 :                         sc->txs[i].tx_mbuf = NULL;
    1083           0 :                 }
    1084             :         }
    1085           0 :         sc->sc_cbt_cnt = 0;
    1086             : 
    1087           0 :         if (drain) {
    1088             :                 bus_dmamap_t rxmap;
    1089             :                 struct mbuf *m;
    1090             : 
    1091             :                 /*
    1092             :                  * Free all the receive buffers then reallocate/reinitialize
    1093             :                  */
    1094           0 :                 m = sc->rfa_headm;
    1095           0 :                 while (m != NULL) {
    1096           0 :                         rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
    1097           0 :                         bus_dmamap_unload(sc->sc_dmat, rxmap);
    1098           0 :                         FXP_RXMAP_PUT(sc, rxmap);
    1099           0 :                         m = m_free(m);
    1100           0 :                         sc->rx_bufs--;
    1101             :                 }
    1102           0 :                 sc->rfa_headm = NULL;
    1103           0 :                 sc->rfa_tailm = NULL;
    1104           0 :                 for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
    1105           0 :                         if (fxp_add_rfabuf(sc, NULL) != 0) {
    1106             :                                 /*
    1107             :                                  * This "can't happen" - we're at splnet()
    1108             :                                  * and we just freed all the buffers we need
    1109             :                                  * above.
    1110             :                                  */
    1111           0 :                                 panic("fxp_stop: no buffers!");
    1112             :                         }
    1113           0 :                         sc->rx_bufs++;
    1114             :                 }
    1115           0 :         }
    1116           0 : }
    1117             : 
    1118             : /*
    1119             :  * Watchdog/transmission transmit timeout handler. Called when a
    1120             :  * transmission is started on the interface, but no interrupt is
    1121             :  * received before the timeout. This usually indicates that the
    1122             :  * card has wedged for some reason.
    1123             :  */
    1124             : void
    1125           0 : fxp_watchdog(struct ifnet *ifp)
    1126             : {
    1127           0 :         struct fxp_softc *sc = ifp->if_softc;
    1128             : 
    1129           0 :         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
    1130           0 :         ifp->if_oerrors++;
    1131             : 
    1132           0 :         fxp_init(sc);
    1133           0 : }
    1134             : 
    1135             : /*
    1136             :  * Submit a command to the i82557.
    1137             :  */
    1138             : void
    1139           0 : fxp_scb_cmd(struct fxp_softc *sc, u_int16_t cmd)
    1140             : {
    1141           0 :         CSR_WRITE_2(sc, FXP_CSR_SCB_COMMAND, cmd);
    1142           0 : }
    1143             : 
    1144             : void
    1145           0 : fxp_init(void *xsc)
    1146             : {
    1147           0 :         struct fxp_softc *sc = xsc;
    1148           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1149             :         struct fxp_cb_config *cbp;
    1150             :         struct fxp_cb_ias *cb_ias;
    1151             :         struct fxp_cb_tx *txp;
    1152             :         bus_dmamap_t rxmap;
    1153             :         int i, prm, save_bf, lrxen, allm, bufs;
    1154             : 
    1155           0 :         splassert(IPL_NET);
    1156             : 
    1157             :         /*
    1158             :          * Cancel any pending I/O
    1159             :          */
    1160           0 :         fxp_stop(sc, 0, 0);
    1161             : 
    1162             :         /*
    1163             :          * Initialize base of CBL and RFA memory. Loading with zero
    1164             :          * sets it up for regular linear addressing.
    1165             :          */
    1166           0 :         fxp_scb_wait(sc);
    1167           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
    1168           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
    1169             : 
    1170           0 :         fxp_scb_wait(sc);
    1171           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
    1172           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
    1173             : 
    1174             : #ifndef SMALL_KERNEL
    1175           0 :         fxp_load_ucode(sc);
    1176             : #endif
    1177             :         /* Once through to set flags */
    1178           0 :         fxp_mc_setup(sc, 0);
    1179             : 
    1180             :         /*
    1181             :          * In order to support receiving 802.1Q VLAN frames, we have to
    1182             :          * enable "save bad frames", since they are 4 bytes larger than
    1183             :          * the normal Ethernet maximum frame length. On i82558 and later,
    1184             :          * we have a better mechanism for this.
    1185             :          */
    1186             :         save_bf = 0;
    1187             :         lrxen = 0;
    1188             : 
    1189           0 :         if (sc->sc_revision >= FXP_REV_82558_A4)
    1190           0 :                 lrxen = 1;
    1191             :         else
    1192             :                 save_bf = 1;
    1193             : 
    1194             :         /*
    1195             :          * Initialize base of dump-stats buffer.
    1196             :          */
    1197           0 :         fxp_scb_wait(sc);
    1198           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
    1199             :             sc->tx_cb_map->dm_segs->ds_addr +
    1200             :             offsetof(struct fxp_ctrl, stats));
    1201           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
    1202             : 
    1203           0 :         cbp = &sc->sc_ctrl->u.cfg;
    1204             :         /*
    1205             :          * This bcopy is kind of disgusting, but there are a bunch of must be
    1206             :          * zero and must be one bits in this structure and this is the easiest
    1207             :          * way to initialize them all to proper values.
    1208             :          */
    1209           0 :         bcopy(fxp_cb_config_template, (void *)&cbp->cb_status,
    1210             :                 sizeof(fxp_cb_config_template));
    1211             : 
    1212           0 :         prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;
    1213           0 :         allm = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;
    1214             : 
    1215             : #if 0
    1216             :         cbp->cb_status =     0;
    1217             :         cbp->cb_command =    FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
    1218             :         cbp->link_addr =     0xffffffff;     /* (no) next command */
    1219             :         cbp->byte_count =    22;             /* (22) bytes to config */
    1220             :         cbp->rx_fifo_limit = 8;      /* rx fifo threshold (32 bytes) */
    1221             :         cbp->tx_fifo_limit = 0;      /* tx fifo threshold (0 bytes) */
    1222             :         cbp->adaptive_ifs =  0;      /* (no) adaptive interframe spacing */
    1223             :         cbp->rx_dma_bytecount =      0;      /* (no) rx DMA max */
    1224             :         cbp->tx_dma_bytecount =      0;      /* (no) tx DMA max */
    1225             :         cbp->dma_bce =               0;      /* (disable) dma max counters */
    1226             :         cbp->late_scb =              0;      /* (don't) defer SCB update */
    1227             :         cbp->tno_int =               0;      /* (disable) tx not okay interrupt */
    1228             :         cbp->ci_int =                1;      /* interrupt on CU idle */
    1229             :         cbp->save_bf =               save_bf ? 1 : prm; /* save bad frames */
    1230             :         cbp->disc_short_rx = !prm;   /* discard short packets */
    1231             :         cbp->underrun_retry =        1;      /* retry mode (1) on DMA underrun */
    1232             :         cbp->mediatype =     !sc->phy_10Mbps_only; /* interface mode */
    1233             :         cbp->nsai =          1;      /* (don't) disable source addr insert */
    1234             :         cbp->preamble_length =       2;      /* (7 byte) preamble */
    1235             :         cbp->loopback =              0;      /* (don't) loopback */
    1236             :         cbp->linear_priority =       0;      /* (normal CSMA/CD operation) */
    1237             :         cbp->linear_pri_mode =       0;      /* (wait after xmit only) */
    1238             :         cbp->interfrm_spacing =      6;      /* (96 bits of) interframe spacing */
    1239             :         cbp->promiscuous =   prm;    /* promiscuous mode */
    1240             :         cbp->bcast_disable = 0;      /* (don't) disable broadcasts */
    1241             :         cbp->crscdt =                0;      /* (CRS only) */
    1242             :         cbp->stripping =     !prm;   /* truncate rx packet to byte count */
    1243             :         cbp->padding =               1;      /* (do) pad short tx packets */
    1244             :         cbp->rcv_crc_xfer =  0;      /* (don't) xfer CRC to host */
    1245             :         cbp->long_rx =               lrxen;  /* (enable) long packets */
    1246             :         cbp->force_fdx =     0;      /* (don't) force full duplex */
    1247             :         cbp->fdx_pin_en =    1;      /* (enable) FDX# pin */
    1248             :         cbp->multi_ia =              0;      /* (don't) accept multiple IAs */
    1249             :         cbp->mc_all =                allm;
    1250             : #else
    1251           0 :         cbp->cb_command = htole16(FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL);
    1252             : 
    1253           0 :         if (allm && !prm)
    1254           0 :                 cbp->mc_all |= 0x08;         /* accept all multicasts */
    1255             :         else
    1256           0 :                 cbp->mc_all &= ~0x08;            /* reject all multicasts */
    1257             : 
    1258           0 :         if (prm) {
    1259           0 :                 cbp->promiscuous |= 1;               /* promiscuous mode */
    1260           0 :                 cbp->ctrl2 &= ~0x01;             /* save short packets */
    1261           0 :                 cbp->stripping &= ~0x01; /* don't truncate rx packets */
    1262           0 :         } else {
    1263           0 :                 cbp->promiscuous &= ~1;          /* no promiscuous mode */
    1264           0 :                 cbp->ctrl2 |= 0x01;          /* discard short packets */
    1265           0 :                 cbp->stripping |= 0x01;              /* truncate rx packets */
    1266             :         }
    1267             : 
    1268           0 :         if (prm || save_bf)
    1269           0 :                 cbp->ctrl1 |= 0x80;          /* save bad frames */
    1270             :         else
    1271           0 :                 cbp->ctrl1 &= ~0x80;             /* discard bad frames */
    1272             : 
    1273           0 :         if (sc->sc_flags & FXPF_MWI_ENABLE)
    1274           0 :                 cbp->ctrl0 |= 0x01;          /* enable PCI MWI command */
    1275             : 
    1276           0 :         if(!sc->phy_10Mbps_only)                     /* interface mode */
    1277           0 :                 cbp->mediatype |= 0x01;
    1278             :         else
    1279           0 :                 cbp->mediatype &= ~0x01;
    1280             : 
    1281           0 :         if(lrxen)                       /* long packets */
    1282           0 :                 cbp->stripping |= 0x08;
    1283             :         else
    1284           0 :                 cbp->stripping &= ~0x08;
    1285             : 
    1286           0 :         cbp->tx_dma_bytecount = 0; /* (no) tx DMA max, dma_dce = 0 ??? */
    1287           0 :         cbp->ctrl1 |= 0x08;  /* ci_int = 1 */
    1288           0 :         cbp->ctrl3 |= 0x08;  /* nsai */
    1289           0 :         cbp->fifo_limit = 0x08; /* tx and rx fifo limit */
    1290           0 :         cbp->fdx_pin |= 0x80;        /* Enable full duplex setting by pin */
    1291             : #endif
    1292             : 
    1293             :         /*
    1294             :          * Start the config command/DMA.
    1295             :          */
    1296           0 :         fxp_scb_wait(sc);
    1297           0 :         FXP_CFG_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1298           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
    1299             :             offsetof(struct fxp_ctrl, u.cfg));
    1300           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
    1301             :         /* ...and wait for it to complete. */
    1302             :         i = FXP_CMD_TMO;
    1303           0 :         do {
    1304           0 :                 DELAY(1);
    1305           0 :                 FXP_CFG_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1306           0 :         } while ((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0 && i--);
    1307             : 
    1308           0 :         FXP_CFG_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1309           0 :         if (!(cbp->cb_status & htole16(FXP_CB_STATUS_C))) {
    1310           0 :                 printf("%s: config command timeout\n", sc->sc_dev.dv_xname);
    1311           0 :                 return;
    1312             :         }
    1313             : 
    1314             :         /*
    1315             :          * Now initialize the station address.
    1316             :          */
    1317           0 :         cb_ias = &sc->sc_ctrl->u.ias;
    1318           0 :         cb_ias->cb_status = htole16(0);
    1319           0 :         cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL);
    1320           0 :         cb_ias->link_addr = htole32(0xffffffff);
    1321           0 :         bcopy(sc->sc_arpcom.ac_enaddr, (void *)cb_ias->macaddr,
    1322             :             sizeof(sc->sc_arpcom.ac_enaddr));
    1323             : 
    1324             :         /*
    1325             :          * Start the IAS (Individual Address Setup) command/DMA.
    1326             :          */
    1327           0 :         fxp_scb_wait(sc);
    1328           0 :         FXP_IAS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1329           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
    1330             :             offsetof(struct fxp_ctrl, u.ias));
    1331           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
    1332             :         /* ...and wait for it to complete. */
    1333             :         i = FXP_CMD_TMO;
    1334           0 :         do {
    1335           0 :                 DELAY(1);
    1336           0 :                 FXP_IAS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1337           0 :         } while (!(cb_ias->cb_status & htole16(FXP_CB_STATUS_C)) && i--);
    1338             : 
    1339           0 :         FXP_IAS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1340           0 :         if (!(cb_ias->cb_status & htole16(FXP_CB_STATUS_C))) {
    1341           0 :                 printf("%s: IAS command timeout\n", sc->sc_dev.dv_xname);
    1342           0 :                 return;
    1343             :         }
    1344             : 
    1345             :         /* Again, this time really upload the multicast addresses */
    1346           0 :         fxp_mc_setup(sc, 1);
    1347             : 
    1348             :         /*
    1349             :          * Initialize transmit control block (TxCB) list.
    1350             :          */
    1351           0 :         bzero(sc->sc_ctrl->tx_cb, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
    1352           0 :         txp = sc->sc_ctrl->tx_cb;
    1353           0 :         for (i = 0; i < FXP_NTXCB; i++) {
    1354           0 :                 txp[i].cb_command = htole16(FXP_CB_COMMAND_NOP);
    1355           0 :                 txp[i].link_addr = htole32(sc->tx_cb_map->dm_segs->ds_addr +
    1356             :                     offsetof(struct fxp_ctrl, tx_cb[(i + 1) & FXP_TXCB_MASK]));
    1357           0 :                 txp[i].tbd_array_addr =htole32(sc->tx_cb_map->dm_segs->ds_addr +
    1358             :                     offsetof(struct fxp_ctrl, tx_cb[i].tbd[0]));
    1359             :         }
    1360             :         /*
    1361             :          * Set the suspend flag on the first TxCB and start the control
    1362             :          * unit. It will execute the NOP and then suspend.
    1363             :          */
    1364           0 :         sc->sc_cbt_prev = sc->sc_cbt_prod = sc->sc_cbt_cons = sc->txs;
    1365           0 :         sc->sc_cbt_cnt = 1;
    1366           0 :         sc->sc_ctrl->tx_cb[0].cb_command = htole16(FXP_CB_COMMAND_NOP |
    1367             :             FXP_CB_COMMAND_S | FXP_CB_COMMAND_I);
    1368           0 :         bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, 0,
    1369             :             sc->tx_cb_map->dm_mapsize,
    1370             :             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    1371             : 
    1372           0 :         fxp_scb_wait(sc);
    1373           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
    1374             :             offsetof(struct fxp_ctrl, tx_cb[0]));
    1375           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
    1376             : 
    1377             :         /*
    1378             :          * Initialize receiver buffer area - RFA.
    1379             :          */
    1380           0 :         if (ifp->if_flags & IFF_UP)
    1381           0 :                 bufs = FXP_NRFABUFS_MAX;
    1382             :         else
    1383             :                 bufs = FXP_NRFABUFS_MIN;
    1384           0 :         if (sc->rx_bufs > bufs) {
    1385           0 :                 while (sc->rfa_headm != NULL && sc->rx_bufs-- > bufs) {
    1386           0 :                         rxmap = *((bus_dmamap_t *)sc->rfa_headm->m_ext.ext_buf);
    1387           0 :                         bus_dmamap_unload(sc->sc_dmat, rxmap);
    1388           0 :                         FXP_RXMAP_PUT(sc, rxmap);
    1389           0 :                         sc->rfa_headm = m_free(sc->rfa_headm);
    1390             :                 }
    1391           0 :         } else if (sc->rx_bufs < bufs) {
    1392             :                 int err, tmp_rx_bufs = sc->rx_bufs;
    1393           0 :                 for (i = sc->rx_bufs; i < bufs; i++) {
    1394           0 :                         if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
    1395           0 :                             MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
    1396           0 :                                 printf("%s: unable to create rx dma map %d, "
    1397           0 :                                   "error %d\n", sc->sc_dev.dv_xname, i, err);
    1398           0 :                                 break;
    1399             :                         }
    1400           0 :                         sc->rx_bufs++;
    1401             :                 }
    1402           0 :                 for (i = tmp_rx_bufs; i < sc->rx_bufs; i++)
    1403           0 :                         if (fxp_add_rfabuf(sc, NULL) != 0)
    1404             :                                 break;
    1405           0 :         }
    1406           0 :         fxp_scb_wait(sc);
    1407             : 
    1408             :         /*
    1409             :          * Set current media.
    1410             :          */
    1411           0 :         mii_mediachg(&sc->sc_mii);
    1412             : 
    1413           0 :         ifp->if_flags |= IFF_RUNNING;
    1414           0 :         ifq_clr_oactive(&ifp->if_snd);
    1415             : 
    1416             :         /*
    1417             :          * Request a software generated interrupt that will be used to 
    1418             :          * (re)start the RU processing.  If we direct the chip to start
    1419             :          * receiving from the start of queue now, instead of letting the
    1420             :          * interrupt handler first process all received packets, we run
    1421             :          * the risk of having it overwrite mbuf clusters while they are
    1422             :          * being processed or after they have been returned to the pool.
    1423             :          */
    1424           0 :         CSR_WRITE_2(sc, FXP_CSR_SCB_COMMAND,
    1425             :             CSR_READ_2(sc, FXP_CSR_SCB_COMMAND) |
    1426             :             FXP_SCB_INTRCNTL_REQUEST_SWI);
    1427             : 
    1428             :         /*
    1429             :          * Start stats updater.
    1430             :          */
    1431           0 :         timeout_add_sec(&sc->stats_update_to, 1);
    1432           0 : }
    1433             : 
    1434             : /*
    1435             :  * Change media according to request.
    1436             :  */
    1437             : int
    1438           0 : fxp_mediachange(struct ifnet *ifp)
    1439             : {
    1440           0 :         struct fxp_softc *sc = ifp->if_softc;
    1441           0 :         struct mii_data *mii = &sc->sc_mii;
    1442             : 
    1443           0 :         if (mii->mii_instance) {
    1444             :                 struct mii_softc *miisc;
    1445           0 :                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
    1446           0 :                         mii_phy_reset(miisc);
    1447           0 :         }
    1448           0 :         mii_mediachg(&sc->sc_mii);
    1449           0 :         return (0);
    1450             : }
    1451             : 
    1452             : /*
    1453             :  * Notify the world which media we're using.
    1454             :  */
    1455             : void
    1456           0 : fxp_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
    1457             : {
    1458           0 :         struct fxp_softc *sc = ifp->if_softc;
    1459             : 
    1460           0 :         mii_pollstat(&sc->sc_mii);
    1461           0 :         ifmr->ifm_status = sc->sc_mii.mii_media_status;
    1462           0 :         ifmr->ifm_active = sc->sc_mii.mii_media_active;
    1463           0 : }
    1464             : 
    1465             : /*
    1466             :  * Add a buffer to the end of the RFA buffer list.
    1467             :  * Return 0 if successful, 1 for failure. A failure results in
    1468             :  * adding the 'oldm' (if non-NULL) on to the end of the list -
    1469             :  * tossing out its old contents and recycling it.
    1470             :  * The RFA struct is stuck at the beginning of mbuf cluster and the
    1471             :  * data pointer is fixed up to point just past it.
    1472             :  */
    1473             : int
    1474           0 : fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm)
    1475             : {
    1476           0 :         u_int32_t v;
    1477             :         struct mbuf *m;
    1478             :         u_int8_t *rfap;
    1479             :         bus_dmamap_t rxmap = NULL;
    1480             : 
    1481           0 :         MGETHDR(m, M_DONTWAIT, MT_DATA);
    1482           0 :         if (m != NULL) {
    1483           0 :                 MCLGET(m, M_DONTWAIT);
    1484           0 :                 if ((m->m_flags & M_EXT) == 0) {
    1485           0 :                         m_freem(m);
    1486           0 :                         if (oldm == NULL)
    1487           0 :                                 return 1;
    1488             :                         m = oldm;
    1489           0 :                         m->m_data = m->m_ext.ext_buf;
    1490           0 :                 }
    1491           0 :                 if (oldm == NULL) {
    1492           0 :                         rxmap = FXP_RXMAP_GET(sc);
    1493           0 :                         *((bus_dmamap_t *)m->m_ext.ext_buf) = rxmap;
    1494           0 :                         bus_dmamap_load(sc->sc_dmat, rxmap,
    1495             :                             m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
    1496             :                             BUS_DMA_NOWAIT);
    1497           0 :                 } else if (oldm == m)
    1498             :                         rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
    1499             :                 else {
    1500             :                         rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
    1501           0 :                         bus_dmamap_unload(sc->sc_dmat, rxmap);
    1502           0 :                         bus_dmamap_load(sc->sc_dmat, rxmap,
    1503             :                             m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
    1504             :                             BUS_DMA_NOWAIT);
    1505           0 :                         *mtod(m, bus_dmamap_t *) = rxmap;
    1506             :                 }
    1507             :         } else {
    1508           0 :                 if (oldm == NULL)
    1509           0 :                         return 1;
    1510             :                 m = oldm;
    1511           0 :                 m->m_data = m->m_ext.ext_buf;
    1512           0 :                 rxmap = *mtod(m, bus_dmamap_t *);
    1513             :         }
    1514             : 
    1515             :         /*
    1516             :          * Move the data pointer up so that the incoming data packet
    1517             :          * will be 32-bit aligned.
    1518             :          */
    1519           0 :         m->m_data += RFA_ALIGNMENT_FUDGE;
    1520             : 
    1521             :         /*
    1522             :          * Get a pointer to the base of the mbuf cluster and move
    1523             :          * data start past it.
    1524             :          */
    1525             :         rfap = m->m_data;
    1526           0 :         m->m_data += sizeof(struct fxp_rfa);
    1527           0 :         *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, size)) =
    1528             :             htole16(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
    1529             : 
    1530             :         /*
    1531             :          * Initialize the rest of the RFA.  Note that since the RFA
    1532             :          * is misaligned, we cannot store values directly.  Instead,
    1533             :          * we use an optimized, inline copy.
    1534             :          */
    1535           0 :         *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_status)) = 0;
    1536           0 :         *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) =
    1537             :             htole16(FXP_RFA_CONTROL_EL);
    1538           0 :         *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, actual_size)) = 0;
    1539             : 
    1540           0 :         v = -1;
    1541           0 :         fxp_lwcopy(&v,
    1542           0 :             (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
    1543           0 :         fxp_lwcopy(&v,
    1544           0 :             (u_int32_t *)(rfap + offsetof(struct fxp_rfa, rbd_addr)));
    1545             : 
    1546           0 :         bus_dmamap_sync(sc->sc_dmat, rxmap, 0, MCLBYTES,
    1547             :             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    1548             : 
    1549             :         /*
    1550             :          * If there are other buffers already on the list, attach this
    1551             :          * one to the end by fixing up the tail to point to this one.
    1552             :          */
    1553           0 :         if (sc->rfa_headm != NULL) {
    1554           0 :                 sc->rfa_tailm->m_next = m;
    1555           0 :                 v = htole32(rxmap->dm_segs[0].ds_addr + RFA_ALIGNMENT_FUDGE);
    1556           0 :                 rfap = sc->rfa_tailm->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
    1557           0 :                 fxp_lwcopy(&v,
    1558           0 :                     (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
    1559           0 :                 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) &=
    1560             :                     htole16((u_int16_t)~FXP_RFA_CONTROL_EL);
    1561             :                 /* XXX we only need to sync the control struct */
    1562           0 :                 bus_dmamap_sync(sc->sc_dmat,
    1563             :                     *((bus_dmamap_t *)sc->rfa_tailm->m_ext.ext_buf), 0,
    1564             :                         MCLBYTES, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    1565           0 :         } else
    1566           0 :                 sc->rfa_headm = m;
    1567             : 
    1568           0 :         sc->rfa_tailm = m;
    1569             : 
    1570           0 :         return (m == oldm);
    1571           0 : }
    1572             : 
    1573             : int
    1574           0 : fxp_mdi_read(struct device *self, int phy, int reg)
    1575             : {
    1576           0 :         struct fxp_softc *sc = (struct fxp_softc *)self;
    1577             :         int count = FXP_CMD_TMO;
    1578             :         int value;
    1579             : 
    1580           0 :         CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
    1581             :             (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
    1582             : 
    1583           0 :         while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0
    1584           0 :             && count--)
    1585           0 :                 DELAY(10);
    1586             : 
    1587           0 :         if (count <= 0)
    1588           0 :                 printf("%s: fxp_mdi_read: timed out\n", sc->sc_dev.dv_xname);
    1589             : 
    1590           0 :         return (value & 0xffff);
    1591             : }
    1592             : 
    1593             : void
    1594           0 : fxp_statchg(struct device *self)
    1595             : {
    1596             :         /* Nothing to do. */
    1597           0 : }
    1598             : 
    1599             : void
    1600           0 : fxp_mdi_write(struct device *self, int phy, int reg, int value)
    1601             : {
    1602           0 :         struct fxp_softc *sc = (struct fxp_softc *)self;
    1603             :         int count = FXP_CMD_TMO;
    1604             : 
    1605           0 :         CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
    1606             :             (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) |
    1607             :             (value & 0xffff));
    1608             : 
    1609           0 :         while((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 &&
    1610           0 :             count--)
    1611           0 :                 DELAY(10);
    1612             : 
    1613           0 :         if (count <= 0)
    1614           0 :                 printf("%s: fxp_mdi_write: timed out\n", sc->sc_dev.dv_xname);
    1615           0 : }
    1616             : 
    1617             : int
    1618           0 : fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
    1619             : {
    1620           0 :         struct fxp_softc *sc = ifp->if_softc;
    1621           0 :         struct ifreq *ifr = (struct ifreq *)data;
    1622             :         int s, error = 0;
    1623             : 
    1624           0 :         s = splnet();
    1625             : 
    1626           0 :         switch (command) {
    1627             :         case SIOCSIFADDR:
    1628           0 :                 ifp->if_flags |= IFF_UP;
    1629           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
    1630           0 :                         fxp_init(sc);
    1631             :                 break;
    1632             : 
    1633             :         case SIOCSIFFLAGS:
    1634           0 :                 if (ifp->if_flags & IFF_UP) {
    1635           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1636           0 :                                 error = ENETRESET;
    1637             :                         else
    1638           0 :                                 fxp_init(sc);
    1639             :                 } else {
    1640           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1641           0 :                                 fxp_stop(sc, 1, 0);
    1642             :                 }
    1643             :                 break;
    1644             : 
    1645             :         case SIOCSIFMEDIA:
    1646             :         case SIOCGIFMEDIA:
    1647           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
    1648           0 :                 break;
    1649             : 
    1650             :         default:
    1651           0 :                 error = ether_ioctl(ifp, &sc->sc_arpcom, command, data);
    1652           0 :         }
    1653             : 
    1654           0 :         if (error == ENETRESET) {
    1655           0 :                 if (ifp->if_flags & IFF_RUNNING)
    1656           0 :                         fxp_init(sc);
    1657             :                 error = 0;
    1658           0 :         }
    1659             : 
    1660           0 :         splx(s);
    1661           0 :         return (error);
    1662             : }
    1663             : 
    1664             : /*
    1665             :  * Program the multicast filter.
    1666             :  *
    1667             :  * We have an artificial restriction that the multicast setup command
    1668             :  * must be the first command in the chain, so we take steps to ensure
    1669             :  * this. By requiring this, it allows us to keep up the performance of
    1670             :  * the pre-initialized command ring (esp. link pointers) by not actually
    1671             :  * inserting the mcsetup command in the ring - i.e. its link pointer
    1672             :  * points to the TxCB ring, but the mcsetup descriptor itself is not part
    1673             :  * of it. We then can do 'CU_START' on the mcsetup descriptor and have it
    1674             :  * lead into the regular TxCB ring when it completes.
    1675             :  *
    1676             :  * This function must be called at splnet.
    1677             :  */
    1678             : void
    1679           0 : fxp_mc_setup(struct fxp_softc *sc, int doit)
    1680             : {
    1681           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1682             :         struct arpcom *ac = &sc->sc_arpcom;
    1683           0 :         struct fxp_cb_mcs *mcsp = &sc->sc_ctrl->u.mcs;
    1684             :         struct ether_multistep step;
    1685             :         struct ether_multi *enm;
    1686             :         int i, nmcasts = 0;
    1687             : 
    1688           0 :         splassert(IPL_NET);
    1689             : 
    1690           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
    1691             : 
    1692           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 ||
    1693           0 :             ac->ac_multicnt >= MAXMCADDR) {
    1694           0 :                 ifp->if_flags |= IFF_ALLMULTI;
    1695           0 :         } else {
    1696           0 :                 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
    1697           0 :                 while (enm != NULL) {
    1698           0 :                         bcopy(enm->enm_addrlo,
    1699           0 :                             (void *)&mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN);
    1700             : 
    1701           0 :                         nmcasts++;
    1702             : 
    1703           0 :                         ETHER_NEXT_MULTI(step, enm);
    1704             :                 }
    1705             :         }
    1706             : 
    1707           0 :         if (doit == 0)
    1708           0 :                 return;
    1709             : 
    1710             :         /* 
    1711             :          * Initialize multicast setup descriptor.
    1712             :          */
    1713           0 :         mcsp->cb_status = htole16(0);
    1714           0 :         mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL);
    1715           0 :         mcsp->link_addr = htole32(-1);
    1716           0 :         mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN);
    1717             : 
    1718             :         /*
    1719             :          * Wait until command unit is not active. This should never
    1720             :          * be the case when nothing is queued, but make sure anyway.
    1721             :          */
    1722           0 :         for (i = FXP_CMD_TMO; (CSR_READ_2(sc, FXP_CSR_SCB_STATUS) &
    1723           0 :             FXP_SCB_CUS_MASK) != FXP_SCB_CUS_IDLE && i--; DELAY(1));
    1724             : 
    1725           0 :         if ((CSR_READ_2(sc, FXP_CSR_SCB_STATUS) &
    1726           0 :             FXP_SCB_CUS_MASK) != FXP_SCB_CUS_IDLE) {
    1727           0 :                 printf("%s: timeout waiting for CU ready\n",
    1728           0 :                     sc->sc_dev.dv_xname);
    1729           0 :                 return;
    1730             :         }
    1731             : 
    1732             :         /*
    1733             :          * Start the multicast setup command.
    1734             :          */
    1735           0 :         fxp_scb_wait(sc);
    1736           0 :         FXP_MCS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1737           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
    1738             :             offsetof(struct fxp_ctrl, u.mcs));
    1739           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
    1740             : 
    1741             :         i = FXP_CMD_TMO;
    1742           0 :         do {
    1743           0 :                 DELAY(1);
    1744           0 :                 FXP_MCS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1745           0 :         } while (!(mcsp->cb_status & htole16(FXP_CB_STATUS_C)) && i--);
    1746             : 
    1747           0 :         FXP_MCS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1748           0 :         if (!(mcsp->cb_status & htole16(FXP_CB_STATUS_C))) {
    1749           0 :                 printf("%s: multicast command timeout\n", sc->sc_dev.dv_xname);
    1750           0 :                 return;
    1751             :         }
    1752             : 
    1753           0 : }
    1754             : 
    1755             : #ifndef SMALL_KERNEL
    1756             : #include <dev/microcode/fxp/rcvbundl.h>
    1757             : struct ucode {
    1758             :         u_int16_t       revision;
    1759             :         u_int16_t       int_delay_offset;
    1760             :         u_int16_t       bundle_max_offset;
    1761             :         u_int16_t       min_size_mask_offset;
    1762             :         const char      *uname;
    1763             : } const ucode_table[] = {
    1764             :         { FXP_REV_82558_A4, D101_CPUSAVER_DWORD,
    1765             :           0, 0,
    1766             :           "fxp-d101a" }, 
    1767             : 
    1768             :         { FXP_REV_82558_B0, D101_CPUSAVER_DWORD,
    1769             :           0, 0,
    1770             :           "fxp-d101b0" },
    1771             : 
    1772             :         { FXP_REV_82559_A0, D101M_CPUSAVER_DWORD, 
    1773             :           D101M_CPUSAVER_BUNDLE_MAX_DWORD, D101M_CPUSAVER_MIN_SIZE_DWORD,
    1774             :           "fxp-d101ma" },
    1775             : 
    1776             :         { FXP_REV_82559S_A, D101S_CPUSAVER_DWORD,
    1777             :           D101S_CPUSAVER_BUNDLE_MAX_DWORD, D101S_CPUSAVER_MIN_SIZE_DWORD,
    1778             :           "fxp-d101s" },
    1779             : 
    1780             :         { FXP_REV_82550, D102_B_CPUSAVER_DWORD,
    1781             :           D102_B_CPUSAVER_BUNDLE_MAX_DWORD, D102_B_CPUSAVER_MIN_SIZE_DWORD,
    1782             :           "fxp-d102" },
    1783             : 
    1784             :         { FXP_REV_82550_C, D102_C_CPUSAVER_DWORD,
    1785             :           D102_C_CPUSAVER_BUNDLE_MAX_DWORD, D102_C_CPUSAVER_MIN_SIZE_DWORD,
    1786             :           "fxp-d102c" },
    1787             : 
    1788             :         { FXP_REV_82551_F, D102_E_CPUSAVER_DWORD,
    1789             :           D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
    1790             :           "fxp-d102e" },
    1791             : 
    1792             :         { FXP_REV_82551_10, D102_E_CPUSAVER_DWORD,
    1793             :           D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
    1794             :           "fxp-d102e" },
    1795             :         
    1796             :         { 0, 0,
    1797             :           0, 0,
    1798             :           NULL }
    1799             : };
    1800             : 
    1801             : void
    1802           0 : fxp_load_ucode(struct fxp_softc *sc)
    1803             : {
    1804             :         const struct ucode *uc;
    1805           0 :         struct fxp_cb_ucode *cbp = &sc->sc_ctrl->u.code;
    1806             :         int i, error;
    1807             : 
    1808           0 :         if (sc->sc_flags & FXPF_NOUCODE)
    1809           0 :                 return;
    1810             : 
    1811           0 :         for (uc = ucode_table; uc->revision != 0; uc++)
    1812           0 :                 if (sc->sc_revision == uc->revision)
    1813             :                         break;
    1814           0 :         if (uc->revision == 0) {
    1815           0 :                 sc->sc_flags |= FXPF_NOUCODE;
    1816           0 :                 return; /* no ucode for this chip is found */
    1817             :         }
    1818             : 
    1819           0 :         if (sc->sc_ucodebuf)
    1820             :                 goto reloadit;
    1821             : 
    1822           0 :         if (sc->sc_revision == FXP_REV_82550_C) {
    1823           0 :                 u_int16_t data;
    1824             : 
    1825             :                 /*
    1826             :                  * 82550C without the server extensions
    1827             :                  * locks up with the microcode patch.
    1828             :                  */
    1829           0 :                 fxp_read_eeprom(sc, &data, FXP_EEPROM_REG_COMPAT, 1);
    1830           0 :                 if ((data & FXP_EEPROM_REG_COMPAT_SRV) == 0) {
    1831           0 :                         sc->sc_flags |= FXPF_NOUCODE;
    1832           0 :                         return;
    1833             :                 }
    1834           0 :         }
    1835             : 
    1836           0 :         error = loadfirmware(uc->uname, (u_char **)&sc->sc_ucodebuf,
    1837           0 :             &sc->sc_ucodelen);
    1838           0 :         if (error) {
    1839           0 :                 printf("%s: error %d, could not read firmware %s\n",
    1840           0 :                     sc->sc_dev.dv_xname, error, uc->uname);
    1841           0 :                 return;
    1842             :         }
    1843             : 
    1844             : reloadit:
    1845           0 :         if (sc->sc_flags & FXPF_UCODELOADED)
    1846           0 :                 return;
    1847             : 
    1848           0 :         cbp->cb_status = 0;
    1849           0 :         cbp->cb_command = htole16(FXP_CB_COMMAND_UCODE|FXP_CB_COMMAND_EL);
    1850           0 :         cbp->link_addr = 0xffffffff; /* (no) next command */
    1851           0 :         for (i = 0; i < (sc->sc_ucodelen / sizeof(u_int32_t)); i++)
    1852           0 :                 cbp->ucode[i] = sc->sc_ucodebuf[i];
    1853             : 
    1854           0 :         if (uc->int_delay_offset)
    1855           0 :                 *((u_int16_t *)&cbp->ucode[uc->int_delay_offset]) =
    1856           0 :                         htole16(sc->sc_int_delay + sc->sc_int_delay / 2);
    1857             : 
    1858           0 :         if (uc->bundle_max_offset)
    1859           0 :                 *((u_int16_t *)&cbp->ucode[uc->bundle_max_offset]) =
    1860           0 :                         htole16(sc->sc_bundle_max);
    1861             : 
    1862           0 :         if (uc->min_size_mask_offset)
    1863           0 :                 *((u_int16_t *)&cbp->ucode[uc->min_size_mask_offset]) =
    1864           0 :                         htole16(sc->sc_min_size_mask);
    1865             :         
    1866           0 :         FXP_UCODE_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1867             : 
    1868             :         /*
    1869             :          * Download the ucode to the chip.
    1870             :          */
    1871           0 :         fxp_scb_wait(sc);
    1872           0 :         CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr
    1873             :               + offsetof(struct fxp_ctrl, u.code));
    1874           0 :         fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
    1875             : 
    1876             :         /* ...and wait for it to complete. */
    1877             :         i = FXP_CMD_TMO;
    1878           0 :         do {
    1879           0 :                 DELAY(2);
    1880           0 :                 FXP_UCODE_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1881           0 :         } while (((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0) && --i);
    1882           0 :         if (i == 0) {
    1883           0 :                 printf("%s: timeout loading microcode\n", sc->sc_dev.dv_xname);
    1884           0 :                 return;
    1885             :         }
    1886           0 :         sc->sc_flags |= FXPF_UCODELOADED;
    1887             : 
    1888             : #ifdef DEBUG
    1889             :         printf("%s: microcode loaded, int_delay: %d usec",
    1890             :             sc->sc_dev.dv_xname, sc->sc_int_delay);
    1891             : 
    1892             :         if (uc->bundle_max_offset)
    1893             :                 printf(", bundle_max %d\n", sc->sc_bundle_max);
    1894             :         else
    1895             :                 printf("\n");
    1896             : #endif
    1897           0 : }
    1898             : #endif /* SMALL_KERNEL */

Generated by: LCOV version 1.13