/*
 * register definitions.
 */
#define FET_PAR0         0x0     /* physical address 0-3 */
#define FET_PAR1         0x04    /* physical address 4-5 */
#define FET_MAR0         0x08    /* multicast address 0-3 */
#define FET_MAR1         0x0C    /* multicast address 4-7 */
#define FET_FAR0         0x10    /* flow-control address 0-3 */
#define FET_FAR1         0x14    /* flow-control address 4-5 */
#define FET_TCRRCR       0x18    /* receive & transmit configuration */
#define FET_BCR          0x1C    /* bus command */
#define FET_TXPDR        0x20    /* transmit polling demand */
#define FET_RXPDR        0x24    /* receive polling demand */
#define FET_RXCWP        0x28    /* receive current word pointer */
#define FET_TXLBA        0x2C    /* transmit list base address */
#define FET_RXLBA        0x30    /* receive list base address */
#define FET_ISR          0x34    /* interrupt status */
#define FET_IMR          0x38    /* interrupt mask */
#define FET_FTH          0x3C    /* flow control high/low threshold */
#define FET_MANAGEMENT   0x40    /* bootrom/eeprom and mii management */
#define FET_TALLY        0x44    /* tally counters for crc and mpa */
#define FET_TSR          0x48    /* tally counter for transmit status */
#define FET_PHYBASE	0x4c

/*
 * Receive Configuration Register
 */
#define FET_RXRUN        0x00008000      /* receive running status */
#define FET_EIEN         0x00004000      /* early interrupt enable */
#define FET_RFCEN        0x00002000      /* receive flow control packet enable */
#define FET_NDFA         0x00001000      /* not defined flow control address */
#define FET_RBLEN        0x00000800      /* receive burst length enable */
#define FET_RPBLE1       0x00000000      /* 1 word */
#define FET_RPBLE4       0x00000100      /* 4 words */
#define FET_RPBLE8       0x00000200      /* 8 words */
#define FET_RPBLE16      0x00000300      /* 16 words */
#define FET_RPBLE32      0x00000400      /* 32 words */
#define FET_RPBLE64      0x00000500      /* 64 words */
#define FET_RPBLE128     0x00000600      /* 128 words */
#define FET_RPBLE512     0x00000700      /* 512 words */
#define FET_PROM         0x000000080     /* promiscuous mode */
#define FET_AB           0x000000040     /* accept broadcast */
#define FET_AM           0x000000020     /* accept mutlicast */
#define FET_ARP          0x000000008     /* receive runt pkt */
#define FET_ALP          0x000000004     /* receive long pkt */
#define FET_SEP          0x000000002     /* receive error pkt */
#define FET_RE           0x000000001     /* receive enable */

/*
 * Transmit Configuration Register
 */
#define FET_TXRUN        0x04000000      /* transmit running status */
#define FET_Enhanced     0x02000000      /* transmit enhanced mode */
#define FET_TFCEN        0x01000000      /* tx flow control packet enable */
#define FET_TFT64        0x00000000      /* 64 bytes */
#define FET_TFT32        0x00200000      /* 32 bytes */
#define FET_TFT128       0x00400000      /* 128 bytes */
#define FET_TFT256       0x00600000      /* 256 bytes */
#define FET_TFT512       0x00800000      /* 512 bytes */
#define FET_TFT768       0x00A00000      /* 768 bytes */
#define FET_TFT1024      0x00C00000      /* 1024 bytes */
#define FET_TFTSF        0x00E00000      /* store and forward */
#define FET_FD           0x00100000      /* full duplex mode */
#define FET_PS10         0x00080000      /* port speed is 10M */
#define FET_TE           0x00040000      /* transmit enable */
#define FET_PS1000       0x00010000      /* port speed is 1000M */
/*
 * Bus Command Register
 */
#define FET_PROG		0x00000200	/* programming */
#define FET_RLE          0x00000100      /* read line command enable */
#define FET_RME          0x00000080      /* read multiple command enable */
#define FET_WIE          0x00000040      /* write and invalidate cmd enable */
#define FET_PBL1         0x00000000      /* 1 dword */
#define FET_PBL4         0x00000008      /* 4 dwords */
#define FET_PBL8         0x00000010      /* 8 dwords */
#define FET_PBL16        0x00000018      /* 16 dwords */
#define FET_PBL32        0x00000020      /* 32 dwords */
#define FET_PBL64        0x00000028      /* 64 dwords */
#define FET_PBL128       0x00000030      /* 128 dwords */
#define FET_PBL512       0x00000038      /* 512 dwords */
#define FET_ABR          0x00000004      /* arbitration rule */
#define FET_BLS          0x00000002      /* big/little endian select */
#define FET_SWR          0x00000001      /* software reset */

/*
 * Transmit Poll Demand Register
 */
#define FET_TxPollDemand 0x1

/*
 * Receive Poll Demand Register
 */
#define FET_RxPollDemand 0x01

/*
 * Interrupt Status Register
 */
#define FET_RFCON        0x00020000      /* receive flow control xon packet */
#define FET_RFCOFF       0x00010000      /* receive flow control xoff packet */
#define FET_LSCStatus    0x00008000      /* link status change */
#define FET_ANCStatus    0x00004000      /* autonegotiation completed */
#define FET_FBE          0x00002000      /* fatal bus error */
#define FET_FBEMask      0x00001800
#define FET_ParityErr    0x00000000      /* parity error */
#define FET_MasterErr    0x00000800      /* master error */
#define FET_TargetErr    0x00001000      /* target abort */
#define FET_TUNF         0x00000400      /* transmit underflow */
#define FET_ROVF         0x00000200      /* receive overflow */
#define FET_ETI          0x00000100      /* transmit early int */
#define FET_ERI          0x00000080      /* receive early int */
#define FET_CNTOVF       0x00000040      /* counter overflow */
#define FET_RBU          0x00000020      /* receive buffer unavailable */
#define FET_TBU          0x00000010      /* transmit buffer unavilable */
#define FET_TI           0x00000008      /* transmit interrupt */
#define FET_RI           0x00000004      /* receive interrupt */
#define FET_RxErr        0x00000002      /* receive error */

/*
 * Interrupt Mask Register
 */
#define FET_MRFCON       0x00020000      /* receive flow control xon packet */
#define FET_MRFCOFF      0x00010000      /* receive flow control xoff packet */
#define FET_MLSCStatus   0x00008000      /* link status change */
#define FET_MANCStatus   0x00004000      /* autonegotiation completed */
#define FET_MFBE         0x00002000      /* fatal bus error */
#define FET_MFBEMask     0x00001800
#define FET_MTUNF        0x00000400      /* transmit underflow */
#define FET_MROVF        0x00000200      /* receive overflow */
#define FET_METI         0x00000100      /* transmit early int */
#define FET_MERI         0x00000080      /* receive early int */
#define FET_MCNTOVF      0x00000040      /* counter overflow */
#define FET_MRBU         0x00000020      /* receive buffer unavailable */
#define FET_MTBU         0x00000010      /* transmit buffer unavilable */
#define FET_MTI          0x00000008      /* transmit interrupt */
#define FET_MRI          0x00000004      /* receive interrupt */
#define FET_MRxErr       0x00000002      /* receive error */

/* 90/1/18 delete */
/* #define FET_INTRS FET_FBE|FET_MRBU|FET_TBU|FET_MTI|FET_MRI|FET_METI */
#define FET_INTRS FET_MRBU|FET_TBU|FET_MTI|FET_MRI|FET_METI

/*
 * Flow Control High/Low Threshold Register
 */
#define FET_FCHTShift    16      /* flow control high threshold */
#define FET_FCLTShift    0       /* flow control low threshold */

/*
 * BootROM/EEPROM/MII Management Register
 */
#define FET_MASK_MIIR_MII_READ   0x00000000
#define FET_MASK_MIIR_MII_WRITE  0x00000008
#define FET_MASK_MIIR_MII_MDO    0x00000004
#define FET_MASK_MIIR_MII_MDI    0x00000002
#define FET_MASK_MIIR_MII_MDC    0x00000001

/*
 * Tally Counter for CRC and MPA
 */
#define FET_TCOVF        0x80000000      /* crc tally counter overflow */
#define FET_CRCMask      0x7fff0000      /* crc number: bit 16-30 */
#define FET_CRCShift     16
#define FET_TMOVF        0x00008000      /* mpa tally counter overflow */
#define FET_MPAMask      0x00007fff      /* mpa number: bit 0-14 */
#define FET_MPAShift     0

/*
 * Tally Counters for transmit status
 */
#define FET_AbortMask      0xff000000    /* transmit abort number */
#define FET_AbortShift     24
#define FET_LColMask       0x00ff0000    /* transmit late collisions */
#define FET_LColShift      16
#define FET_NCRMask        0x0000ffff    /* transmit retry number */
#define FET_NCRShift       0

/*
 * Myson TX/RX descriptor structure.
 */

struct fet_desc {
        u_int32_t       fet_status;
        u_int32_t       fet_ctl;
        u_int32_t       fet_data;
        u_int32_t       fet_next;
};

/*
 * for tx/rx descriptors
 */
#define FET_OWNByNIC     0x80000000
#define FET_OWNByDriver  0x0

/*
 * receive descriptor 0
 */
#define FET_RXOWN        0x80000000      /* own bit */
#define FET_FLNGMASK     0x0fff0000      /* frame length */
#define FET_FLNGShift    16
#define FET_MARSTATUS    0x00004000      /* multicast address received */
#define FET_BARSTATUS    0x00002000      /* broadcast address received */
#define FET_PHYSTATUS    0x00001000      /* physical address received */
#define FET_RXFSD        0x00000800      /* first descriptor */
#define FET_RXLSD        0x00000400      /* last descriptor */
#define FET_ES           0x00000080      /* error summary */
#define FET_RUNT         0x00000040      /* runt packet received */
#define FET_LONG         0x00000020      /* long packet received */
#define FET_FAE          0x00000010      /* frame align error */
#define FET_CRC          0x00000008      /* crc error */
#define FET_RXER         0x00000004      /* receive error */
#define FET_RDES0CHECK   0x000078fc      /* only check MAR, BAR, PHY, ES, RUNT,
                                           LONG, FAE, CRC and RXER bits */

/*
 * receive descriptor 1
 */
#define FET_RXIC         0x00800000      /* interrupt control */
#define FET_RBSMASK      0x000007ff      /* receive buffer size */
#define FET_RBSShift     0

/*
 * transmit descriptor 0
 */
#define FET_TXERR        0x00008000      /* transmit error */
#define FET_JABTO        0x00004000      /* jabber timeout */
#define FET_CSL          0x00002000      /* carrier sense lost */
#define FET_LC           0x00001000      /* late collision */
#define FET_EC           0x00000800      /* excessive collision */
#define FET_UDF          0x00000400      /* fifo underflow */
#define FET_DFR          0x00000200      /* deferred */
#define FET_HF           0x00000100      /* heartbeat fail */
#define FET_NCRMASK      0x000000ff      /* collision retry count */
#define FET_NCRShift     0

/*
 * tx descriptor 1
 */
#define FET_TXIC         0x80000000      /* interrupt control */
#define FET_ETIControl   0x40000000      /* early transmit interrupt */
#define FET_TXLD         0x20000000      /* last descriptor */
#define FET_TXFD         0x10000000      /* first descriptor */
#define FET_CRCDisable   0x00000000      /* crc control */
#define FET_CRCEnable    0x08000000
#define FET_PADDisable   0x00000000      /* padding control */
#define FET_PADEnable    0x04000000
#define FET_RetryTxLC	0x02000000	/* retry late collision */
#define FET_PKTShift     11              /* transmit pkt size */
#define FET_TBSMASK      0x000007ff
#define FET_TBSShift     0               /* transmit buffer size */

#define FET_MAXFRAGS     1
#define FET_RX_LIST_CNT  64
#define FET_TX_LIST_CNT  64
#define FET_MIN_FRAMELEN 60

/*
 * A transmit 'super descriptor' is actually FET_MAXFRAGS regular
 * descriptors clumped together. The idea here is to emulate the
 * multi-fragment descriptor layout found in devices such as the
 * Texas Instruments ThunderLAN and 3Com boomerang and cylone chips.
 * The advantage to using this scheme is that it avoids buffer copies.
 * The disadvantage is that there's a certain amount of overhead due
 * to the fact that each 'fragment' is 16 bytes long. In fet tests,
 * this limits top speed to about 10.5MB/sec. It should be more like
 * 11.5MB/sec. However, the upshot is that you can achieve better
 * results on slower machines: a Pentium 200 can pump out packets at
 * same speed as a PII 400.
 */
struct fet_txdesc {
        struct fet_desc          fet_frag[FET_MAXFRAGS];
};

#define FET_TXSTATUS(x)  x->fet_ptr->fet_frag[x->fet_lastdesc].fet_status
#define FET_TXCTL(x)     x->fet_ptr->fet_frag[x->fet_lastdesc].fet_ctl
#define FET_TXDATA(x)    x->fet_ptr->fet_frag[x->fet_lastdesc].fet_data
#define FET_TXNEXT(x)    x->fet_ptr->fet_frag[x->fet_lastdesc].fet_next

#define FET_TXOWN(x)     x->fet_ptr->fet_frag[0].fet_status

#define FET_UNSENT       0x1234

struct fet_list_data {
        struct fet_desc          fet_rx_list[FET_RX_LIST_CNT];
        struct fet_txdesc        fet_tx_list[FET_TX_LIST_CNT];
};

struct fet_chain {
        struct fet_txdesc        *fet_ptr;
        struct mbuf             *fet_mbuf;
        struct fet_chain         *fet_nextdesc;
        u_int8_t                fet_lastdesc;
};

struct fet_chain_onefrag {
        struct fet_desc          *fet_ptr;
        struct mbuf             *fet_mbuf;
        struct fet_chain_onefrag *fet_nextdesc;
        u_int8_t                fet_rlast;
};

struct fet_chain_data {
        struct fet_chain_onefrag fet_rx_chain[FET_RX_LIST_CNT];
        struct fet_chain         fet_tx_chain[FET_TX_LIST_CNT];

        struct fet_chain_onefrag *fet_rx_head;

        struct fet_chain         *fet_tx_head;
        struct fet_chain         *fet_tx_tail;
        struct fet_chain         *fet_tx_free;
};

struct fet_type {
        u_int16_t               fet_vid;
        u_int16_t               fet_did;
        char                    *fet_name;
};

#define FET_FLAG_FORCEDELAY      1
#define FET_FLAG_SCHEDDELAY      2
#define FET_FLAG_DELAYTIMEO      3

struct fet_softc {
        struct arpcom           arpcom;         /* interface info */
        struct ifmedia          ifmedia;        /* media info */
        bus_space_handle_t      fet_bhandle;
        bus_space_tag_t         fet_btag;
        struct fet_type          *fet_info;       /* adapter info */
        struct fet_type          *fet_pinfo;      /* phy info */
        u_int8_t                fet_unit;        /* interface number */
        u_int8_t                fet_type;
        u_int8_t                fet_phy_addr;    /* PHY address */
        u_int8_t                fet_tx_pend;     /* TX pending */
        u_int8_t                fet_want_auto;
        u_int8_t                fet_autoneg;
        u_int16_t               fet_txthresh;
        caddr_t                 fet_ldata_ptr;
        struct fet_list_data     *fet_ldata;
        struct fet_chain_data    fet_cdata;
};

/*
 * register space access macros
 */
#define CSR_WRITE_4(sc, reg, val)       \
        bus_space_write_4(sc->fet_btag, sc->fet_bhandle, reg, val)
#define CSR_WRITE_2(sc, reg, val)       \
        bus_space_write_2(sc->fet_btag, sc->fet_bhandle, reg, val)
#define CSR_WRITE_1(sc, reg, val)       \
        bus_space_write_1(sc->fet_btag, sc->fet_bhandle, reg, val)

#define CSR_READ_4(sc, reg)     \
        bus_space_read_4(sc->fet_btag, sc->fet_bhandle, reg)
#define CSR_READ_2(sc, reg)     \
        bus_space_read_2(sc->fet_btag, sc->fet_bhandle, reg)
#define CSR_READ_1(sc, reg)     \
        bus_space_read_1(sc->fet_btag, sc->fet_bhandle, reg)

#define FET_TIMEOUT              1000

/*
 * General constants that are fun to know.
 *
 *  PCI vendor ID
 */
#define FETVENDORID           0x1516

/*
 * FETSON device IDs.
 */
#define ID0                0x0800
#define ID1                0x0803
#define ID2                0x0891

/*
 * ST+OP+PHYAD+REGAD+TA
 */
#define FET_OP_READ      0x6000  /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */
#define FET_OP_WRITE     0x5002  /* ST:01+OP:01+PHYAD+REGAD+TA:10 */

/*
 * Constansts for Myson PHY
 */
#define MysonPHYID0     0x0300

/*
 * Constansts for Seeq 80225 PHY
 */
#define SeeqPHYID0      0x0016

#define SEEQ_MIIRegister18      18
#define SEEQ_SPD_DET_100        0x80
#define SEEQ_DPLX_DET_FULL      0x40

/*
 * Constansts for Ahdoc 101 PHY
 */
#define AhdocPHYID0     0x0022

#define AHDOC_DiagnosticReg     18
#define AHDOC_DPLX_FULL         0x0800
#define AHDOC_Speed_100         0x0400

/*
 * Constansts for Marvell 88E1000/88E1000S PHY and LevelOne PHY
 */
#define MarvellPHYID0           0x0141
#define LevelOnePHYID0		0x0013

#define Marvell_SpecificStatus  17
#define Marvell_Speed1000       0x8000
#define Marvell_Speed100        0x4000
#define Marvell_FullDuplex      0x2000

/*
 * PCI low memory base and low I/O base register, and
 * other PCI registers. Note: some are only available on
 * the 3c905B, in particular those that related to power management.
 */
#define FET_PCI_VENDOR_ID        0x00
#define FET_PCI_DEVICE_ID        0x02
#define FET_PCI_COMMAND          0x04
#define FET_PCI_STATUS           0x06
#define FET_PCI_CLASSCODE        0x09
#define FET_PCI_LATENCY_TIMER    0x0D
#define FET_PCI_HEADER_TYPE      0x0E
#define FET_PCI_LOIO             0x10
#define FET_PCI_LOMEM            0x14
#define FET_PCI_BIOSROM          0x30
#define FET_PCI_INTLINE          0x3C
#define FET_PCI_INTPIN           0x3D
#define FET_PCI_MINGNT           0x3E
#define FET_PCI_MINLAT           0x0F
#define FET_PCI_RESETOPT         0x48
#define FET_PCI_EEPROM_DATA      0x4C

#define PHY_UNKNOWN             3

#define FET_PHYADDR_MIN          0x00
#define FET_PHYADDR_MAX          0x1F

#define PHY_BMCR                0x00
#define PHY_BMSR                0x01
#define PHY_VENID               0x02
#define PHY_DEVID               0x03
#define PHY_ANAR                0x04
#define PHY_LPAR                0x05
#define PHY_ANEXP               0x06
#define PHY_NPTR                0x07
#define PHY_LPNPR               0x08
#define PHY_1000CR              0x09
#define PHY_1000SR              0x0a

#define PHY_ANAR_NEXTPAGE       0x8000
#define PHY_ANAR_RSVD0          0x4000
#define PHY_ANAR_TLRFLT         0x2000
#define PHY_ANAR_RSVD1          0x1000
#define PHY_ANAR_RSVD2          0x0800
#define PHY_ANAR_RSVD3          0x0400
#define PHY_ANAR_100BT4         0x0200L
#define PHY_ANAR_100BTXFULL     0x0100
#define PHY_ANAR_100BTXHALF     0x0080
#define PHY_ANAR_10BTFULL       0x0040
#define PHY_ANAR_10BTHALF       0x0020
#define PHY_ANAR_PROTO4         0x0010
#define PHY_ANAR_PROTO3         0x0008
#define PHY_ANAR_PROTO2         0x0004
#define PHY_ANAR_PROTO1         0x0002
#define PHY_ANAR_PROTO0         0x0001

#define PHY_1000SR_1000BTXFULL  0x0800
#define PHY_1000SR_1000BTXHALF  0x0400

/*
 * These are the register definitions for the PHY (physical layer
 * interface chip).
 */
/*
 * PHY BMCR Basic Mode Control Register
 */
#define PHY_BMCR_RESET                  0x8000
#define PHY_BMCR_LOOPBK                 0x4000
#define PHY_BMCR_SPEEDSEL               0x2000
#define PHY_BMCR_AUTONEGENBL            0x1000
#define PHY_BMCR_RSVD0                  0x0800  /* write as zero */
#define PHY_BMCR_ISOLATE                0x0400
#define PHY_BMCR_AUTONEGRSTR            0x0200
#define PHY_BMCR_DUPLEX                 0x0100
#define PHY_BMCR_COLLTEST               0x0080
#define PHY_BMCR_1000                   0x0040  /* only used for Marvell PHY */
#define PHY_BMCR_RSVD2                  0x0020  /* write as zero, don't care */
#define PHY_BMCR_RSVD3                  0x0010  /* write as zero, don't care */
#define PHY_BMCR_RSVD4                  0x0008  /* write as zero, don't care */
#define PHY_BMCR_RSVD5                  0x0004  /* write as zero, don't care */
#define PHY_BMCR_RSVD6                  0x0002  /* write as zero, don't care */
#define PHY_BMCR_RSVD7                  0x0001  /* write as zero, don't care */

/*
 * RESET: 1 == software reset, 0 == normal operation
 * Resets status and control registers to default values.
 * Relatches all hardware config values.
 *
 * LOOPBK: 1 == loopback operation enabled, 0 == normal operation
 *
 * SPEEDSEL: 1 == 100Mb/s, 0 == 10Mb/s
 * Link speed is selected byt his bit or if auto-negotiation if bit
 * 12 (AUTONEGENBL) is set (in which case the value of this register
 * is ignored).
 *
 * AUTONEGENBL: 1 == Autonegotiation enabled, 0 == Autonegotiation disabled
 * Bits 8 and 13 are ignored when autoneg is set, otherwise bits 8 and 13
 * determine speed and mode. Should be cleared and then set if PHY configured
 * for no autoneg on startup.
 *
 * ISOLATE: 1 == isolate PHY from MII, 0 == normal operation
 *
 * AUTONEGRSTR: 1 == restart autonegotiation, 0 = normal operation
 *
 * DUPLEX: 1 == full duplex mode, 0 == half duplex mode
 *
 * COLLTEST: 1 == collision test enabled, 0 == normal operation
 */

/*
 * PHY, BMSR Basic Mode Status Register
 */
#define PHY_BMSR_100BT4                 0x8000
#define PHY_BMSR_100BTXFULL             0x4000
#define PHY_BMSR_100BTXHALF             0x2000
#define PHY_BMSR_10BTFULL               0x1000
#define PHY_BMSR_10BTHALF               0x0800
#define PHY_BMSR_RSVD1                  0x0400  /* write as zero, don't care */
#define PHY_BMSR_RSVD2                  0x0200  /* write as zero, don't care */
#define PHY_BMSR_RSVD3                  0x0100  /* write as zero, don't care */
#define PHY_BMSR_RSVD4                  0x0080  /* write as zero, don't care */
#define PHY_BMSR_MFPRESUP               0x0040
#define PHY_BMSR_AUTONEGCOMP            0x0020
#define PHY_BMSR_REMFAULT               0x0010
#define PHY_BMSR_CANAUTONEG             0x0008
#define PHY_BMSR_LINKSTAT               0x0004
#define PHY_BMSR_JABBER                 0x0002
#define PHY_BMSR_EXTENDED               0x0001
