Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Apr 2003 23:24:55 +0200
From:      "bert01" <bert-vde@pandora.be>
To:        <questions@freebsd.org>
Subject:   question about freebsd install
Message-ID:  <001501c2ffa7$a31970d0$0100000a@bert>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

------=_NextPart_000_0011_01C2FFB8.64D15160
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

HEllo,

I'm installing freebsd 5.0 from the boot discs... Everything goed fine, =
but my network card 's driver is not attached, now I have a disc with my =
network card and on that disc there's a map "freebsd" in that map There =
are 3 files:=20
IF_FET.C  =20
if_fetreg.h
readme.txt
-> they are attached to this email

Now how can I make my ethernet work so I can install freebsd with ftp?

Greetz Bert


------=_NextPart_000_0011_01C2FFB8.64D15160
Content-Type: text/plain;
	name="README.TXT"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="README.TXT"


Installation:

  1. copy the source codes if_fet.c and if_fetreg.h to /sys/pci =
directory,

        #cp if_fet.c /sys/pci
        #cp if_fetreg.h /sys/pci

  2. modify /sys/conf/files, add the following line

        pci/if_fet.c     optional       fet      device-driver

  3. modify /usr/src/sys/i386/conf/GENERIC, add the following line

        device  fet0

  4. compile the kernel,

        #cd /usr/src/sys/i386/conf
        #cp GENERIC MYKERNEL
        #/usr/sbin/config MYKERNEL
        #cd /usr/src/sys/compile/MYKERNEL
        #make depend
        #make
        #make install

  5. reboot the system,

        #reboot

  6. bind your card to an IP address

        #ifconfig fet0 ${IPADDR} broadcast ${BROADCAST} netmask =
${NETMASK}

  7. now, you should be able to ping local network.
=1A
------=_NextPart_000_0011_01C2FFB8.64D15160
Content-Type: application/octet-stream;
	name="IF_FET.C"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="IF_FET.C"

/*=0A=
 * fast ethernet PCI NIC driver=0A=
 */=0A=
=0A=
#include "bpfilter.h"=0A=
=0A=
#include <sys/param.h>=0A=
#include <sys/systm.h>=0A=
#include <sys/sockio.h>=0A=
#include <sys/mbuf.h>=0A=
#include <sys/malloc.h>=0A=
#include <sys/kernel.h>=0A=
#include <sys/socket.h>=0A=
=0A=
#include <net/if.h>=0A=
#include <net/if_arp.h>=0A=
#include <net/ethernet.h>=0A=
#include <net/if_dl.h>=0A=
#include <net/if_media.h>=0A=
=0A=
#if NBPFILTER > 0=0A=
#include <net/bpf.h>=0A=
#endif=0A=
=0A=
#include <vm/vm.h>              /* for vtophys */=0A=
#include <vm/pmap.h>            /* for vtophys */=0A=
#include <machine/clock.h>      /* for DELAY */=0A=
#include <machine/bus_memio.h>=0A=
#include <machine/bus_pio.h>=0A=
#include <machine/bus.h>=0A=
=0A=
#include <pci/pcireg.h>=0A=
#include <pci/pcivar.h>=0A=
=0A=
/*=0A=
#define FET_USEIOSPACE=0A=
*/=0A=
static int FET_USEIOSPACE=3D1;=0A=
=0A=
#include <pci/if_fetreg.h>=0A=
=0A=
#ifndef lint=0A=
static const char rcsid[] =3D=0A=
        "$Id: if_fet.c,v 1.30 2000/12/29 09:28:52 wpaul Exp $";=0A=
#endif=0A=
=0A=
/*=0A=
 * Various supported device vendors/types and their names.=0A=
 */=0A=
struct fet_type *fet_info_tmp;=0A=
static struct fet_type fet_devs[] =3D {=0A=
        { FETVENDORID, ID0, "100/10M Ethernet PCI Adapter" },=0A=
        { FETVENDORID, ID1, "100/10M Ethernet PCI Adapter" },=0A=
        { FETVENDORID, ID2, "1000/100/10M Ethernet PCI Adapter" },=0A=
        { 0, 0, NULL }=0A=
};=0A=
=0A=
/*=0A=
 * Various supported PHY vendors/types and their names. Note that=0A=
 * this driver will work with pretty much any MII-compliant PHY,=0A=
 * so failure to positively identify the chip is not a fatal error.=0A=
 */=0A=
static struct fet_type fet_phys[] =3D {=0A=
        { MysonPHYID0, MysonPHYID0, "<MYSON MTD981>"},=0A=
        { SeeqPHYID0, SeeqPHYID0, "<SEEQ 80225>" },=0A=
        { AhdocPHYID0, AhdocPHYID0, "<AHDOC 101>" },=0A=
        { MarvellPHYID0, MarvellPHYID0, "<MARVELL 88E1000>"},=0A=
        { LevelOnePHYID0, LevelOnePHYID0, "<LevelOne LXT1000>"},=0A=
        { 0, 0, "<MII-compliant physical interface>" }=0A=
};=0A=
=0A=
static unsigned long fet_count =3D 0;=0A=
=0A=
static const char *fet_probe __P((pcici_t, pcidi_t));=0A=
static void fet_attach __P((pcici_t, int));=0A=
static int fet_newbuf __P((struct fet_softc *, struct fet_chain_onefrag =
*));=0A=
static int fet_encap __P((struct fet_softc *, struct fet_chain *,=0A=
                             struct mbuf *));=0A=
static void fet_rxeof __P((struct fet_softc *));=0A=
static void fet_txeof __P((struct fet_softc *));=0A=
static void fet_txeoc __P((struct fet_softc *));=0A=
static void fet_intr __P((void *));=0A=
static void fet_start __P((struct ifnet *));=0A=
static int fet_ioctl __P((struct ifnet *, u_long, caddr_t));=0A=
static void fet_init __P((void *));=0A=
static void fet_stop __P((struct fet_softc *));=0A=
static void fet_watchdog __P((struct ifnet *));=0A=
static void fet_shutdown __P((int, void *));=0A=
static int fet_ifmedia_upd __P((struct ifnet *));=0A=
static void fet_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));=0A=
static u_int16_t fet_phy_readreg __P((struct fet_softc *, int));=0A=
static void fet_phy_writereg __P((struct fet_softc *, int, int));=0A=
static void fet_autoneg_xmit __P((struct fet_softc *));=0A=
static void fet_autoneg_mii __P((struct fet_softc *, int, int));=0A=
static void fet_setmode_mii __P((struct fet_softc *, int));=0A=
static void fet_getmode_mii __P((struct fet_softc *));=0A=
static void fet_setcfg __P((struct fet_softc *, int));=0A=
static u_int8_t fet_calchash __P((caddr_t));=0A=
static void fet_setmulti __P((struct fet_softc *));=0A=
static void fet_reset __P((struct fet_softc *));=0A=
static int fet_list_rx_init __P((struct fet_softc *));=0A=
static int fet_list_tx_init __P((struct fet_softc *));=0A=
static long fet_send_cmd_to_phy __P((struct fet_softc *, int, int));=0A=
=0A=
#define FET_SETBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) =
| x)=0A=
#define FET_CLRBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) =
& ~x)=0A=
=0A=
=0A=
static long fet_send_cmd_to_phy(sc, opcode, regad)=0A=
struct fet_softc *sc;=0A=
int opcode;=0A=
int regad;=0A=
{=0A=
   long miir;=0A=
   int  i;=0A=
   int mask, data;=0A=
=0A=
   /* enable MII output */=0A=
   miir=3DCSR_READ_4(sc, FET_MANAGEMENT);=0A=
   miir&=3D0xfffffff0;=0A=
=0A=
   miir|=3DFET_MASK_MIIR_MII_WRITE+FET_MASK_MIIR_MII_MDO;=0A=
=0A=
   /* send 32 1's preamble */=0A=
   for (i=3D0;i<32;i++)=0A=
   {=0A=
      /* low MDC; MDO is already high (miir) */=0A=
      miir&=3D~FET_MASK_MIIR_MII_MDC;=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
=0A=
      /* high MDC */=0A=
      miir|=3DFET_MASK_MIIR_MII_MDC;=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
   }=0A=
=0A=
   /* calculate ST+OP+PHYAD+REGAD+TA */=0A=
   data=3Dopcode|(sc->fet_phy_addr<<7)|(regad<<2);=0A=
=0A=
   /* sent out */=0A=
   mask=3D0x8000;=0A=
   while (mask)=0A=
   {=0A=
      /* low MDC, prepare MDO */=0A=
      miir&=3D~(FET_MASK_MIIR_MII_MDC+FET_MASK_MIIR_MII_MDO);=0A=
      if (mask & data)=0A=
        miir|=3DFET_MASK_MIIR_MII_MDO;=0A=
=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
      /* high MDC */=0A=
      miir|=3DFET_MASK_MIIR_MII_MDC;=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
      DELAY(30);=0A=
=0A=
      /* next */=0A=
      mask>>=3D1;=0A=
      if (mask=3D=3D0x2 && opcode=3D=3DFET_OP_READ)=0A=
        miir&=3D~FET_MASK_MIIR_MII_WRITE;=0A=
   }=0A=
   return miir;=0A=
}=0A=
=0A=
=0A=
static u_int16_t fet_phy_readreg(sc, reg)=0A=
struct fet_softc *sc;=0A=
int reg;=0A=
{=0A=
   long miir;=0A=
   int mask, data;=0A=
=0A=
   if (sc->fet_info->fet_did =3D=3D ID1)=0A=
     data =3D CSR_READ_2(sc, FET_PHYBASE+reg*2);=0A=
   else=0A=
   {=0A=
      miir=3Dfet_send_cmd_to_phy(sc, FET_OP_READ, reg);=0A=
=0A=
      /* read data */=0A=
      mask=3D0x8000;=0A=
      data=3D0;=0A=
      while (mask)=0A=
      {=0A=
         /* low MDC */=0A=
         miir&=3D~FET_MASK_MIIR_MII_MDC;=0A=
         CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
=0A=
         /* read MDI */=0A=
         miir=3DCSR_READ_4(sc, FET_MANAGEMENT);=0A=
         if (miir & FET_MASK_MIIR_MII_MDI)=0A=
           data|=3Dmask;=0A=
=0A=
         /* high MDC, and wait */=0A=
         miir|=3DFET_MASK_MIIR_MII_MDC;=0A=
         CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
         DELAY(30);=0A=
=0A=
         /* next */=0A=
         mask>>=3D1;=0A=
      }=0A=
=0A=
      /* low MDC */=0A=
      miir&=3D~FET_MASK_MIIR_MII_MDC;=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
   }=0A=
=0A=
   return (u_int16_t)data;=0A=
}=0A=
=0A=
=0A=
static void fet_phy_writereg(sc, reg, data)=0A=
struct fet_softc *sc;=0A=
int reg;=0A=
int data;=0A=
{=0A=
   long miir;=0A=
   int mask;=0A=
=0A=
   if (sc->fet_info->fet_did =3D=3D ID1)=0A=
     CSR_WRITE_2(sc, FET_PHYBASE+reg*2, data);=0A=
   else=0A=
   {=0A=
      miir=3Dfet_send_cmd_to_phy(sc, FET_OP_WRITE, reg);=0A=
=0A=
      /* write data */=0A=
      mask=3D0x8000;=0A=
      while (mask)=0A=
      {=0A=
         /* low MDC, prepare MDO */=0A=
         miir&=3D~(FET_MASK_MIIR_MII_MDC+FET_MASK_MIIR_MII_MDO);=0A=
         if (mask&data)=0A=
           miir|=3DFET_MASK_MIIR_MII_MDO;=0A=
         CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
	 DELAY(1);=0A=
=0A=
         /* high MDC */=0A=
         miir|=3DFET_MASK_MIIR_MII_MDC;=0A=
         CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
         DELAY(1);=0A=
=0A=
         /* next */=0A=
         mask>>=3D1;=0A=
      }=0A=
=0A=
      /* low MDC */=0A=
      miir&=3D~FET_MASK_MIIR_MII_MDC;=0A=
      CSR_WRITE_4(sc, FET_MANAGEMENT, miir);=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static u_int8_t fet_calchash(addr)=0A=
caddr_t addr;=0A=
{=0A=
   u_int32_t crc, carry;=0A=
   int i, j;=0A=
   u_int8_t c;=0A=
=0A=
   /* Compute CRC for the address value. */=0A=
   crc =3D 0xFFFFFFFF; /* initial value */=0A=
=0A=
   for (i =3D 0; i < 6; i++)=0A=
   {=0A=
      c =3D *(addr + i);=0A=
      for (j =3D 0; j < 8; j++)=0A=
      {=0A=
         carry =3D ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);=0A=
         crc <<=3D 1;=0A=
         c >>=3D 1;=0A=
         if (carry)=0A=
           crc =3D (crc ^ 0x04c11db6) | carry;=0A=
      }=0A=
   }=0A=
=0A=
   /*=0A=
    * return the filter bit position=0A=
    * Note: I arrived at the following nonsense=0A=
    * through experimentation. It's not the usual way to=0A=
    * generate the bit position but it's the only thing=0A=
    * I could come up with that works.=0A=
    */=0A=
   return(~(crc >> 26) & 0x0000003F);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Program the 64-bit multicast hash filter.=0A=
 */=0A=
static void fet_setmulti(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct ifnet *ifp;=0A=
   int h =3D 0;=0A=
   u_int32_t hashes[2] =3D { 0, 0 };=0A=
   struct ifmultiaddr *ifma;=0A=
   u_int32_t rxfilt;=0A=
   int mcnt =3D 0;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   rxfilt =3D CSR_READ_4(sc, FET_TCRRCR);=0A=
=0A=
   if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC)=0A=
   {=0A=
      rxfilt |=3D FET_AM;=0A=
      CSR_WRITE_4(sc, FET_TCRRCR, rxfilt);=0A=
      CSR_WRITE_4(sc, FET_MAR0, 0xFFFFFFFF);=0A=
      CSR_WRITE_4(sc, FET_MAR1, 0xFFFFFFFF);=0A=
      return;=0A=
   }=0A=
=0A=
   /* first, zot all the existing hash bits */=0A=
   CSR_WRITE_4(sc, FET_MAR0, 0);=0A=
   CSR_WRITE_4(sc, FET_MAR1, 0);=0A=
=0A=
   /* now program new ones */=0A=
   for (ifma =3D ifp->if_multiaddrs.lh_first; ifma !=3D NULL;=0A=
        ifma =3D ifma->ifma_link.le_next)=0A=
   {=0A=
      if (ifma->ifma_addr->sa_family !=3D AF_LINK)=0A=
        continue;=0A=
      h =3D fet_calchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));=0A=
      if (h < 32)=0A=
        hashes[0] |=3D (1 << h);=0A=
      else=0A=
        hashes[1] |=3D (1 << (h - 32));=0A=
      mcnt++;=0A=
   }=0A=
=0A=
   if (mcnt)=0A=
     rxfilt |=3D FET_AM;=0A=
   else=0A=
     rxfilt &=3D ~FET_AM;=0A=
=0A=
   CSR_WRITE_4(sc, FET_MAR0, hashes[0]);=0A=
   CSR_WRITE_4(sc, FET_MAR1, hashes[1]);=0A=
   CSR_WRITE_4(sc, FET_TCRRCR, rxfilt);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Initiate an autonegotiation session.=0A=
 */=0A=
static void fet_autoneg_xmit(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   u_int16_t phy_sts;=0A=
=0A=
   fet_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);=0A=
   DELAY(500);=0A=
   while(fet_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_RESET);=0A=
=0A=
   phy_sts =3D fet_phy_readreg(sc, PHY_BMCR);=0A=
   phy_sts |=3D PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;=0A=
   fet_phy_writereg(sc, PHY_BMCR, phy_sts);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Invoke autonegotiation on a PHY.=0A=
 */=0A=
static void fet_autoneg_mii(sc, flag, verbose)=0A=
struct fet_softc *sc;=0A=
int flag;=0A=
int verbose;=0A=
{=0A=
   u_int16_t phy_sts =3D 0, media, advert, ability;=0A=
   u_int16_t ability2 =3D 0;=0A=
   struct ifnet *ifp;=0A=
   struct ifmedia *ifm;=0A=
=0A=
   ifm =3D &sc->ifmedia;=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   ifm->ifm_media =3D IFM_ETHER | IFM_AUTO;=0A=
=0A=
#ifndef FORCE_AUTONEG_TFOUR=0A=
   /*=0A=
    * First, see if autoneg is supported. If not, there's=0A=
    * no point in continuing.=0A=
    */=0A=
   phy_sts =3D fet_phy_readreg(sc, PHY_BMSR);=0A=
   if (!(phy_sts & PHY_BMSR_CANAUTONEG))=0A=
   {=0A=
      if (verbose)=0A=
        printf("fet%d: autonegotiation not supported\n", sc->fet_unit);=0A=
=0A=
      ifm->ifm_media =3D IFM_ETHER|IFM_10_T|IFM_HDX;=0A=
      return;=0A=
   }=0A=
#endif=0A=
=0A=
   switch (flag)=0A=
   {=0A=
      case FET_FLAG_FORCEDELAY:=0A=
        /*=0A=
         * XXX Never use this option anywhere but in the probe=0A=
         * routine: making the kernel stop dead in its tracks=0A=
         * for three whole seconds after we've gone multi-user=0A=
         * is really bad manners.=0A=
         */=0A=
        fet_autoneg_xmit(sc);=0A=
        DELAY(5000000);=0A=
        break;=0A=
      case FET_FLAG_SCHEDDELAY:=0A=
        /*=0A=
         * Wait for the transmitter to go idle before starting=0A=
         * an autoneg session, otherwise fet_start() may clobber=0A=
         * our timeout, and we don't want to allow transmission=0A=
         * during an autoneg session since that can screw it up.=0A=
         */=0A=
        if (sc->fet_cdata.fet_tx_head !=3D NULL)=0A=
        {=0A=
           sc->fet_want_auto =3D 1;=0A=
           return;=0A=
        }=0A=
        fet_autoneg_xmit(sc);=0A=
        ifp->if_timer =3D 5;=0A=
        sc->fet_autoneg =3D 1;=0A=
        sc->fet_want_auto =3D 0;=0A=
        return;=0A=
      case FET_FLAG_DELAYTIMEO:=0A=
        ifp->if_timer =3D 0;=0A=
        sc->fet_autoneg =3D 0;=0A=
        break;=0A=
      default:=0A=
        printf("fet%d: invalid autoneg flag: %d\n", sc->fet_unit, flag);=0A=
        return;=0A=
   }=0A=
=0A=
   if (fet_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP)=0A=
   {=0A=
      if (verbose)=0A=
        printf("fet%d: autoneg complete, ", sc->fet_unit);=0A=
=0A=
      phy_sts =3D fet_phy_readreg(sc, PHY_BMSR);=0A=
   }=0A=
   else=0A=
   {=0A=
      if (verbose)=0A=
        printf("fet%d: autoneg not complete, ", sc->fet_unit);=0A=
   }=0A=
=0A=
   media =3D fet_phy_readreg(sc, PHY_BMCR);=0A=
=0A=
   /* Link is good. Report modes and set duplex mode. */=0A=
   if (fet_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)=0A=
   {=0A=
      if (verbose)=0A=
        printf("fet%d: link status good. ", sc->fet_unit);=0A=
=0A=
      advert =3D fet_phy_readreg(sc, PHY_ANAR);=0A=
      ability =3D fet_phy_readreg(sc, PHY_LPAR);=0A=
=0A=
      if ( (sc->fet_pinfo->fet_vid =3D=3D MarvellPHYID0) ||=0A=
          (sc->fet_pinfo->fet_vid =3D=3D LevelOnePHYID0) )=0A=
      {=0A=
         ability2 =3D fet_phy_readreg(sc, PHY_1000SR);=0A=
=0A=
         if (ability2 & PHY_1000SR_1000BTXFULL)=0A=
         {=0A=
            advert =3D 0;=0A=
            ability =3D 0;=0A=
/* this version did not support 1000M,=0A=
            ifm->ifm_media =3D IFM_ETHER|IFM_1000_TX|IFM_FDX;=0A=
*/=0A=
	    ifm->ifm_media =3D IFM_ETHER|IFM_100_TX|IFM_FDX;=0A=
            media &=3D ~PHY_BMCR_SPEEDSEL;=0A=
            media |=3D PHY_BMCR_1000;=0A=
            media |=3D PHY_BMCR_DUPLEX;=0A=
            printf("(full-duplex, 1000Mbps)\n");=0A=
         }=0A=
         else if (ability2 & PHY_1000SR_1000BTXHALF)=0A=
         {=0A=
            advert =3D 0;=0A=
            ability =3D 0;=0A=
/* this version did not support 1000M,=0A=
            ifm->ifm_media =3D IFM_ETHER|IFM_1000_TX;=0A=
*/=0A=
	    ifm->ifm_media =3D IFM_ETHER|IFM_100_TX;	=0A=
            media &=3D ~PHY_BMCR_SPEEDSEL;=0A=
            media &=3D ~PHY_BMCR_DUPLEX;=0A=
            media |=3D PHY_BMCR_1000;=0A=
            printf("(half-duplex, 1000Mbps)\n");=0A=
         }=0A=
      }=0A=
=0A=
      if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4)=0A=
      {=0A=
         ifm->ifm_media =3D IFM_ETHER|IFM_100_T4;=0A=
         media |=3D PHY_BMCR_SPEEDSEL;=0A=
         media &=3D ~PHY_BMCR_DUPLEX;=0A=
         printf("(100baseT4)\n");=0A=
      }=0A=
      else if (advert & PHY_ANAR_100BTXFULL && ability & =
PHY_ANAR_100BTXFULL)=0A=
      {=0A=
         ifm->ifm_media =3D IFM_ETHER|IFM_100_TX|IFM_FDX;=0A=
         media |=3D PHY_BMCR_SPEEDSEL;=0A=
         media |=3D PHY_BMCR_DUPLEX;=0A=
         printf("(full-duplex, 100Mbps)\n");=0A=
      }=0A=
      else if (advert & PHY_ANAR_100BTXHALF && ability & =
PHY_ANAR_100BTXHALF)=0A=
      {=0A=
         ifm->ifm_media =3D IFM_ETHER|IFM_100_TX|IFM_HDX;=0A=
         media |=3D PHY_BMCR_SPEEDSEL;=0A=
         media &=3D ~PHY_BMCR_DUPLEX;=0A=
         printf("(half-duplex, 100Mbps)\n");=0A=
      }=0A=
      else if (advert & PHY_ANAR_10BTFULL && ability & PHY_ANAR_10BTFULL)=0A=
      {=0A=
         ifm->ifm_media =3D IFM_ETHER|IFM_10_T|IFM_FDX;=0A=
         media &=3D ~PHY_BMCR_SPEEDSEL;=0A=
         media |=3D PHY_BMCR_DUPLEX;=0A=
         printf("(full-duplex, 10Mbps)\n");=0A=
      }=0A=
      else if (advert)=0A=
      {=0A=
         ifm->ifm_media =3D IFM_ETHER|IFM_10_T|IFM_HDX;=0A=
         media &=3D ~PHY_BMCR_SPEEDSEL;=0A=
         media &=3D ~PHY_BMCR_DUPLEX;=0A=
         printf("(half-duplex, 10Mbps)\n");=0A=
      }=0A=
=0A=
      media &=3D ~PHY_BMCR_AUTONEGENBL;=0A=
=0A=
      /* Set ASIC's duplex mode to match the PHY. */=0A=
      fet_phy_writereg(sc, PHY_BMCR, media);=0A=
      fet_setcfg(sc, media);=0A=
   }=0A=
   else=0A=
   {=0A=
      if (verbose)=0A=
        printf("fet%d: no carrier\n", sc->fet_unit);=0A=
   }=0A=
=0A=
   fet_init(sc);=0A=
=0A=
   if (sc->fet_tx_pend)=0A=
   {=0A=
      sc->fet_autoneg =3D 0;=0A=
      sc->fet_tx_pend =3D 0;=0A=
      fet_start(ifp);=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * To get PHY ability.=0A=
 */=0A=
static void fet_getmode_mii(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   u_int16_t bmsr;=0A=
   struct ifnet *ifp;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   bmsr =3D fet_phy_readreg(sc, PHY_BMSR);=0A=
   if (bootverbose)=0A=
     printf("fet%d: PHY status word: %x\n", sc->fet_unit, bmsr);=0A=
=0A=
   /* fallback */=0A=
   sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_10_T|IFM_HDX;=0A=
=0A=
   if (bmsr & PHY_BMSR_10BTHALF)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 10Mbps half-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);=0A=
   }=0A=
=0A=
   if (bmsr & PHY_BMSR_10BTFULL)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 10Mbps full-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_10_T|IFM_FDX;=0A=
   }=0A=
=0A=
   if (bmsr & PHY_BMSR_100BTXHALF)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 100Mbps half-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifp->if_baudrate =3D 100000000;=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_100_TX|IFM_HDX;=0A=
   }=0A=
=0A=
   if (bmsr & PHY_BMSR_100BTXFULL)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 100Mbps full-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifp->if_baudrate =3D 100000000;=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_100_TX|IFM_FDX;=0A=
   }=0A=
=0A=
   /* Some also support 100BaseT4. */=0A=
   if (bmsr & PHY_BMSR_100BT4)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 100baseT4 mode supported\n", sc->fet_unit);=0A=
=0A=
      ifp->if_baudrate =3D 100000000;=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_T4, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_100_T4;=0A=
#ifdef FORCE_AUTONEG_TFOUR=0A=
      if (bootverbose)=0A=
        printf("fet%d: forcing on autoneg support for BT4\n", =
sc->fet_unit);=0A=
=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0 NULL):=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_AUTO;=0A=
#endif=0A=
   }=0A=
=0A=
/* this version did not support 1000M,=0A=
   if (sc->fet_pinfo->fet_vid =3D=3D MarvellPHYID0)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: 1000Mbps half-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifp->if_baudrate =3D 1000000000;=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_TX, 0, NULL);=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_TX|IFM_HDX, 0, NULL);=0A=
=0A=
      if (bootverbose)=0A=
        printf("fet%d: 1000Mbps full-duplex mode supported\n", =
sc->fet_unit);=0A=
=0A=
      ifp->if_baudrate =3D 1000000000;=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_TX|IFM_FDX, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_1000_TX|IFM_FDX;=0A=
   }=0A=
*/=0A=
=0A=
   if (bmsr & PHY_BMSR_CANAUTONEG)=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: autoneg supported\n", sc->fet_unit);=0A=
=0A=
      ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);=0A=
      sc->ifmedia.ifm_media =3D IFM_ETHER|IFM_AUTO;=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Set speed and duplex mode.=0A=
 */=0A=
static void fet_setmode_mii(sc, media)=0A=
struct fet_softc *sc;=0A=
int media;=0A=
{=0A=
   u_int16_t bmcr;=0A=
   struct ifnet *ifp;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
printf("enter fet_setmode_mii()\n");=0A=
=0A=
   /*=0A=
    * If an autoneg session is in progress, stop it.=0A=
    */=0A=
   if (sc->fet_autoneg)=0A=
   {=0A=
      printf("fet%d: canceling autoneg session\n", sc->fet_unit);=0A=
      ifp->if_timer =3D sc->fet_autoneg =3D sc->fet_want_auto =3D 0;=0A=
      bmcr =3D fet_phy_readreg(sc, PHY_BMCR);=0A=
      bmcr &=3D ~PHY_BMCR_AUTONEGENBL;=0A=
      fet_phy_writereg(sc, PHY_BMCR, bmcr);=0A=
   }=0A=
=0A=
   printf("fet%d: selecting MII, ", sc->fet_unit);=0A=
=0A=
   bmcr =3D fet_phy_readreg(sc, PHY_BMCR);=0A=
=0A=
   bmcr &=3D ~(PHY_BMCR_AUTONEGENBL|PHY_BMCR_SPEEDSEL|PHY_BMCR_1000|=0A=
             PHY_BMCR_DUPLEX|PHY_BMCR_LOOPBK);=0A=
=0A=
/* this version did not support 1000M,=0A=
   if (IFM_SUBTYPE(media) =3D=3D IFM_1000_TX)=0A=
   {=0A=
      printf("1000Mbps/T4, half-duplex\n");=0A=
      bmcr &=3D ~PHY_BMCR_SPEEDSEL;=0A=
      bmcr &=3D ~PHY_BMCR_DUPLEX;=0A=
      bmcr |=3D PHY_BMCR_1000;=0A=
   }=0A=
*/=0A=
=0A=
   if (IFM_SUBTYPE(media) =3D=3D IFM_100_T4)=0A=
   {=0A=
      printf("100Mbps/T4, half-duplex\n");=0A=
      bmcr |=3D PHY_BMCR_SPEEDSEL;=0A=
      bmcr &=3D ~PHY_BMCR_DUPLEX;=0A=
   }=0A=
=0A=
   if (IFM_SUBTYPE(media) =3D=3D IFM_100_TX)=0A=
   {=0A=
      printf("100Mbps, ");=0A=
      bmcr |=3D PHY_BMCR_SPEEDSEL;=0A=
   }=0A=
=0A=
   if (IFM_SUBTYPE(media) =3D=3D IFM_10_T)=0A=
   {=0A=
      printf("10Mbps, ");=0A=
      bmcr &=3D ~PHY_BMCR_SPEEDSEL;=0A=
   }=0A=
=0A=
   if ((media & IFM_GMASK) =3D=3D IFM_FDX)=0A=
   {=0A=
      printf("full duplex\n");=0A=
      bmcr |=3D PHY_BMCR_DUPLEX;=0A=
   }=0A=
   else=0A=
   {=0A=
      printf("half duplex\n");=0A=
      bmcr &=3D ~PHY_BMCR_DUPLEX;=0A=
   }=0A=
=0A=
   fet_phy_writereg(sc, PHY_BMCR, bmcr);=0A=
   fet_setcfg(sc, bmcr);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * The Myson manual states that in order to fiddle with the=0A=
 * 'full-duplex' and '100Mbps' bits in the netconfig register, we=0A=
 * first have to put the transmit and/or receive logic in the idle state.=0A=
 */=0A=
static void fet_setcfg(sc, bmcr)=0A=
struct fet_softc *sc;=0A=
int bmcr;=0A=
{=0A=
   int i, restart =3D 0;=0A=
=0A=
   if (CSR_READ_4(sc, FET_TCRRCR) & (FET_TE|FET_RE))=0A=
   {=0A=
      restart =3D 1;=0A=
      FET_CLRBIT(sc, FET_TCRRCR, (FET_TE|FET_RE));=0A=
=0A=
      for (i =3D 0; i < FET_TIMEOUT; i++)=0A=
      {=0A=
         DELAY(10);=0A=
         if (!(CSR_READ_4(sc, FET_TCRRCR)&(FET_TXRUN|FET_RXRUN)))=0A=
           break;=0A=
      }=0A=
=0A=
      if (i =3D=3D FET_TIMEOUT)=0A=
        printf("fet%d: failed to force tx and rx to idle state\n",=0A=
                sc->fet_unit);=0A=
   }=0A=
=0A=
   FET_CLRBIT(sc, FET_TCRRCR, FET_PS1000);=0A=
   FET_CLRBIT(sc, FET_TCRRCR, FET_PS10);=0A=
   if (bmcr & PHY_BMCR_1000)=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_PS1000);=0A=
   else if (!(bmcr & PHY_BMCR_SPEEDSEL))=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_PS10);=0A=
=0A=
   if (bmcr & PHY_BMCR_DUPLEX)=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_FD);=0A=
   else=0A=
     FET_CLRBIT(sc, FET_TCRRCR, FET_FD);=0A=
=0A=
   if (restart)=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_TE|FET_RE);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static void fet_reset(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   register int i;=0A=
=0A=
   FET_SETBIT(sc, FET_BCR, FET_SWR);=0A=
=0A=
   for (i =3D 0; i < FET_TIMEOUT; i++)=0A=
   {=0A=
      DELAY(10);=0A=
      if (!(CSR_READ_4(sc, FET_BCR) & FET_SWR))=0A=
        break;=0A=
   }=0A=
   if (i =3D=3D FET_TIMEOUT)=0A=
     printf("m0x%d: reset never completed!\n", sc->fet_unit);=0A=
=0A=
   /* Wait a little while for the chip to get its brains in order. */=0A=
   DELAY(1000);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Probe for a Myson chip. Check the PCI vendor and device=0A=
 * IDs against our list and return a device name if we find a match.=0A=
 */=0A=
static const char *fet_probe(config_id, device_id)=0A=
pcici_t config_id;=0A=
pcidi_t device_id;=0A=
{=0A=
   struct fet_type *t;=0A=
=0A=
   t =3D fet_devs;=0A=
=0A=
   while(t->fet_name !=3D NULL)=0A=
   {=0A=
      if ((device_id & 0xFFFF) =3D=3D t->fet_vid &&=0A=
          ((device_id >> 16) & 0xFFFF) =3D=3D t->fet_did)=0A=
      {=0A=
         fet_info_tmp =3D t;=0A=
        return(t->fet_name);=0A=
      }=0A=
      t++;=0A=
   }=0A=
=0A=
   return(NULL);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Attach the interface. Allocate softc structures, do ifmedia=0A=
 * setup and ethernet/BPF attach.=0A=
 */=0A=
static void fet_attach(config_id, unit)=0A=
pcici_t config_id;=0A=
int unit;=0A=
{=0A=
   int s, i;=0A=
   vm_offset_t pbase, vbase;=0A=
   u_char eaddr[ETHER_ADDR_LEN];=0A=
   u_int32_t command, iobase;=0A=
   struct fet_softc *sc;=0A=
   struct ifnet *ifp;=0A=
   int media =3D IFM_ETHER|IFM_100_TX|IFM_FDX;=0A=
   unsigned int round;=0A=
   caddr_t roundptr;=0A=
   struct fet_type *p;=0A=
   u_int16_t phy_vid, phy_did, phy_sts;=0A=
=0A=
   s =3D splimp();=0A=
=0A=
   sc =3D malloc(sizeof(struct fet_softc), M_DEVBUF, M_NOWAIT);=0A=
   if (sc =3D=3D NULL)=0A=
   {=0A=
      printf("fet%d: no memory for softc struct!\n", unit);=0A=
      return;=0A=
   }=0A=
   bzero(sc, sizeof(struct fet_softc));=0A=
=0A=
   /*=0A=
    * Map control/status registers.=0A=
    */=0A=
   command =3D pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);=0A=
   command |=3D (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);=0A=
   pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command);=0A=
   command =3D pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);=0A=
=0A=
   if (fet_info_tmp->fet_did=3D=3DID0)=0A=
   {=0A=
      iobase =3D pci_conf_read(config_id, FET_PCI_LOIO);=0A=
      if (iobase & 0x300)=0A=
        FET_USEIOSPACE=3D0;=0A=
   }=0A=
=0A=
if (FET_USEIOSPACE)=0A=
{=0A=
   if (!(command & PCIM_CMD_PORTEN))=0A=
   {=0A=
      printf("fet%d: failed to enable I/O ports!\n", unit);=0A=
      free(sc, M_DEVBUF);=0A=
      goto fail;=0A=
   }=0A=
=0A=
   if (!pci_map_port(config_id, FET_PCI_LOIO, (u_int16_t =
*)&(sc->fet_bhandle)))=0A=
   {=0A=
      printf ("fet%d: couldn't map ports\n", unit);=0A=
      goto fail;=0A=
   }=0A=
   sc->fet_btag =3D I386_BUS_SPACE_IO;=0A=
}=0A=
else=0A=
{=0A=
   if (!(command & PCIM_CMD_MEMEN))=0A=
   {=0A=
      printf("fet%d: failed to enable memory mapping!\n", unit);=0A=
      goto fail;=0A=
   }=0A=
=0A=
   if (!pci_map_mem(config_id, FET_PCI_LOMEM, &vbase, &pbase))=0A=
   {=0A=
      printf ("fet%d: couldn't map memory\n", unit);=0A=
      goto fail;=0A=
   }=0A=
/*=0A=
   sc->csr =3D (volatile caddr_t)vbase;=0A=
*/=0A=
   sc->fet_btag =3D I386_BUS_SPACE_MEM;=0A=
   sc->fet_bhandle =3D vbase;=0A=
}=0A=
=0A=
   /* Allocate interrupt */=0A=
   if (!pci_map_int(config_id, fet_intr, sc, &net_imask))=0A=
   {=0A=
      printf("fet%d: couldn't map interrupt\n", unit);=0A=
      goto fail;=0A=
   }=0A=
=0A=
   sc->fet_info =3D fet_info_tmp;=0A=
=0A=
   /* Reset the adapter. */=0A=
   fet_reset(sc);=0A=
=0A=
   /*=0A=
    * Get station address=0A=
    */=0A=
   for (i =3D 0; i < ETHER_ADDR_LEN; ++i)=0A=
     eaddr[i] =3D CSR_READ_1(sc, FET_PAR0+i);=0A=
=0A=
   /*=0A=
    * A Myson chip was detected. Inform the world.=0A=
    */=0A=
   printf("fet%d: Ethernet address: %6D\n", unit, eaddr, ":");=0A=
=0A=
   sc->fet_unit =3D unit;=0A=
   bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);=0A=
=0A=
   sc->fet_ldata_ptr =3D malloc(sizeof(struct fet_list_data) + 8,=0A=
                             M_DEVBUF, M_NOWAIT);=0A=
   if (sc->fet_ldata_ptr =3D=3D NULL)=0A=
   {=0A=
      free(sc, M_DEVBUF);=0A=
      printf("fet%d: no memory for list buffers!\n", unit);=0A=
      return;=0A=
   }=0A=
=0A=
   sc->fet_ldata =3D (struct fet_list_data *)sc->fet_ldata_ptr;=0A=
   round =3D (unsigned int)sc->fet_ldata_ptr & 0xF;=0A=
   roundptr =3D sc->fet_ldata_ptr;=0A=
   for (i =3D 0; i < 8; i++)=0A=
   {=0A=
      if (round % 8)=0A=
      {=0A=
         round++;=0A=
         roundptr++;=0A=
      }=0A=
      else=0A=
        break;=0A=
   }=0A=
   sc->fet_ldata =3D (struct fet_list_data *)roundptr;=0A=
   bzero(sc->fet_ldata, sizeof(struct fet_list_data));=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
   ifp->if_softc =3D sc;=0A=
   ifp->if_unit =3D unit;=0A=
   ifp->if_name =3D "fet";=0A=
   ifp->if_mtu =3D ETHERMTU;=0A=
   ifp->if_flags =3D IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;=0A=
   ifp->if_ioctl =3D fet_ioctl;=0A=
   ifp->if_output =3D ether_output;=0A=
   ifp->if_start =3D fet_start;=0A=
   ifp->if_watchdog =3D fet_watchdog;=0A=
   ifp->if_init =3D fet_init;=0A=
   ifp->if_baudrate =3D 10000000;=0A=
=0A=
   if (sc->fet_info->fet_did =3D=3D ID1)=0A=
     sc->fet_pinfo =3D fet_phys;=0A=
   else=0A=
   {=0A=
      if (bootverbose)=0A=
        printf("fet%d: probing for a PHY\n", sc->fet_unit);=0A=
      for (i =3D FET_PHYADDR_MIN; i < FET_PHYADDR_MAX + 1; i++)=0A=
      {=0A=
         if (bootverbose)=0A=
           printf("fet%d: checking address: %d\n", sc->fet_unit, i);=0A=
         sc->fet_phy_addr =3D i;=0A=
         phy_sts =3D fet_phy_readreg(sc, PHY_BMSR);=0A=
          if ( (phy_sts!=3D0)&&(phy_sts!=3D0xffff) )=0A=
            break;=0A=
          else=0A=
            phy_sts =3D 0;=0A=
      }=0A=
      if (phy_sts)=0A=
      {=0A=
         phy_vid =3D fet_phy_readreg(sc, PHY_VENID);=0A=
         phy_did =3D fet_phy_readreg(sc, PHY_DEVID);=0A=
         if (bootverbose)=0A=
         {=0A=
            printf("fet%d: found PHY at address %d, ",=0A=
                    sc->fet_unit, sc->fet_phy_addr);=0A=
            printf("vendor id: %x device id: %x\n", phy_vid, phy_did);=0A=
         }=0A=
=0A=
         p =3D fet_phys;=0A=
         while(p->fet_vid)=0A=
         {=0A=
            if (phy_vid =3D=3D p->fet_vid)=0A=
            {=0A=
               sc->fet_pinfo =3D p;=0A=
               break;=0A=
            }=0A=
            p++;=0A=
         }=0A=
         if (sc->fet_pinfo =3D=3D NULL)=0A=
           sc->fet_pinfo =3D &fet_phys[PHY_UNKNOWN];=0A=
         if (bootverbose)=0A=
           printf("fet%d: PHY type: %s\n",=0A=
                   sc->fet_unit, sc->fet_pinfo->fet_name);=0A=
      }=0A=
      else=0A=
      {=0A=
         printf("fet%d: MII without any phy!\n", sc->fet_unit);=0A=
         goto fail;=0A=
      }=0A=
   }=0A=
=0A=
   /*=0A=
    * Do ifmedia setup.=0A=
    */=0A=
   ifmedia_init(&sc->ifmedia, 0, fet_ifmedia_upd, fet_ifmedia_sts);=0A=
=0A=
   fet_getmode_mii(sc);=0A=
   fet_autoneg_mii(sc, FET_FLAG_FORCEDELAY, 1);=0A=
   media =3D sc->ifmedia.ifm_media;=0A=
   fet_stop(sc);=0A=
=0A=
   ifmedia_set(&sc->ifmedia, media);=0A=
=0A=
   /*=0A=
    * Call MI attach routines.=0A=
    */=0A=
   if_attach(ifp);=0A=
   ether_ifattach(ifp);=0A=
=0A=
#if NBPFILTER > 0=0A=
   bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));=0A=
#endif=0A=
   at_shutdown(fet_shutdown, sc, SHUTDOWN_POST_SYNC);=0A=
=0A=
fail:=0A=
   splx(s);=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Initialize the transmit descriptors.=0A=
 */=0A=
static int fet_list_tx_init(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct fet_chain_data *cd;=0A=
   struct fet_list_data *ld;=0A=
   int i;=0A=
=0A=
   cd =3D &sc->fet_cdata;=0A=
   ld =3D sc->fet_ldata;=0A=
=0A=
   for (i =3D 0; i < FET_TX_LIST_CNT; i++)=0A=
   {=0A=
      cd->fet_tx_chain[i].fet_ptr =3D &ld->fet_tx_list[i];=0A=
      if (i =3D=3D (FET_TX_LIST_CNT - 1))=0A=
        cd->fet_tx_chain[i].fet_nextdesc =3D &cd->fet_tx_chain[0];=0A=
      else=0A=
        cd->fet_tx_chain[i].fet_nextdesc =3D &cd->fet_tx_chain[i + 1];=0A=
   }=0A=
=0A=
   cd->fet_tx_free =3D &cd->fet_tx_chain[0];=0A=
   cd->fet_tx_tail =3D cd->fet_tx_head =3D NULL;=0A=
=0A=
   return(0);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Initialize the RX descriptors and allocate mbufs for them. Note that=0A=
 * we arrange the descriptors in a closed ring, so that the last =
descriptor=0A=
 * points back to the first.=0A=
 */=0A=
static int fet_list_rx_init(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct fet_chain_data *cd;=0A=
   struct fet_list_data *ld;=0A=
   int i;=0A=
=0A=
   cd =3D &sc->fet_cdata;=0A=
   ld =3D sc->fet_ldata;=0A=
=0A=
   for (i =3D 0; i < FET_RX_LIST_CNT; i++)=0A=
   {=0A=
      cd->fet_rx_chain[i].fet_ptr =3D (struct fet_desc =
*)&ld->fet_rx_list[i];=0A=
=0A=
      if (fet_newbuf(sc, &cd->fet_rx_chain[i]) =3D=3D ENOBUFS)=0A=
        return(ENOBUFS);=0A=
=0A=
      if (i =3D=3D (FET_RX_LIST_CNT - 1))=0A=
      {=0A=
         cd->fet_rx_chain[i].fet_nextdesc =3D &cd->fet_rx_chain[0];=0A=
         ld->fet_rx_list[i].fet_next =3D vtophys(&ld->fet_rx_list[0]);=0A=
      }=0A=
      else=0A=
      {=0A=
         cd->fet_rx_chain[i].fet_nextdesc =3D &cd->fet_rx_chain[i + 1];=0A=
         ld->fet_rx_list[i].fet_next =3D vtophys(&ld->fet_rx_list[i + =
1]);=0A=
      }=0A=
   }=0A=
=0A=
   cd->fet_rx_head =3D &cd->fet_rx_chain[0];=0A=
=0A=
   return(0);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Initialize an RX descriptor and attach an MBUF cluster.=0A=
 */=0A=
static int fet_newbuf(sc, c)=0A=
struct fet_softc *sc;=0A=
struct fet_chain_onefrag *c;=0A=
{=0A=
   struct mbuf *m_new =3D NULL;=0A=
=0A=
   MGETHDR(m_new, M_DONTWAIT, MT_DATA);=0A=
   if (m_new =3D=3D NULL)=0A=
   {=0A=
      printf("fet%d: no memory for rx list -- packet dropped!\n",=0A=
              sc->fet_unit);=0A=
      return(ENOBUFS);=0A=
   }=0A=
=0A=
   MCLGET(m_new, M_DONTWAIT);=0A=
   if (!(m_new->m_flags & M_EXT))=0A=
   {=0A=
      printf("fet%d: no memory for rx list -- packet dropped!\n",=0A=
              sc->fet_unit);=0A=
      m_freem(m_new);=0A=
      return(ENOBUFS);=0A=
   }=0A=
=0A=
   c->fet_mbuf =3D m_new;=0A=
   c->fet_ptr->fet_data =3D vtophys(mtod(m_new, caddr_t));=0A=
   c->fet_ptr->fet_ctl =3D (MCLBYTES - 1)<<FET_RBSShift;=0A=
   c->fet_ptr->fet_status =3D FET_OWNByNIC;=0A=
=0A=
   return(0);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * A frame has been uploaded: pass the resulting mbuf chain up to=0A=
 * the higher level protocols.=0A=
 */=0A=
static void fet_rxeof(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct ether_header *eh;=0A=
   struct mbuf *m;=0A=
   struct ifnet *ifp;=0A=
   struct fet_chain_onefrag *cur_rx;=0A=
   int total_len =3D 0;=0A=
   u_int32_t rxstat;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   while (!((rxstat =3D =
sc->fet_cdata.fet_rx_head->fet_ptr->fet_status)&FET_OWNByNIC))=0A=
   {=0A=
      cur_rx =3D sc->fet_cdata.fet_rx_head;=0A=
      sc->fet_cdata.fet_rx_head =3D cur_rx->fet_nextdesc;=0A=
=0A=
      if (rxstat & FET_ES)       /* error summary */=0A=
      {  /* give up this rx pkt */=0A=
         ifp->if_ierrors++;=0A=
         cur_rx->fet_ptr->fet_status =3D FET_OWNByNIC;=0A=
         continue;=0A=
      }=0A=
=0A=
      /* No errors; receive the packet. */=0A=
      total_len =3D (rxstat & FET_FLNGMASK) >> FET_FLNGShift;=0A=
      total_len -=3D ETHER_CRC_LEN;=0A=
=0A=
      if (total_len < MINCLSIZE)=0A=
      {=0A=
         m =3D m_devget(mtod(cur_rx->fet_mbuf, char *), total_len, 0, =
ifp, NULL);=0A=
         cur_rx->fet_ptr->fet_status =3D FET_OWNByNIC;=0A=
         if (m =3D=3D NULL)=0A=
         {=0A=
            ifp->if_ierrors++;=0A=
            continue;=0A=
         }=0A=
      }=0A=
      else=0A=
      {=0A=
         m =3D cur_rx->fet_mbuf;=0A=
=0A=
         /*=0A=
          * Try to conjure up a new mbuf cluster. If that=0A=
          * fails, it means we have an out of memory condition and=0A=
          * should leave the buffer in place and continue. This will=0A=
          * result in a lost packet, but there's little else we=0A=
          * can do in this situation.=0A=
          */=0A=
         if (fet_newbuf(sc, cur_rx) =3D=3D ENOBUFS)=0A=
         {=0A=
            ifp->if_ierrors++;=0A=
            cur_rx->fet_ptr->fet_status =3D FET_OWNByNIC;=0A=
            continue;=0A=
         }=0A=
         m->m_pkthdr.rcvif =3D ifp;=0A=
         m->m_pkthdr.len =3D m->m_len =3D total_len;=0A=
      }=0A=
=0A=
      ifp->if_ipackets++;=0A=
      eh =3D mtod(m, struct ether_header *);=0A=
=0A=
#if NBPFILTER > 0=0A=
      /*=0A=
       * Handle BPF listeners. Let the BPF user see the packet, but=0A=
       * don't pass it up to the ether_input() layer unless it's=0A=
       * a broadcast packet, multicast packet, matches our ethernet=0A=
       * address or the interface is in promiscuous mode.=0A=
       */=0A=
      if (ifp->if_bpf)=0A=
      {=0A=
         bpf_mtap(ifp, m);=0A=
         if (ifp->if_flags & IFF_PROMISC &&=0A=
             (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, =
ETHER_ADDR_LEN) &&=0A=
             (eh->ether_dhost[0] & 1) =3D=3D 0))=0A=
         {=0A=
            m_freem(m);=0A=
            continue;=0A=
         }=0A=
      }=0A=
#endif=0A=
      /* Remove header from mbuf and pass it on. */=0A=
      m_adj(m, sizeof(struct ether_header));=0A=
      ether_input(ifp, eh, m);=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * A frame was downloaded to the chip. It's safe for us to clean up=0A=
 * the list buffers.=0A=
 */=0A=
static void fet_txeof(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct fet_chain *cur_tx;=0A=
   struct ifnet *ifp;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   /* Clear the timeout timer. */=0A=
   ifp->if_timer =3D 0;=0A=
=0A=
   if (sc->fet_cdata.fet_tx_head =3D=3D NULL)=0A=
     return;=0A=
=0A=
   /*=0A=
    * Go through our tx list and free mbufs for those=0A=
    * frames that have been transmitted.=0A=
    */=0A=
   while (sc->fet_cdata.fet_tx_head->fet_mbuf !=3D NULL)=0A=
   {=0A=
      u_int32_t txstat;=0A=
=0A=
      cur_tx =3D sc->fet_cdata.fet_tx_head;=0A=
      txstat =3D FET_TXSTATUS(cur_tx);=0A=
=0A=
      if ((txstat & FET_OWNByNIC) || txstat =3D=3D FET_UNSENT)=0A=
        break;=0A=
=0A=
      if (!(CSR_READ_4(sc, FET_TCRRCR)&FET_Enhanced))=0A=
      {=0A=
         if (txstat & FET_TXERR)=0A=
         {=0A=
            ifp->if_oerrors++;=0A=
            if (txstat & FET_EC)    /* excessive collision */=0A=
              ifp->if_collisions++;=0A=
            if (txstat & FET_LC)    /* late collision */=0A=
              ifp->if_collisions++;=0A=
         }=0A=
=0A=
         ifp->if_collisions +=3D (txstat & FET_NCRMASK) >> FET_NCRShift;=0A=
      }=0A=
=0A=
      ifp->if_opackets++;=0A=
      m_freem(cur_tx->fet_mbuf);=0A=
      cur_tx->fet_mbuf =3D NULL;=0A=
=0A=
      if (sc->fet_cdata.fet_tx_head =3D=3D sc->fet_cdata.fet_tx_tail)=0A=
      {=0A=
         sc->fet_cdata.fet_tx_head =3D NULL;=0A=
         sc->fet_cdata.fet_tx_tail =3D NULL;=0A=
         break;=0A=
      }=0A=
=0A=
      sc->fet_cdata.fet_tx_head =3D cur_tx->fet_nextdesc;=0A=
   }=0A=
=0A=
   if (CSR_READ_4(sc, FET_TCRRCR)&FET_Enhanced)=0A=
   {=0A=
      ifp->if_collisions +=3D (CSR_READ_4(sc, FET_TSR)&FET_NCRMask);=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * TX 'end of channel' interrupt handler.=0A=
 */=0A=
static void fet_txeoc(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   struct ifnet *ifp;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   ifp->if_timer =3D 0;=0A=
=0A=
   if (sc->fet_cdata.fet_tx_head =3D=3D NULL)=0A=
   {=0A=
      ifp->if_flags &=3D ~IFF_OACTIVE;=0A=
      sc->fet_cdata.fet_tx_tail =3D NULL;=0A=
      if (sc->fet_want_auto)=0A=
        fet_autoneg_mii(sc, FET_FLAG_SCHEDDELAY, 1);=0A=
   }=0A=
   else=0A=
   {=0A=
      if (FET_TXOWN(sc->fet_cdata.fet_tx_head) =3D=3D FET_UNSENT)=0A=
      {=0A=
         FET_TXOWN(sc->fet_cdata.fet_tx_head) =3D FET_OWNByNIC;=0A=
         ifp->if_timer =3D 5;=0A=
         CSR_WRITE_4(sc, FET_TXPDR, 0xFFFFFFFF);=0A=
      }=0A=
   }=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static void fet_intr(arg)=0A=
void *arg;=0A=
{=0A=
   struct fet_softc *sc;=0A=
   struct ifnet *ifp;=0A=
   u_int32_t status;=0A=
=0A=
   sc =3D arg;=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
=0A=
   if (!(ifp->if_flags & IFF_UP))=0A=
     return;=0A=
=0A=
   /* Disable interrupts. */=0A=
   CSR_WRITE_4(sc, FET_IMR, 0x00000000);=0A=
=0A=
   for (;;)=0A=
   {=0A=
      status =3D CSR_READ_4(sc, FET_ISR);=0A=
      status &=3D FET_INTRS;=0A=
      if (status)=0A=
        CSR_WRITE_4(sc, FET_ISR, status);=0A=
      else=0A=
        break;=0A=
=0A=
      if (status & FET_RI)       /* receive interrupt */=0A=
        fet_rxeof(sc);=0A=
=0A=
      if ((status & FET_RBU) || (status & FET_RxErr))=0A=
      {  /* rx buffer unavailable or rx error */=0A=
         ifp->if_ierrors++;=0A=
#ifdef foo=0A=
         fet_stop(sc);=0A=
         fet_reset(sc);=0A=
         fet_init(sc);=0A=
#endif=0A=
      }=0A=
=0A=
      if (status & FET_TI)       /* tx interrupt */=0A=
        fet_txeof(sc);=0A=
=0A=
      if (status & FET_ETI)      /* tx early interrupt */=0A=
        fet_txeof(sc);=0A=
=0A=
      if (status & FET_TBU)      /* tx buffer unavailable */=0A=
        fet_txeoc(sc);=0A=
=0A=
/* 90/1/18 delete =0A=
      if (status & FET_FBE)      =0A=
      {=0A=
         fet_reset(sc);=0A=
         fet_init(sc);=0A=
      }=0A=
*/=0A=
=0A=
   }=0A=
=0A=
   /* Re-enable interrupts. */=0A=
   CSR_WRITE_4(sc, FET_IMR, FET_INTRS);=0A=
=0A=
   if (ifp->if_snd.ifq_head !=3D NULL)=0A=
     fet_start(ifp);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data=0A=
 * pointers to the fragment pointers.=0A=
 */=0A=
static int fet_encap(sc, c, m_head)=0A=
struct fet_softc *sc;=0A=
struct fet_chain *c;=0A=
struct mbuf *m_head;=0A=
{=0A=
   struct fet_desc *f =3D NULL;=0A=
   int total_len;=0A=
   struct mbuf *m, *m_new=3DNULL;=0A=
=0A=
   /* calculate the total tx pkt length */=0A=
   total_len =3D 0;=0A=
   for (m =3D m_head;  m !=3D NULL; m =3D m->m_next)=0A=
     total_len +=3D m->m_len;=0A=
=0A=
   /*=0A=
    * Start packing the mbufs in this chain into=0A=
    * the fragment pointers. Stop when we run out=0A=
    * of fragments or hit the end of the mbuf chain.=0A=
    */=0A=
   m =3D m_head;=0A=
=0A=
   MGETHDR(m_new, M_DONTWAIT, MT_DATA);=0A=
   if (m_new =3D=3D NULL)=0A=
   {=0A=
      printf("fet%d: no memory for tx list", sc->fet_unit);=0A=
      return(1);=0A=
   }=0A=
=0A=
   if (m_head->m_pkthdr.len > MHLEN)=0A=
   {=0A=
      MCLGET(m_new, M_DONTWAIT);=0A=
      if (!(m_new->m_flags & M_EXT))=0A=
      {=0A=
         m_freem(m_new);=0A=
         printf("fet%d: no memory for tx list", sc->fet_unit);=0A=
         return(1);=0A=
      }=0A=
   }=0A=
=0A=
   m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t));=0A=
   m_new->m_pkthdr.len =3D m_new->m_len =3D m_head->m_pkthdr.len;=0A=
   m_freem(m_head);=0A=
   m_head =3D m_new;=0A=
   f =3D &c->fet_ptr->fet_frag[0];=0A=
   f->fet_status =3D 0;=0A=
   f->fet_data =3D vtophys(mtod(m_new, caddr_t));=0A=
   total_len =3D m_new->m_len;=0A=
   f->fet_ctl =3D FET_TXFD|FET_TXLD|FET_CRCEnable|FET_PADEnable;=0A=
   f->fet_ctl |=3D total_len<<FET_PKTShift;   /* pkt size */=0A=
   f->fet_ctl |=3D total_len;                /* buffer size */=0A=
/* 89/12/29 add, for mtd891 */=0A=
   if (sc->fet_info->fet_did=3D=3DID2)=0A=
     f->fet_ctl |=3D FET_ETIControl|FET_RetryTxLC;=0A=
=0A=
   c->fet_mbuf =3D m_head;=0A=
   c->fet_lastdesc =3D 0;=0A=
   FET_TXNEXT(c) =3D vtophys(&c->fet_nextdesc->fet_ptr->fet_frag[0]);=0A=
=0A=
   return(0);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Main transmit routine. To avoid having to do mbuf copies, we put =
pointers=0A=
 * to the mbuf data regions directly in the transmit lists. We also save =
a=0A=
 * copy of the pointers since the transmit list fragment pointers are=0A=
 * physical addresses.=0A=
 */=0A=
static void fet_start(ifp)=0A=
struct ifnet *ifp;=0A=
{=0A=
   struct fet_softc *sc;=0A=
   struct mbuf *m_head =3D NULL;=0A=
   struct fet_chain *cur_tx =3D NULL, *start_tx;=0A=
=0A=
   sc =3D ifp->if_softc;=0A=
=0A=
   if (sc->fet_autoneg)=0A=
   {=0A=
      sc->fet_tx_pend =3D 1;=0A=
      return;=0A=
   }=0A=
=0A=
   /*=0A=
    * Check for an available queue slot. If there are none,=0A=
    * punt.=0A=
    */=0A=
   if (sc->fet_cdata.fet_tx_free->fet_mbuf !=3D NULL)=0A=
   {=0A=
      ifp->if_flags |=3D IFF_OACTIVE;=0A=
      return;=0A=
   }=0A=
=0A=
   start_tx =3D sc->fet_cdata.fet_tx_free;=0A=
=0A=
   while (sc->fet_cdata.fet_tx_free->fet_mbuf =3D=3D NULL)=0A=
   {=0A=
      IF_DEQUEUE(&ifp->if_snd, m_head);=0A=
      if (m_head =3D=3D NULL)=0A=
        break;=0A=
=0A=
      /* Pick a descriptor off the free list. */=0A=
      cur_tx =3D sc->fet_cdata.fet_tx_free;=0A=
      sc->fet_cdata.fet_tx_free =3D cur_tx->fet_nextdesc;=0A=
=0A=
      /* Pack the data into the descriptor. */=0A=
      fet_encap(sc, cur_tx, m_head);=0A=
=0A=
      if (cur_tx !=3D start_tx)=0A=
        FET_TXOWN(cur_tx) =3D FET_OWNByNIC;=0A=
=0A=
#if NBPFILTER > 0=0A=
      /*=0A=
       * If there's a BPF listener, bounce a copy of this frame=0A=
       * to him.=0A=
       */=0A=
      if (ifp->if_bpf)=0A=
        bpf_mtap(ifp, cur_tx->fet_mbuf);=0A=
#endif=0A=
   }=0A=
=0A=
   /*=0A=
    * If there are no packets queued, bail.=0A=
    */=0A=
   if (cur_tx =3D=3D NULL)=0A=
     return;=0A=
=0A=
   /*=0A=
    * Place the request for the upload interrupt=0A=
    * in the last descriptor in the chain. This way, if=0A=
    * we're chaining several packets at once, we'll only=0A=
    * get an interupt once for the whole chain rather than=0A=
    * once for each packet.=0A=
    */=0A=
   FET_TXCTL(cur_tx) |=3D FET_TXIC;=0A=
   cur_tx->fet_ptr->fet_frag[0].fet_ctl |=3D FET_TXIC;=0A=
   sc->fet_cdata.fet_tx_tail =3D cur_tx;=0A=
=0A=
   if (sc->fet_cdata.fet_tx_head =3D=3D NULL)=0A=
     sc->fet_cdata.fet_tx_head =3D start_tx;=0A=
=0A=
   FET_TXOWN(start_tx) =3D FET_OWNByNIC;=0A=
   CSR_WRITE_4(sc, FET_TXPDR, 0xFFFFFFFF);    /* tx polling demand */=0A=
=0A=
   /*=0A=
    * Set a timeout in case the chip goes out to lunch.=0A=
    */=0A=
   ifp->if_timer =3D 5;=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static void fet_init(xsc)=0A=
void *xsc;=0A=
{=0A=
   struct fet_softc *sc =3D xsc;=0A=
   struct ifnet *ifp =3D &sc->arpcom.ac_if;=0A=
   int s, i;=0A=
   u_int16_t phy_bmcr =3D 0;=0A=
=0A=
   if (sc->fet_autoneg)=0A=
     return;=0A=
=0A=
   s =3D splimp();=0A=
=0A=
   if (sc->fet_pinfo !=3D NULL)=0A=
     phy_bmcr =3D fet_phy_readreg(sc, PHY_BMCR);=0A=
=0A=
   /*=0A=
    * Cancel pending I/O and free all RX/TX buffers.=0A=
    */=0A=
   fet_stop(sc);=0A=
   fet_reset(sc);=0A=
=0A=
   /*=0A=
    * Set cache alignment and burst length.=0A=
    */=0A=
/* 89/9/1 modify, =0A=
   CSR_WRITE_4(sc, FET_BCR, FET_RPBLE512);=0A=
   CSR_WRITE_4(sc, FET_TCRRCR, FET_TFTSF);=0A=
*/=0A=
   CSR_WRITE_4(sc, FET_BCR, FET_PBL8);=0A=
   CSR_WRITE_4(sc, FET_TCRRCR, FET_TFTSF|FET_RBLEN|FET_RPBLE512);=0A=
/* =0A=
   89/12/29 add, for mtd891,=0A=
*/=0A=
   if (sc->fet_info->fet_did=3D=3DID2)=0A=
   {=0A=
      FET_SETBIT(sc, FET_BCR, FET_PROG);=0A=
      FET_SETBIT(sc, FET_TCRRCR, FET_Enhanced);=0A=
   }=0A=
   fet_setcfg(sc, phy_bmcr);=0A=
=0A=
   /* Init circular RX list. */=0A=
   if (fet_list_rx_init(sc) =3D=3D ENOBUFS)=0A=
   {=0A=
      printf("fet%d: initialization failed: no memory for rx buffers\n",=0A=
              sc->fet_unit);=0A=
      fet_stop(sc);=0A=
      (void)splx(s);=0A=
      return;=0A=
   }=0A=
=0A=
   /* Init TX descriptors. */=0A=
   fet_list_tx_init(sc);=0A=
=0A=
   /* If we want promiscuous mode, set the allframes bit. */=0A=
   if (ifp->if_flags & IFF_PROMISC)=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_PROM);=0A=
   else=0A=
     FET_CLRBIT(sc, FET_TCRRCR, FET_PROM);=0A=
=0A=
   /*=0A=
    * Set capture broadcast bit to capture broadcast frames.=0A=
    */=0A=
   if (ifp->if_flags & IFF_BROADCAST)=0A=
     FET_SETBIT(sc, FET_TCRRCR, FET_AB);=0A=
   else=0A=
     FET_CLRBIT(sc, FET_TCRRCR, FET_AB);=0A=
=0A=
   /*=0A=
    * Program the multicast filter, if necessary.=0A=
    */=0A=
   fet_setmulti(sc);=0A=
=0A=
   /*=0A=
    * Load the address of the RX list.=0A=
    */=0A=
   FET_CLRBIT(sc, FET_TCRRCR, FET_RE);=0A=
   CSR_WRITE_4(sc, FET_RXLBA, vtophys(&sc->fet_ldata->fet_rx_list[0]));=0A=
=0A=
   /*=0A=
    * Enable interrupts.=0A=
    */=0A=
   CSR_WRITE_4(sc, FET_IMR, FET_INTRS);=0A=
   CSR_WRITE_4(sc, FET_ISR, 0xFFFFFFFF);=0A=
=0A=
   /* Enable receiver and transmitter. */=0A=
   FET_SETBIT(sc, FET_TCRRCR, FET_RE);=0A=
=0A=
   FET_CLRBIT(sc, FET_TCRRCR, FET_TE);=0A=
   CSR_WRITE_4(sc, FET_TXLBA, vtophys(&sc->fet_ldata->fet_tx_list[0]));=0A=
   FET_SETBIT(sc, FET_TCRRCR, FET_TE);=0A=
=0A=
   /* Restore state of BMCR */=0A=
   if (sc->fet_pinfo !=3D NULL)=0A=
     fet_phy_writereg(sc, PHY_BMCR, phy_bmcr);=0A=
=0A=
   ifp->if_flags |=3D IFF_RUNNING;=0A=
   ifp->if_flags &=3D ~IFF_OACTIVE;=0A=
=0A=
   (void)splx(s);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Set media options.=0A=
 */=0A=
static int fet_ifmedia_upd(ifp)=0A=
struct ifnet *ifp;=0A=
{=0A=
   struct fet_softc *sc;=0A=
   struct ifmedia *ifm;=0A=
=0A=
   sc =3D ifp->if_softc;=0A=
   ifm =3D &sc->ifmedia;=0A=
=0A=
   if (IFM_TYPE(ifm->ifm_media) !=3D IFM_ETHER)=0A=
     return(EINVAL);=0A=
=0A=
   if (IFM_SUBTYPE(ifm->ifm_media) =3D=3D IFM_AUTO)=0A=
     fet_autoneg_mii(sc, FET_FLAG_SCHEDDELAY, 1);=0A=
   else=0A=
     fet_setmode_mii(sc, ifm->ifm_media);=0A=
=0A=
   return(0);=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Report current media status.=0A=
 */=0A=
static void fet_ifmedia_sts(ifp, ifmr)=0A=
struct ifnet *ifp;=0A=
struct ifmediareq *ifmr;=0A=
{=0A=
   struct fet_softc *sc;=0A=
   u_int16_t advert =3D 0, ability =3D 0, ability2 =3D 0;=0A=
=0A=
   sc =3D ifp->if_softc;=0A=
=0A=
   ifmr->ifm_active =3D IFM_ETHER;=0A=
=0A=
   if (!(fet_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL))=0A=
   {=0A=
/* this version did not support 1000M,=0A=
      if (fet_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_1000)=0A=
        ifmr->ifm_active =3D IFM_ETHER|IFM_1000TX;=0A=
*/=0A=
      if (fet_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL)=0A=
        ifmr->ifm_active =3D IFM_ETHER|IFM_100_TX;=0A=
      else=0A=
        ifmr->ifm_active =3D IFM_ETHER|IFM_10_T;=0A=
      if (fet_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX)=0A=
        ifmr->ifm_active |=3D IFM_FDX;=0A=
      else=0A=
        ifmr->ifm_active |=3D IFM_HDX;=0A=
      return;=0A=
   }=0A=
=0A=
   ability =3D fet_phy_readreg(sc, PHY_LPAR);=0A=
   advert =3D fet_phy_readreg(sc, PHY_ANAR);=0A=
=0A=
/* this version did not support 1000M,=0A=
   if (sc->fet_pinfo->fet_vid =3D MarvellPHYID0)=0A=
   {=0A=
      ability2 =3D fet_phy_readreg(sc, PHY_1000SR);=0A=
      if (ability2 & PHY_1000SR_1000BTXFULL)=0A=
      {=0A=
         advert =3D 0;=0A=
         ability =3D 0;=0A=
         ifmr->ifm_active =3D IFM_ETHER|IFM_1000_TX|IFM_FDX;=0A=
=0A=
      }=0A=
      else if (ability & PHY_1000SR_1000BTXHALF)=0A=
      {=0A=
         advert =3D 0;=0A=
         ability =3D 0;=0A=
         ifmr->ifm_active =3D IFM_ETHER|IFM_1000_TX|IFM_HDX;=0A=
      }=0A=
   }=0A=
*/=0A=
=0A=
   if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4)=0A=
     ifmr->ifm_active =3D IFM_ETHER|IFM_100_T4;=0A=
   else if (advert & PHY_ANAR_100BTXFULL && ability & =
PHY_ANAR_100BTXFULL)=0A=
     ifmr->ifm_active =3D IFM_ETHER|IFM_100_TX|IFM_FDX;=0A=
   else if (advert & PHY_ANAR_100BTXHALF && ability & =
PHY_ANAR_100BTXHALF)=0A=
     ifmr->ifm_active =3D IFM_ETHER|IFM_100_TX|IFM_HDX;=0A=
   else if (advert & PHY_ANAR_10BTFULL && ability & PHY_ANAR_10BTFULL)=0A=
     ifmr->ifm_active =3D IFM_ETHER|IFM_10_T|IFM_FDX;=0A=
   else if (advert & PHY_ANAR_10BTHALF && ability & PHY_ANAR_10BTHALF)=0A=
     ifmr->ifm_active =3D IFM_ETHER|IFM_10_T|IFM_HDX;=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static int fet_ioctl(ifp, command, data)=0A=
struct ifnet *ifp;=0A=
u_long command;=0A=
caddr_t data;=0A=
{=0A=
   struct fet_softc *sc =3D ifp->if_softc;=0A=
   struct ifreq *ifr =3D (struct ifreq *)data;=0A=
   int s, error =3D 0;=0A=
=0A=
   s =3D splimp();=0A=
=0A=
   switch(command)=0A=
   {=0A=
      case SIOCSIFADDR:=0A=
      case SIOCGIFADDR:=0A=
      case SIOCSIFMTU:=0A=
        error =3D ether_ioctl(ifp, command, data);=0A=
        break;=0A=
      case SIOCSIFFLAGS:=0A=
        if (ifp->if_flags & IFF_UP)=0A=
          fet_init(sc);=0A=
        else if (ifp->if_flags & IFF_RUNNING)=0A=
          fet_stop(sc);=0A=
        error =3D 0;=0A=
        break;=0A=
      case SIOCADDMULTI:=0A=
      case SIOCDELMULTI:=0A=
        fet_setmulti(sc);=0A=
        error =3D 0;=0A=
        break;=0A=
      case SIOCGIFMEDIA:=0A=
      case SIOCSIFMEDIA:=0A=
        error =3D ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);=0A=
        break;=0A=
      default:=0A=
        error =3D EINVAL;=0A=
        break;=0A=
   }=0A=
=0A=
   (void)splx(s);=0A=
=0A=
   return(error);=0A=
}=0A=
=0A=
=0A=
static void fet_watchdog(ifp)=0A=
struct ifnet *ifp;=0A=
{=0A=
   struct fet_softc *sc;=0A=
=0A=
   sc =3D ifp->if_softc;=0A=
=0A=
   if (sc->fet_autoneg)=0A=
   {=0A=
      fet_autoneg_mii(sc, FET_FLAG_DELAYTIMEO, 1);=0A=
      return;=0A=
   }=0A=
=0A=
   ifp->if_oerrors++;=0A=
   printf("fet%d: watchdog timeout\n", sc->fet_unit);=0A=
=0A=
   if (!(fet_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT))=0A=
     printf("fet%d: no carrier - transceiver cable problem?\n", =
sc->fet_unit);=0A=
=0A=
   fet_stop(sc);=0A=
   fet_reset(sc);=0A=
   fet_init(sc);=0A=
=0A=
   if (ifp->if_snd.ifq_head !=3D NULL)=0A=
     fet_start(ifp);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Stop the adapter and free any mbufs allocated to the=0A=
 * RX and TX lists.=0A=
 */=0A=
static void fet_stop(sc)=0A=
struct fet_softc *sc;=0A=
{=0A=
   register int i;=0A=
   struct ifnet *ifp;=0A=
=0A=
   ifp =3D &sc->arpcom.ac_if;=0A=
   ifp->if_timer =3D 0;=0A=
=0A=
   FET_CLRBIT(sc, FET_TCRRCR, (FET_RE|FET_TE));=0A=
   CSR_WRITE_4(sc, FET_IMR, 0x00000000);=0A=
   CSR_WRITE_4(sc, FET_TXLBA, 0x00000000);=0A=
   CSR_WRITE_4(sc, FET_RXLBA, 0x00000000);=0A=
=0A=
   /*=0A=
    * Free data in the RX lists.=0A=
    */=0A=
   for (i =3D 0; i < FET_RX_LIST_CNT; i++)=0A=
   {=0A=
      if (sc->fet_cdata.fet_rx_chain[i].fet_mbuf !=3D NULL)=0A=
      {=0A=
         m_freem(sc->fet_cdata.fet_rx_chain[i].fet_mbuf);=0A=
         sc->fet_cdata.fet_rx_chain[i].fet_mbuf =3D NULL;=0A=
      }=0A=
   }=0A=
   bzero((char *)&sc->fet_ldata->fet_rx_list, =
sizeof(sc->fet_ldata->fet_rx_list));=0A=
=0A=
   /*=0A=
    * Free the TX list buffers.=0A=
    */=0A=
   for (i =3D 0; i < FET_TX_LIST_CNT; i++)=0A=
   {=0A=
      if (sc->fet_cdata.fet_tx_chain[i].fet_mbuf !=3D NULL)=0A=
      {=0A=
         m_freem(sc->fet_cdata.fet_tx_chain[i].fet_mbuf);=0A=
         sc->fet_cdata.fet_tx_chain[i].fet_mbuf =3D NULL;=0A=
      }=0A=
   }=0A=
   bzero((char *)&sc->fet_ldata->fet_tx_list, =
sizeof(sc->fet_ldata->fet_tx_list));=0A=
=0A=
   ifp->if_flags &=3D ~(IFF_RUNNING | IFF_OACTIVE);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
/*=0A=
 * Stop all chip I/O so that the kernel's probe routines don't=0A=
 * get confused by errant DMAs when rebooting.=0A=
 */=0A=
static void fet_shutdown(howto, arg)=0A=
int howto;=0A=
void *arg;=0A=
{=0A=
   struct fet_softc *sc =3D (struct fet_softc *)arg;=0A=
=0A=
   fet_stop(sc);=0A=
=0A=
   return;=0A=
}=0A=
=0A=
=0A=
static struct pci_device fet_device =3D {=0A=
        "fet",=0A=
        fet_probe,=0A=
        fet_attach,=0A=
        &fet_count,=0A=
        NULL=0A=
};=0A=
DATA_SET(pcidevice_set, fet_device);=0A=

------=_NextPart_000_0011_01C2FFB8.64D15160
Content-Type: application/octet-stream;
	name="if_fetreg.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="if_fetreg.h"

/*=0A=
 * register definitions.=0A=
 */=0A=
#define FET_PAR0         0x0     /* physical address 0-3 */=0A=
#define FET_PAR1         0x04    /* physical address 4-5 */=0A=
#define FET_MAR0         0x08    /* multicast address 0-3 */=0A=
#define FET_MAR1         0x0C    /* multicast address 4-7 */=0A=
#define FET_FAR0         0x10    /* flow-control address 0-3 */=0A=
#define FET_FAR1         0x14    /* flow-control address 4-5 */=0A=
#define FET_TCRRCR       0x18    /* receive & transmit configuration */=0A=
#define FET_BCR          0x1C    /* bus command */=0A=
#define FET_TXPDR        0x20    /* transmit polling demand */=0A=
#define FET_RXPDR        0x24    /* receive polling demand */=0A=
#define FET_RXCWP        0x28    /* receive current word pointer */=0A=
#define FET_TXLBA        0x2C    /* transmit list base address */=0A=
#define FET_RXLBA        0x30    /* receive list base address */=0A=
#define FET_ISR          0x34    /* interrupt status */=0A=
#define FET_IMR          0x38    /* interrupt mask */=0A=
#define FET_FTH          0x3C    /* flow control high/low threshold */=0A=
#define FET_MANAGEMENT   0x40    /* bootrom/eeprom and mii management */=0A=
#define FET_TALLY        0x44    /* tally counters for crc and mpa */=0A=
#define FET_TSR          0x48    /* tally counter for transmit status */=0A=
#define FET_PHYBASE	0x4c=0A=
=0A=
/*=0A=
 * Receive Configuration Register=0A=
 */=0A=
#define FET_RXRUN        0x00008000      /* receive running status */=0A=
#define FET_EIEN         0x00004000      /* early interrupt enable */=0A=
#define FET_RFCEN        0x00002000      /* receive flow control packet =
enable */=0A=
#define FET_NDFA         0x00001000      /* not defined flow control =
address */=0A=
#define FET_RBLEN        0x00000800      /* receive burst length enable =
*/=0A=
#define FET_RPBLE1       0x00000000      /* 1 word */=0A=
#define FET_RPBLE4       0x00000100      /* 4 words */=0A=
#define FET_RPBLE8       0x00000200      /* 8 words */=0A=
#define FET_RPBLE16      0x00000300      /* 16 words */=0A=
#define FET_RPBLE32      0x00000400      /* 32 words */=0A=
#define FET_RPBLE64      0x00000500      /* 64 words */=0A=
#define FET_RPBLE128     0x00000600      /* 128 words */=0A=
#define FET_RPBLE512     0x00000700      /* 512 words */=0A=
#define FET_PROM         0x000000080     /* promiscuous mode */=0A=
#define FET_AB           0x000000040     /* accept broadcast */=0A=
#define FET_AM           0x000000020     /* accept mutlicast */=0A=
#define FET_ARP          0x000000008     /* receive runt pkt */=0A=
#define FET_ALP          0x000000004     /* receive long pkt */=0A=
#define FET_SEP          0x000000002     /* receive error pkt */=0A=
#define FET_RE           0x000000001     /* receive enable */=0A=
=0A=
/*=0A=
 * Transmit Configuration Register=0A=
 */=0A=
#define FET_TXRUN        0x04000000      /* transmit running status */=0A=
#define FET_Enhanced     0x02000000      /* transmit enhanced mode */=0A=
#define FET_TFCEN        0x01000000      /* tx flow control packet =
enable */=0A=
#define FET_TFT64        0x00000000      /* 64 bytes */=0A=
#define FET_TFT32        0x00200000      /* 32 bytes */=0A=
#define FET_TFT128       0x00400000      /* 128 bytes */=0A=
#define FET_TFT256       0x00600000      /* 256 bytes */=0A=
#define FET_TFT512       0x00800000      /* 512 bytes */=0A=
#define FET_TFT768       0x00A00000      /* 768 bytes */=0A=
#define FET_TFT1024      0x00C00000      /* 1024 bytes */=0A=
#define FET_TFTSF        0x00E00000      /* store and forward */=0A=
#define FET_FD           0x00100000      /* full duplex mode */=0A=
#define FET_PS10         0x00080000      /* port speed is 10M */=0A=
#define FET_TE           0x00040000      /* transmit enable */=0A=
#define FET_PS1000       0x00010000      /* port speed is 1000M */=0A=
/*=0A=
 * Bus Command Register=0A=
 */=0A=
#define FET_PROG		0x00000200	/* programming */=0A=
#define FET_RLE          0x00000100      /* read line command enable */=0A=
#define FET_RME          0x00000080      /* read multiple command enable =
*/=0A=
#define FET_WIE          0x00000040      /* write and invalidate cmd =
enable */=0A=
#define FET_PBL1         0x00000000      /* 1 dword */=0A=
#define FET_PBL4         0x00000008      /* 4 dwords */=0A=
#define FET_PBL8         0x00000010      /* 8 dwords */=0A=
#define FET_PBL16        0x00000018      /* 16 dwords */=0A=
#define FET_PBL32        0x00000020      /* 32 dwords */=0A=
#define FET_PBL64        0x00000028      /* 64 dwords */=0A=
#define FET_PBL128       0x00000030      /* 128 dwords */=0A=
#define FET_PBL512       0x00000038      /* 512 dwords */=0A=
#define FET_ABR          0x00000004      /* arbitration rule */=0A=
#define FET_BLS          0x00000002      /* big/little endian select */=0A=
#define FET_SWR          0x00000001      /* software reset */=0A=
=0A=
/*=0A=
 * Transmit Poll Demand Register=0A=
 */=0A=
#define FET_TxPollDemand 0x1=0A=
=0A=
/*=0A=
 * Receive Poll Demand Register=0A=
 */=0A=
#define FET_RxPollDemand 0x01=0A=
=0A=
/*=0A=
 * Interrupt Status Register=0A=
 */=0A=
#define FET_RFCON        0x00020000      /* receive flow control xon =
packet */=0A=
#define FET_RFCOFF       0x00010000      /* receive flow control xoff =
packet */=0A=
#define FET_LSCStatus    0x00008000      /* link status change */=0A=
#define FET_ANCStatus    0x00004000      /* autonegotiation completed */=0A=
#define FET_FBE          0x00002000      /* fatal bus error */=0A=
#define FET_FBEMask      0x00001800=0A=
#define FET_ParityErr    0x00000000      /* parity error */=0A=
#define FET_MasterErr    0x00000800      /* master error */=0A=
#define FET_TargetErr    0x00001000      /* target abort */=0A=
#define FET_TUNF         0x00000400      /* transmit underflow */=0A=
#define FET_ROVF         0x00000200      /* receive overflow */=0A=
#define FET_ETI          0x00000100      /* transmit early int */=0A=
#define FET_ERI          0x00000080      /* receive early int */=0A=
#define FET_CNTOVF       0x00000040      /* counter overflow */=0A=
#define FET_RBU          0x00000020      /* receive buffer unavailable */=0A=
#define FET_TBU          0x00000010      /* transmit buffer unavilable */=0A=
#define FET_TI           0x00000008      /* transmit interrupt */=0A=
#define FET_RI           0x00000004      /* receive interrupt */=0A=
#define FET_RxErr        0x00000002      /* receive error */=0A=
=0A=
/*=0A=
 * Interrupt Mask Register=0A=
 */=0A=
#define FET_MRFCON       0x00020000      /* receive flow control xon =
packet */=0A=
#define FET_MRFCOFF      0x00010000      /* receive flow control xoff =
packet */=0A=
#define FET_MLSCStatus   0x00008000      /* link status change */=0A=
#define FET_MANCStatus   0x00004000      /* autonegotiation completed */=0A=
#define FET_MFBE         0x00002000      /* fatal bus error */=0A=
#define FET_MFBEMask     0x00001800=0A=
#define FET_MTUNF        0x00000400      /* transmit underflow */=0A=
#define FET_MROVF        0x00000200      /* receive overflow */=0A=
#define FET_METI         0x00000100      /* transmit early int */=0A=
#define FET_MERI         0x00000080      /* receive early int */=0A=
#define FET_MCNTOVF      0x00000040      /* counter overflow */=0A=
#define FET_MRBU         0x00000020      /* receive buffer unavailable */=0A=
#define FET_MTBU         0x00000010      /* transmit buffer unavilable */=0A=
#define FET_MTI          0x00000008      /* transmit interrupt */=0A=
#define FET_MRI          0x00000004      /* receive interrupt */=0A=
#define FET_MRxErr       0x00000002      /* receive error */=0A=
=0A=
/* 90/1/18 delete */=0A=
/* #define FET_INTRS FET_FBE|FET_MRBU|FET_TBU|FET_MTI|FET_MRI|FET_METI */=0A=
#define FET_INTRS FET_MRBU|FET_TBU|FET_MTI|FET_MRI|FET_METI=0A=
=0A=
/*=0A=
 * Flow Control High/Low Threshold Register=0A=
 */=0A=
#define FET_FCHTShift    16      /* flow control high threshold */=0A=
#define FET_FCLTShift    0       /* flow control low threshold */=0A=
=0A=
/*=0A=
 * BootROM/EEPROM/MII Management Register=0A=
 */=0A=
#define FET_MASK_MIIR_MII_READ   0x00000000=0A=
#define FET_MASK_MIIR_MII_WRITE  0x00000008=0A=
#define FET_MASK_MIIR_MII_MDO    0x00000004=0A=
#define FET_MASK_MIIR_MII_MDI    0x00000002=0A=
#define FET_MASK_MIIR_MII_MDC    0x00000001=0A=
=0A=
/*=0A=
 * Tally Counter for CRC and MPA=0A=
 */=0A=
#define FET_TCOVF        0x80000000      /* crc tally counter overflow */=0A=
#define FET_CRCMask      0x7fff0000      /* crc number: bit 16-30 */=0A=
#define FET_CRCShift     16=0A=
#define FET_TMOVF        0x00008000      /* mpa tally counter overflow */=0A=
#define FET_MPAMask      0x00007fff      /* mpa number: bit 0-14 */=0A=
#define FET_MPAShift     0=0A=
=0A=
/*=0A=
 * Tally Counters for transmit status=0A=
 */=0A=
#define FET_AbortMask      0xff000000    /* transmit abort number */=0A=
#define FET_AbortShift     24=0A=
#define FET_LColMask       0x00ff0000    /* transmit late collisions */=0A=
#define FET_LColShift      16=0A=
#define FET_NCRMask        0x0000ffff    /* transmit retry number */=0A=
#define FET_NCRShift       0=0A=
=0A=
/*=0A=
 * Myson TX/RX descriptor structure.=0A=
 */=0A=
=0A=
struct fet_desc {=0A=
        u_int32_t       fet_status;=0A=
        u_int32_t       fet_ctl;=0A=
        u_int32_t       fet_data;=0A=
        u_int32_t       fet_next;=0A=
};=0A=
=0A=
/*=0A=
 * for tx/rx descriptors=0A=
 */=0A=
#define FET_OWNByNIC     0x80000000=0A=
#define FET_OWNByDriver  0x0=0A=
=0A=
/*=0A=
 * receive descriptor 0=0A=
 */=0A=
#define FET_RXOWN        0x80000000      /* own bit */=0A=
#define FET_FLNGMASK     0x0fff0000      /* frame length */=0A=
#define FET_FLNGShift    16=0A=
#define FET_MARSTATUS    0x00004000      /* multicast address received */=0A=
#define FET_BARSTATUS    0x00002000      /* broadcast address received */=0A=
#define FET_PHYSTATUS    0x00001000      /* physical address received */=0A=
#define FET_RXFSD        0x00000800      /* first descriptor */=0A=
#define FET_RXLSD        0x00000400      /* last descriptor */=0A=
#define FET_ES           0x00000080      /* error summary */=0A=
#define FET_RUNT         0x00000040      /* runt packet received */=0A=
#define FET_LONG         0x00000020      /* long packet received */=0A=
#define FET_FAE          0x00000010      /* frame align error */=0A=
#define FET_CRC          0x00000008      /* crc error */=0A=
#define FET_RXER         0x00000004      /* receive error */=0A=
#define FET_RDES0CHECK   0x000078fc      /* only check MAR, BAR, PHY, =
ES, RUNT,=0A=
                                           LONG, FAE, CRC and RXER bits =
*/=0A=
=0A=
/*=0A=
 * receive descriptor 1=0A=
 */=0A=
#define FET_RXIC         0x00800000      /* interrupt control */=0A=
#define FET_RBSMASK      0x000007ff      /* receive buffer size */=0A=
#define FET_RBSShift     0=0A=
=0A=
/*=0A=
 * transmit descriptor 0=0A=
 */=0A=
#define FET_TXERR        0x00008000      /* transmit error */=0A=
#define FET_JABTO        0x00004000      /* jabber timeout */=0A=
#define FET_CSL          0x00002000      /* carrier sense lost */=0A=
#define FET_LC           0x00001000      /* late collision */=0A=
#define FET_EC           0x00000800      /* excessive collision */=0A=
#define FET_UDF          0x00000400      /* fifo underflow */=0A=
#define FET_DFR          0x00000200      /* deferred */=0A=
#define FET_HF           0x00000100      /* heartbeat fail */=0A=
#define FET_NCRMASK      0x000000ff      /* collision retry count */=0A=
#define FET_NCRShift     0=0A=
=0A=
/*=0A=
 * tx descriptor 1=0A=
 */=0A=
#define FET_TXIC         0x80000000      /* interrupt control */=0A=
#define FET_ETIControl   0x40000000      /* early transmit interrupt */=0A=
#define FET_TXLD         0x20000000      /* last descriptor */=0A=
#define FET_TXFD         0x10000000      /* first descriptor */=0A=
#define FET_CRCDisable   0x00000000      /* crc control */=0A=
#define FET_CRCEnable    0x08000000=0A=
#define FET_PADDisable   0x00000000      /* padding control */=0A=
#define FET_PADEnable    0x04000000=0A=
#define FET_RetryTxLC	0x02000000	/* retry late collision */=0A=
#define FET_PKTShift     11              /* transmit pkt size */=0A=
#define FET_TBSMASK      0x000007ff=0A=
#define FET_TBSShift     0               /* transmit buffer size */=0A=
=0A=
#define FET_MAXFRAGS     1=0A=
#define FET_RX_LIST_CNT  64=0A=
#define FET_TX_LIST_CNT  64=0A=
#define FET_MIN_FRAMELEN 60=0A=
=0A=
/*=0A=
 * A transmit 'super descriptor' is actually FET_MAXFRAGS regular=0A=
 * descriptors clumped together. The idea here is to emulate the=0A=
 * multi-fragment descriptor layout found in devices such as the=0A=
 * Texas Instruments ThunderLAN and 3Com boomerang and cylone chips.=0A=
 * The advantage to using this scheme is that it avoids buffer copies.=0A=
 * The disadvantage is that there's a certain amount of overhead due=0A=
 * to the fact that each 'fragment' is 16 bytes long. In fet tests,=0A=
 * this limits top speed to about 10.5MB/sec. It should be more like=0A=
 * 11.5MB/sec. However, the upshot is that you can achieve better=0A=
 * results on slower machines: a Pentium 200 can pump out packets at=0A=
 * same speed as a PII 400.=0A=
 */=0A=
struct fet_txdesc {=0A=
        struct fet_desc          fet_frag[FET_MAXFRAGS];=0A=
};=0A=
=0A=
#define FET_TXSTATUS(x)  x->fet_ptr->fet_frag[x->fet_lastdesc].fet_status=0A=
#define FET_TXCTL(x)     x->fet_ptr->fet_frag[x->fet_lastdesc].fet_ctl=0A=
#define FET_TXDATA(x)    x->fet_ptr->fet_frag[x->fet_lastdesc].fet_data=0A=
#define FET_TXNEXT(x)    x->fet_ptr->fet_frag[x->fet_lastdesc].fet_next=0A=
=0A=
#define FET_TXOWN(x)     x->fet_ptr->fet_frag[0].fet_status=0A=
=0A=
#define FET_UNSENT       0x1234=0A=
=0A=
struct fet_list_data {=0A=
        struct fet_desc          fet_rx_list[FET_RX_LIST_CNT];=0A=
        struct fet_txdesc        fet_tx_list[FET_TX_LIST_CNT];=0A=
};=0A=
=0A=
struct fet_chain {=0A=
        struct fet_txdesc        *fet_ptr;=0A=
        struct mbuf             *fet_mbuf;=0A=
        struct fet_chain         *fet_nextdesc;=0A=
        u_int8_t                fet_lastdesc;=0A=
};=0A=
=0A=
struct fet_chain_onefrag {=0A=
        struct fet_desc          *fet_ptr;=0A=
        struct mbuf             *fet_mbuf;=0A=
        struct fet_chain_onefrag *fet_nextdesc;=0A=
        u_int8_t                fet_rlast;=0A=
};=0A=
=0A=
struct fet_chain_data {=0A=
        struct fet_chain_onefrag fet_rx_chain[FET_RX_LIST_CNT];=0A=
        struct fet_chain         fet_tx_chain[FET_TX_LIST_CNT];=0A=
=0A=
        struct fet_chain_onefrag *fet_rx_head;=0A=
=0A=
        struct fet_chain         *fet_tx_head;=0A=
        struct fet_chain         *fet_tx_tail;=0A=
        struct fet_chain         *fet_tx_free;=0A=
};=0A=
=0A=
struct fet_type {=0A=
        u_int16_t               fet_vid;=0A=
        u_int16_t               fet_did;=0A=
        char                    *fet_name;=0A=
};=0A=
=0A=
#define FET_FLAG_FORCEDELAY      1=0A=
#define FET_FLAG_SCHEDDELAY      2=0A=
#define FET_FLAG_DELAYTIMEO      3=0A=
=0A=
struct fet_softc {=0A=
        struct arpcom           arpcom;         /* interface info */=0A=
        struct ifmedia          ifmedia;        /* media info */=0A=
        bus_space_handle_t      fet_bhandle;=0A=
        bus_space_tag_t         fet_btag;=0A=
        struct fet_type          *fet_info;       /* adapter info */=0A=
        struct fet_type          *fet_pinfo;      /* phy info */=0A=
        u_int8_t                fet_unit;        /* interface number */=0A=
        u_int8_t                fet_type;=0A=
        u_int8_t                fet_phy_addr;    /* PHY address */=0A=
        u_int8_t                fet_tx_pend;     /* TX pending */=0A=
        u_int8_t                fet_want_auto;=0A=
        u_int8_t                fet_autoneg;=0A=
        u_int16_t               fet_txthresh;=0A=
        caddr_t                 fet_ldata_ptr;=0A=
        struct fet_list_data     *fet_ldata;=0A=
        struct fet_chain_data    fet_cdata;=0A=
};=0A=
=0A=
/*=0A=
 * register space access macros=0A=
 */=0A=
#define CSR_WRITE_4(sc, reg, val)       \=0A=
        bus_space_write_4(sc->fet_btag, sc->fet_bhandle, reg, val)=0A=
#define CSR_WRITE_2(sc, reg, val)       \=0A=
        bus_space_write_2(sc->fet_btag, sc->fet_bhandle, reg, val)=0A=
#define CSR_WRITE_1(sc, reg, val)       \=0A=
        bus_space_write_1(sc->fet_btag, sc->fet_bhandle, reg, val)=0A=
=0A=
#define CSR_READ_4(sc, reg)     \=0A=
        bus_space_read_4(sc->fet_btag, sc->fet_bhandle, reg)=0A=
#define CSR_READ_2(sc, reg)     \=0A=
        bus_space_read_2(sc->fet_btag, sc->fet_bhandle, reg)=0A=
#define CSR_READ_1(sc, reg)     \=0A=
        bus_space_read_1(sc->fet_btag, sc->fet_bhandle, reg)=0A=
=0A=
#define FET_TIMEOUT              1000=0A=
=0A=
/*=0A=
 * General constants that are fun to know.=0A=
 *=0A=
 *  PCI vendor ID=0A=
 */=0A=
#define FETVENDORID           0x1516=0A=
=0A=
/*=0A=
 * FETSON device IDs.=0A=
 */=0A=
#define ID0                0x0800=0A=
#define ID1                0x0803=0A=
#define ID2                0x0891=0A=
=0A=
/*=0A=
 * ST+OP+PHYAD+REGAD+TA=0A=
 */=0A=
#define FET_OP_READ      0x6000  /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */=0A=
#define FET_OP_WRITE     0x5002  /* ST:01+OP:01+PHYAD+REGAD+TA:10 */=0A=
=0A=
/*=0A=
 * Constansts for Myson PHY=0A=
 */=0A=
#define MysonPHYID0     0x0300=0A=
=0A=
/*=0A=
 * Constansts for Seeq 80225 PHY=0A=
 */=0A=
#define SeeqPHYID0      0x0016=0A=
=0A=
#define SEEQ_MIIRegister18      18=0A=
#define SEEQ_SPD_DET_100        0x80=0A=
#define SEEQ_DPLX_DET_FULL      0x40=0A=
=0A=
/*=0A=
 * Constansts for Ahdoc 101 PHY=0A=
 */=0A=
#define AhdocPHYID0     0x0022=0A=
=0A=
#define AHDOC_DiagnosticReg     18=0A=
#define AHDOC_DPLX_FULL         0x0800=0A=
#define AHDOC_Speed_100         0x0400=0A=
=0A=
/*=0A=
 * Constansts for Marvell 88E1000/88E1000S PHY and LevelOne PHY=0A=
 */=0A=
#define MarvellPHYID0           0x0141=0A=
#define LevelOnePHYID0		0x0013=0A=
=0A=
#define Marvell_SpecificStatus  17=0A=
#define Marvell_Speed1000       0x8000=0A=
#define Marvell_Speed100        0x4000=0A=
#define Marvell_FullDuplex      0x2000=0A=
=0A=
/*=0A=
 * PCI low memory base and low I/O base register, and=0A=
 * other PCI registers. Note: some are only available on=0A=
 * the 3c905B, in particular those that related to power management.=0A=
 */=0A=
#define FET_PCI_VENDOR_ID        0x00=0A=
#define FET_PCI_DEVICE_ID        0x02=0A=
#define FET_PCI_COMMAND          0x04=0A=
#define FET_PCI_STATUS           0x06=0A=
#define FET_PCI_CLASSCODE        0x09=0A=
#define FET_PCI_LATENCY_TIMER    0x0D=0A=
#define FET_PCI_HEADER_TYPE      0x0E=0A=
#define FET_PCI_LOIO             0x10=0A=
#define FET_PCI_LOMEM            0x14=0A=
#define FET_PCI_BIOSROM          0x30=0A=
#define FET_PCI_INTLINE          0x3C=0A=
#define FET_PCI_INTPIN           0x3D=0A=
#define FET_PCI_MINGNT           0x3E=0A=
#define FET_PCI_MINLAT           0x0F=0A=
#define FET_PCI_RESETOPT         0x48=0A=
#define FET_PCI_EEPROM_DATA      0x4C=0A=
=0A=
#define PHY_UNKNOWN             3=0A=
=0A=
#define FET_PHYADDR_MIN          0x00=0A=
#define FET_PHYADDR_MAX          0x1F=0A=
=0A=
#define PHY_BMCR                0x00=0A=
#define PHY_BMSR                0x01=0A=
#define PHY_VENID               0x02=0A=
#define PHY_DEVID               0x03=0A=
#define PHY_ANAR                0x04=0A=
#define PHY_LPAR                0x05=0A=
#define PHY_ANEXP               0x06=0A=
#define PHY_NPTR                0x07=0A=
#define PHY_LPNPR               0x08=0A=
#define PHY_1000CR              0x09=0A=
#define PHY_1000SR              0x0a=0A=
=0A=
#define PHY_ANAR_NEXTPAGE       0x8000=0A=
#define PHY_ANAR_RSVD0          0x4000=0A=
#define PHY_ANAR_TLRFLT         0x2000=0A=
#define PHY_ANAR_RSVD1          0x1000=0A=
#define PHY_ANAR_RSVD2          0x0800=0A=
#define PHY_ANAR_RSVD3          0x0400=0A=
#define PHY_ANAR_100BT4         0x0200L=0A=
#define PHY_ANAR_100BTXFULL     0x0100=0A=
#define PHY_ANAR_100BTXHALF     0x0080=0A=
#define PHY_ANAR_10BTFULL       0x0040=0A=
#define PHY_ANAR_10BTHALF       0x0020=0A=
#define PHY_ANAR_PROTO4         0x0010=0A=
#define PHY_ANAR_PROTO3         0x0008=0A=
#define PHY_ANAR_PROTO2         0x0004=0A=
#define PHY_ANAR_PROTO1         0x0002=0A=
#define PHY_ANAR_PROTO0         0x0001=0A=
=0A=
#define PHY_1000SR_1000BTXFULL  0x0800=0A=
#define PHY_1000SR_1000BTXHALF  0x0400=0A=
=0A=
/*=0A=
 * These are the register definitions for the PHY (physical layer=0A=
 * interface chip).=0A=
 */=0A=
/*=0A=
 * PHY BMCR Basic Mode Control Register=0A=
 */=0A=
#define PHY_BMCR_RESET                  0x8000=0A=
#define PHY_BMCR_LOOPBK                 0x4000=0A=
#define PHY_BMCR_SPEEDSEL               0x2000=0A=
#define PHY_BMCR_AUTONEGENBL            0x1000=0A=
#define PHY_BMCR_RSVD0                  0x0800  /* write as zero */=0A=
#define PHY_BMCR_ISOLATE                0x0400=0A=
#define PHY_BMCR_AUTONEGRSTR            0x0200=0A=
#define PHY_BMCR_DUPLEX                 0x0100=0A=
#define PHY_BMCR_COLLTEST               0x0080=0A=
#define PHY_BMCR_1000                   0x0040  /* only used for Marvell =
PHY */=0A=
#define PHY_BMCR_RSVD2                  0x0020  /* write as zero, don't =
care */=0A=
#define PHY_BMCR_RSVD3                  0x0010  /* write as zero, don't =
care */=0A=
#define PHY_BMCR_RSVD4                  0x0008  /* write as zero, don't =
care */=0A=
#define PHY_BMCR_RSVD5                  0x0004  /* write as zero, don't =
care */=0A=
#define PHY_BMCR_RSVD6                  0x0002  /* write as zero, don't =
care */=0A=
#define PHY_BMCR_RSVD7                  0x0001  /* write as zero, don't =
care */=0A=
=0A=
/*=0A=
 * RESET: 1 =3D=3D software reset, 0 =3D=3D normal operation=0A=
 * Resets status and control registers to default values.=0A=
 * Relatches all hardware config values.=0A=
 *=0A=
 * LOOPBK: 1 =3D=3D loopback operation enabled, 0 =3D=3D normal operation=0A=
 *=0A=
 * SPEEDSEL: 1 =3D=3D 100Mb/s, 0 =3D=3D 10Mb/s=0A=
 * Link speed is selected byt his bit or if auto-negotiation if bit=0A=
 * 12 (AUTONEGENBL) is set (in which case the value of this register=0A=
 * is ignored).=0A=
 *=0A=
 * AUTONEGENBL: 1 =3D=3D Autonegotiation enabled, 0 =3D=3D =
Autonegotiation disabled=0A=
 * Bits 8 and 13 are ignored when autoneg is set, otherwise bits 8 and 13=0A=
 * determine speed and mode. Should be cleared and then set if PHY =
configured=0A=
 * for no autoneg on startup.=0A=
 *=0A=
 * ISOLATE: 1 =3D=3D isolate PHY from MII, 0 =3D=3D normal operation=0A=
 *=0A=
 * AUTONEGRSTR: 1 =3D=3D restart autonegotiation, 0 =3D normal operation=0A=
 *=0A=
 * DUPLEX: 1 =3D=3D full duplex mode, 0 =3D=3D half duplex mode=0A=
 *=0A=
 * COLLTEST: 1 =3D=3D collision test enabled, 0 =3D=3D normal operation=0A=
 */=0A=
=0A=
/*=0A=
 * PHY, BMSR Basic Mode Status Register=0A=
 */=0A=
#define PHY_BMSR_100BT4                 0x8000=0A=
#define PHY_BMSR_100BTXFULL             0x4000=0A=
#define PHY_BMSR_100BTXHALF             0x2000=0A=
#define PHY_BMSR_10BTFULL               0x1000=0A=
#define PHY_BMSR_10BTHALF               0x0800=0A=
#define PHY_BMSR_RSVD1                  0x0400  /* write as zero, don't =
care */=0A=
#define PHY_BMSR_RSVD2                  0x0200  /* write as zero, don't =
care */=0A=
#define PHY_BMSR_RSVD3                  0x0100  /* write as zero, don't =
care */=0A=
#define PHY_BMSR_RSVD4                  0x0080  /* write as zero, don't =
care */=0A=
#define PHY_BMSR_MFPRESUP               0x0040=0A=
#define PHY_BMSR_AUTONEGCOMP            0x0020=0A=
#define PHY_BMSR_REMFAULT               0x0010=0A=
#define PHY_BMSR_CANAUTONEG             0x0008=0A=
#define PHY_BMSR_LINKSTAT               0x0004=0A=
#define PHY_BMSR_JABBER                 0x0002=0A=
#define PHY_BMSR_EXTENDED               0x0001=0A=

------=_NextPart_000_0011_01C2FFB8.64D15160--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?001501c2ffa7$a31970d0$0100000a>