Home | History | Annotate | Download | only in net
      1 /**************************************************************************
      2 *
      3 *    mtd80x.c: Etherboot device driver for the mtd80x Ethernet chip.
      4 *    Written 2004-2004 by Erdem Gven <zuencap (at) yahoo.com>
      5 *
      6 *    This program is free software; you can redistribute it and/or modify
      7 *    it under the terms of the GNU General Public License as published by
      8 *    the Free Software Foundation; either version 2 of the License, or
      9 *    (at your option) any later version.
     10 *
     11 *    This program is distributed in the hope that it will be useful,
     12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 *    GNU General Public License for more details.
     15 *
     16 *    You should have received a copy of the GNU General Public License
     17 *    along with this program; if not, write to the Free Software
     18 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19 *
     20 *    Portions of this code based on:
     21 *               fealnx.c: A Linux device driver for the mtd80x Ethernet chip
     22 *               Written 1998-2000 by Donald Becker
     23 *
     24 ***************************************************************************/
     25 
     26 FILE_LICENCE ( GPL2_OR_LATER );
     27 
     28 /* to get some global routines like printf */
     29 #include "etherboot.h"
     30 /* to get the interface to the body of the program */
     31 #include "nic.h"
     32 /* to get the PCI support functions, if this is a PCI NIC */
     33 #include <gpxe/pci.h>
     34 #include <gpxe/ethernet.h>
     35 #include <mii.h>
     36 
     37 /* Condensed operations for readability. */
     38 #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
     39 #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
     40 #define get_unaligned(ptr) (*(ptr))
     41 
     42 
     43 /* Operational parameters that are set at compile time. */
     44 
     45 /* Keep the ring sizes a power of two for compile efficiency.           */
     46 /* The compiler will convert <unsigned>'%'<2^N> into a bit mask.        */
     47 /* Making the Tx ring too large decreases the effectiveness of channel  */
     48 /* bonding and packet priority.                                         */
     49 /* There are no ill effects from too-large receive rings.               */
     50 #define TX_RING_SIZE 2
     51 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used.  */
     52 #define RX_RING_SIZE 4
     53 
     54 /* Operational parameters that usually are not changed. */
     55 /* Time in jiffies before concluding the transmitter is hung. */
     56 #define HZ 100
     57 #define TX_TIME_OUT   (6*HZ)
     58 
     59 /* Allocation size of Rx buffers with normal sized Ethernet frames.
     60    Do not change this value without good reason.  This is not a limit,
     61    but a way to keep a consistent allocation size among drivers.
     62  */
     63 #define PKT_BUF_SZ 1536
     64 
     65 /* for different PHY */
     66 enum phy_type_flags {
     67     MysonPHY = 1,
     68     AhdocPHY = 2,
     69     SeeqPHY = 3,
     70     MarvellPHY = 4,
     71     Myson981 = 5,
     72     LevelOnePHY = 6,
     73     OtherPHY = 10,
     74 };
     75 
     76 /* A chip capabilities table*/
     77 enum chip_capability_flags {
     78     HAS_MII_XCVR,
     79     HAS_CHIP_XCVR,
     80 };
     81 
     82 #if 0 /* not used */
     83 static
     84 struct chip_info
     85 {
     86     u16 dev_id;
     87     int flag;
     88 }
     89 mtd80x_chips[] = {
     90                      {0x0800, HAS_MII_XCVR},
     91                      {0x0803, HAS_CHIP_XCVR},
     92                      {0x0891, HAS_MII_XCVR}
     93                  };
     94 static int chip_cnt = sizeof( mtd80x_chips ) / sizeof( struct chip_info );
     95 #endif
     96 
     97 /* Offsets to the Command and Status Registers. */
     98 enum mtd_offsets {
     99     PAR0 = 0x0,        /* physical address 0-3 */
    100     PAR1 = 0x04,        /* physical address 4-5 */
    101     MAR0 = 0x08,        /* multicast address 0-3 */
    102     MAR1 = 0x0C,        /* multicast address 4-7 */
    103     FAR0 = 0x10,        /* flow-control address 0-3 */
    104     FAR1 = 0x14,        /* flow-control address 4-5 */
    105     TCRRCR = 0x18,        /* receive & transmit configuration */
    106     BCR = 0x1C,        /* bus command */
    107     TXPDR = 0x20,        /* transmit polling demand */
    108     RXPDR = 0x24,        /* receive polling demand */
    109     RXCWP = 0x28,        /* receive current word pointer */
    110     TXLBA = 0x2C,        /* transmit list base address */
    111     RXLBA = 0x30,        /* receive list base address */
    112     ISR = 0x34,        /* interrupt status */
    113     IMR = 0x38,        /* interrupt mask */
    114     FTH = 0x3C,        /* flow control high/low threshold */
    115     MANAGEMENT = 0x40,    /* bootrom/eeprom and mii management */
    116     TALLY = 0x44,        /* tally counters for crc and mpa */
    117     TSR = 0x48,        /* tally counter for transmit status */
    118     BMCRSR = 0x4c,        /* basic mode control and status */
    119     PHYIDENTIFIER = 0x50,    /* phy identifier */
    120     ANARANLPAR = 0x54,    /* auto-negotiation advertisement and link
    121                                                        partner ability */
    122     ANEROCR = 0x58,        /* auto-negotiation expansion and pci conf. */
    123     BPREMRPSR = 0x5c,    /* bypass & receive error mask and phy status */
    124 };
    125 
    126 /* Bits in the interrupt status/enable registers. */
    127 /* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
    128 enum intr_status_bits {
    129     RFCON = 0x00020000, /* receive flow control xon packet */
    130     RFCOFF = 0x00010000, /* receive flow control xoff packet */
    131     LSCStatus = 0x00008000, /* link status change */
    132     ANCStatus = 0x00004000, /* autonegotiation completed */
    133     FBE = 0x00002000, /* fatal bus error */
    134     FBEMask = 0x00001800, /* mask bit12-11 */
    135     ParityErr = 0x00000000, /* parity error */
    136     TargetErr = 0x00001000, /* target abort */
    137     MasterErr = 0x00000800, /* master error */
    138     TUNF = 0x00000400, /* transmit underflow */
    139     ROVF = 0x00000200, /* receive overflow */
    140     ETI = 0x00000100, /* transmit early int */
    141     ERI = 0x00000080, /* receive early int */
    142     CNTOVF = 0x00000040, /* counter overflow */
    143     RBU = 0x00000020, /* receive buffer unavailable */
    144     TBU = 0x00000010, /* transmit buffer unavilable */
    145     TI = 0x00000008, /* transmit interrupt */
    146     RI = 0x00000004, /* receive interrupt */
    147     RxErr = 0x00000002, /* receive error */
    148 };
    149 
    150 /* Bits in the NetworkConfig register. */
    151 enum rx_mode_bits {
    152     RxModeMask   = 0xe0,
    153     AcceptAllPhys = 0x80,        /* promiscuous mode */
    154     AcceptBroadcast = 0x40,        /* accept broadcast */
    155     AcceptMulticast = 0x20,        /* accept mutlicast */
    156     AcceptRunt   = 0x08,        /* receive runt pkt */
    157     ALP          = 0x04,        /* receive long pkt */
    158     AcceptErr    = 0x02,        /* receive error pkt */
    159 
    160     AcceptMyPhys = 0x00000000,
    161     RxEnable     = 0x00000001,
    162     RxFlowCtrl   = 0x00002000,
    163     TxEnable     = 0x00040000,
    164     TxModeFDX    = 0x00100000,
    165     TxThreshold  = 0x00e00000,
    166 
    167     PS1000       = 0x00010000,
    168     PS10         = 0x00080000,
    169     FD           = 0x00100000,
    170 };
    171 
    172 /* Bits in network_desc.status */
    173 enum rx_desc_status_bits {
    174     RXOWN = 0x80000000, /* own bit */
    175     FLNGMASK = 0x0fff0000, /* frame length */
    176     FLNGShift = 16,
    177     MARSTATUS = 0x00004000, /* multicast address received */
    178     BARSTATUS = 0x00002000, /* broadcast address received */
    179     PHYSTATUS = 0x00001000, /* physical address received */
    180     RXFSD = 0x00000800, /* first descriptor */
    181     RXLSD = 0x00000400, /* last descriptor */
    182     ErrorSummary = 0x80, /* error summary */
    183     RUNT = 0x40,  /* runt packet received */
    184     LONG = 0x20,  /* long packet received */
    185     FAE = 0x10,  /* frame align error */
    186     CRC = 0x08,  /* crc error */
    187     RXER = 0x04,  /* receive error */
    188 };
    189 
    190 enum rx_desc_control_bits {
    191     RXIC = 0x00800000, /* interrupt control */
    192     RBSShift = 0,
    193 };
    194 
    195 enum tx_desc_status_bits {
    196     TXOWN = 0x80000000, /* own bit */
    197     JABTO = 0x00004000, /* jabber timeout */
    198     CSL = 0x00002000, /* carrier sense lost */
    199     LC = 0x00001000, /* late collision */
    200     EC = 0x00000800, /* excessive collision */
    201     UDF = 0x00000400, /* fifo underflow */
    202     DFR = 0x00000200, /* deferred */
    203     HF = 0x00000100, /* heartbeat fail */
    204     NCRMask = 0x000000ff, /* collision retry count */
    205     NCRShift = 0,
    206 };
    207 
    208 enum tx_desc_control_bits {
    209     TXIC = 0x80000000, /* interrupt control */
    210     ETIControl = 0x40000000, /* early transmit interrupt */
    211     TXLD = 0x20000000, /* last descriptor */
    212     TXFD = 0x10000000, /* first descriptor */
    213     CRCEnable = 0x08000000, /* crc control */
    214     PADEnable = 0x04000000, /* padding control */
    215     RetryTxLC = 0x02000000, /* retry late collision */
    216     PKTSMask = 0x3ff800, /* packet size bit21-11 */
    217     PKTSShift = 11,
    218     TBSMask = 0x000007ff, /* transmit buffer bit 10-0 */
    219     TBSShift = 0,
    220 };
    221 
    222 /* BootROM/EEPROM/MII Management Register */
    223 #define MASK_MIIR_MII_READ       0x00000000
    224 #define MASK_MIIR_MII_WRITE      0x00000008
    225 #define MASK_MIIR_MII_MDO        0x00000004
    226 #define MASK_MIIR_MII_MDI        0x00000002
    227 #define MASK_MIIR_MII_MDC        0x00000001
    228 
    229 /* ST+OP+PHYAD+REGAD+TA */
    230 #define OP_READ             0x6000 /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */
    231 #define OP_WRITE            0x5002 /* ST:01+OP:01+PHYAD+REGAD+TA:10 */
    232 
    233 /* ------------------------------------------------------------------------- */
    234 /*      Constants for Myson PHY                                              */
    235 /* ------------------------------------------------------------------------- */
    236 #define MysonPHYID      0xd0000302
    237 /* 89-7-27 add, (begin) */
    238 #define MysonPHYID0     0x0302
    239 #define StatusRegister  18
    240 #define SPEED100        0x0400 // bit10
    241 #define FULLMODE        0x0800 // bit11
    242 /* 89-7-27 add, (end) */
    243 
    244 /* ------------------------------------------------------------------------- */
    245 /*      Constants for Seeq 80225 PHY                                         */
    246 /* ------------------------------------------------------------------------- */
    247 #define SeeqPHYID0      0x0016
    248 
    249 #define MIIRegister18   18
    250 #define SPD_DET_100     0x80
    251 #define DPLX_DET_FULL   0x40
    252 
    253 /* ------------------------------------------------------------------------- */
    254 /*      Constants for Ahdoc 101 PHY                                          */
    255 /* ------------------------------------------------------------------------- */
    256 #define AhdocPHYID0     0x0022
    257 
    258 #define DiagnosticReg   18
    259 #define DPLX_FULL       0x0800
    260 #define Speed_100       0x0400
    261 
    262 /* 89/6/13 add, */
    263 /* -------------------------------------------------------------------------- */
    264 /*      Constants                                                             */
    265 /* -------------------------------------------------------------------------- */
    266 #define MarvellPHYID0           0x0141
    267 #define LevelOnePHYID0  0x0013
    268 
    269 #define MII1000BaseTControlReg  9
    270 #define MII1000BaseTStatusReg   10
    271 #define SpecificReg  17
    272 
    273 /* for 1000BaseT Control Register */
    274 #define PHYAbletoPerform1000FullDuplex  0x0200
    275 #define PHYAbletoPerform1000HalfDuplex  0x0100
    276 #define PHY1000AbilityMask              0x300
    277 
    278 // for phy specific status register, marvell phy.
    279 #define SpeedMask       0x0c000
    280 #define Speed_1000M     0x08000
    281 #define Speed_100M      0x4000
    282 #define Speed_10M       0
    283 #define Full_Duplex     0x2000
    284 
    285 // 89/12/29 add, for phy specific status register, levelone phy, (begin)
    286 #define LXT1000_100M    0x08000
    287 #define LXT1000_1000M   0x0c000
    288 #define LXT1000_Full    0x200
    289 // 89/12/29 add, for phy specific status register, levelone phy, (end)
    290 
    291 #if 0
    292 /* for 3-in-1 case */
    293 #define PS10            0x00080000
    294 #define FD              0x00100000
    295 #define PS1000          0x00010000
    296 #endif
    297 
    298 /* for PHY */
    299 #define LinkIsUp        0x0004
    300 #define LinkIsUp2 0x00040000
    301 
    302 /* Create a static buffer of size PKT_BUF_SZ for each
    303 RX and TX Descriptor.  All descriptors point to a
    304 part of this buffer */
    305 struct {
    306 	u8 txb[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned(8)));
    307 	u8 rxb[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned(8)));
    308 } mtd80x_bufs __shared;
    309 #define txb mtd80x_bufs.txb
    310 #define rxb mtd80x_bufs.rxb
    311 
    312 /* The Tulip Rx and Tx buffer descriptors. */
    313 struct mtd_desc
    314 {
    315     s32 status;
    316     s32 control;
    317     u32 buffer;
    318     u32 next_desc;
    319     struct mtd_desc *next_desc_logical;
    320     u8* skbuff;
    321     u32 reserved1;
    322     u32 reserved2;
    323 };
    324 
    325 struct mtd_private
    326 {
    327     struct mtd_desc rx_ring[RX_RING_SIZE];
    328     struct mtd_desc tx_ring[TX_RING_SIZE];
    329 
    330     /* Frequently used values: keep some adjacent for cache effect. */
    331     int flags;
    332     struct pci_dev *pci_dev;
    333     unsigned long crvalue;
    334     unsigned long bcrvalue;
    335     /*unsigned long imrvalue;*/
    336     struct mtd_desc *cur_rx;
    337     struct mtd_desc *lack_rxbuf;
    338     int really_rx_count;
    339     struct mtd_desc *cur_tx;
    340     struct mtd_desc *cur_tx_copy;
    341     int really_tx_count;
    342     int free_tx_count;
    343     unsigned int rx_buf_sz; /* Based on MTU+slack. */
    344 
    345     /* These values are keep track of the transceiver/media in use. */
    346     unsigned int linkok;
    347     unsigned int line_speed;
    348     unsigned int duplexmode;
    349     unsigned int default_port:
    350     4; /* Last dev->if_port value. */
    351     unsigned int PHYType;
    352 
    353     /* MII transceiver section. */
    354     int mii_cnt;  /* MII device addresses. */
    355     unsigned char phys[1]; /* MII device addresses. */
    356 
    357     /*other*/
    358     const char *nic_name;
    359     int ioaddr;
    360     u16 dev_id;
    361 };
    362 
    363 static struct mtd_private mtdx;
    364 
    365 static int mdio_read(struct nic * , int phy_id, int location);
    366 static void getlinktype(struct nic * );
    367 static void getlinkstatus(struct nic * );
    368 static void set_rx_mode(struct nic *);
    369 
    370 /**************************************************************************
    371  *  init_ring - setup the tx and rx descriptors
    372  *************************************************************************/
    373 static void init_ring(struct nic *nic __unused)
    374 {
    375     int i;
    376 
    377     mtdx.cur_rx = &mtdx.rx_ring[0];
    378 
    379     mtdx.rx_buf_sz = PKT_BUF_SZ;
    380     /*mtdx.rx_head_desc = &mtdx.rx_ring[0];*/
    381 
    382     /* Initialize all Rx descriptors. */
    383     /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
    384     for (i = 0; i < RX_RING_SIZE; i++)
    385     {
    386         mtdx.rx_ring[i].status = RXOWN;
    387         mtdx.rx_ring[i].control = mtdx.rx_buf_sz << RBSShift;
    388         mtdx.rx_ring[i].next_desc = virt_to_le32desc(&mtdx.rx_ring[i+1]);
    389         mtdx.rx_ring[i].next_desc_logical = &mtdx.rx_ring[i+1];
    390         mtdx.rx_ring[i].buffer = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]);
    391         mtdx.rx_ring[i].skbuff = &rxb[i * PKT_BUF_SZ];
    392     }
    393     /* Mark the last entry as wrapping the ring. */
    394     mtdx.rx_ring[i-1].next_desc = virt_to_le32desc(&mtdx.rx_ring[0]);
    395     mtdx.rx_ring[i-1].next_desc_logical = &mtdx.rx_ring[0];
    396 
    397     /* We only use one transmit buffer, but two
    398      * descriptors so transmit engines have somewhere
    399      * to point should they feel the need */
    400     mtdx.tx_ring[0].status = 0x00000000;
    401     mtdx.tx_ring[0].buffer = virt_to_bus(&txb[0]);
    402     mtdx.tx_ring[0].next_desc = virt_to_le32desc(&mtdx.tx_ring[1]);
    403 
    404     /* This descriptor is never used */
    405     mtdx.tx_ring[1].status = 0x00000000;
    406     mtdx.tx_ring[1].buffer = 0; /*virt_to_bus(&txb[1]); */
    407     mtdx.tx_ring[1].next_desc = virt_to_le32desc(&mtdx.tx_ring[0]);
    408 
    409     return;
    410 }
    411 
    412 /**************************************************************************
    413 RESET - Reset Adapter
    414 ***************************************************************************/
    415 static void mtd_reset( struct nic *nic )
    416 {
    417     /* Reset the chip to erase previous misconfiguration. */
    418     outl(0x00000001, mtdx.ioaddr + BCR);
    419 
    420     init_ring(nic);
    421 
    422     outl(virt_to_bus(mtdx.rx_ring), mtdx.ioaddr + RXLBA);
    423     outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA);
    424 
    425     /* Initialize other registers. */
    426     /* Configure the PCI bus bursts and FIFO thresholds. */
    427     mtdx.bcrvalue = 0x10; /* little-endian, 8 burst length */
    428     mtdx.crvalue = 0xa00; /* rx 128 burst length */
    429 
    430 	if ( mtdx.dev_id == 0x891 ) {
    431 		mtdx.bcrvalue |= 0x200;	/* set PROG bit */
    432 		mtdx.crvalue |= 0x02000000;	/* set enhanced bit */
    433 	}
    434 
    435     outl( mtdx.bcrvalue, mtdx.ioaddr + BCR);
    436 
    437     /* Restart Rx engine if stopped. */
    438     outl(0, mtdx.ioaddr + RXPDR);
    439 
    440     getlinkstatus(nic);
    441     if (mtdx.linkok)
    442     {
    443         static const char* texts[]={"half","full","10","100","1000"};
    444         getlinktype(nic);
    445         DBG ( "Link is OK : %s %s\n", texts[mtdx.duplexmode-1], texts[mtdx.line_speed+1] );
    446     } else
    447     {
    448         DBG ( "No link!!!\n" );
    449     }
    450 
    451     mtdx.crvalue |= /*TxEnable |*/ RxEnable | TxThreshold;
    452     set_rx_mode(nic);
    453 
    454     /* Clear interrupts by setting the interrupt mask. */
    455     outl(FBE | TUNF | CNTOVF | RBU | TI | RI, mtdx.ioaddr + ISR);
    456     outl( 0, mtdx.ioaddr + IMR);
    457 }
    458 
    459 /**************************************************************************
    460 POLL - Wait for a frame
    461 ***************************************************************************/
    462 static int mtd_poll(struct nic *nic, __unused int retrieve)
    463 {
    464     s32 rx_status = mtdx.cur_rx->status;
    465     int retval = 0;
    466 
    467     if( ( rx_status & RXOWN ) != 0 )
    468     {
    469         return 0;
    470     }
    471 
    472     if (rx_status & ErrorSummary)
    473     { /* there was a fatal error */
    474         printf( "%s: Receive error, Rx status %8.8x, Error(s) %s%s%s\n",
    475                 mtdx.nic_name, (unsigned int) rx_status,
    476                 (rx_status & (LONG | RUNT)) ? "length_error ":"",
    477                 (rx_status & RXER) ? "frame_error ":"",
    478                 (rx_status & CRC) ? "crc_error ":"" );
    479         retval = 0;
    480     } else if( !((rx_status & RXFSD) && (rx_status & RXLSD)) )
    481     {
    482         /* this pkt is too long, over one rx buffer */
    483         printf("Pkt is too long, over one rx buffer.\n");
    484         retval = 0;
    485     } else
    486     { /* this received pkt is ok */
    487         /* Omit the four octet CRC from the length. */
    488         short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4;
    489 
    490         DBG ( " netdev_rx() normal Rx pkt length %d"
    491  	      " status %x.\n", pkt_len, (unsigned int) rx_status );
    492 
    493         nic->packetlen = pkt_len;
    494         memcpy(nic->packet, mtdx.cur_rx->skbuff, pkt_len);
    495 
    496         retval = 1;
    497     }
    498 
    499     while( ( mtdx.cur_rx->status & RXOWN ) == 0 )
    500     {
    501         mtdx.cur_rx->status = RXOWN;
    502         mtdx.cur_rx = mtdx.cur_rx->next_desc_logical;
    503     }
    504 
    505     /* Restart Rx engine if stopped. */
    506     outl(0, mtdx.ioaddr + RXPDR);
    507 
    508     return retval;
    509 }
    510 
    511 /**************************************************************************
    512 TRANSMIT - Transmit a frame
    513 ***************************************************************************/
    514 static void mtd_transmit(
    515     struct nic *nic,
    516     const char *dest,            /* Destination */
    517     unsigned int type,            /* Type */
    518     unsigned int size,            /* size */
    519     const char *data)            /* Packet */
    520 {
    521     u32 to;
    522     u32 tx_status;
    523     unsigned int nstype = htons ( type );
    524 
    525     memcpy( txb, dest, ETH_ALEN );
    526     memcpy( txb + ETH_ALEN, nic->node_addr, ETH_ALEN );
    527     memcpy( txb + 2 * ETH_ALEN, &nstype, 2 );
    528     memcpy( txb + ETH_HLEN, data, size );
    529 
    530     size += ETH_HLEN;
    531     size &= 0x0FFF;
    532     while( size < ETH_ZLEN )
    533     {
    534         txb[size++] = '\0';
    535     }
    536 
    537     mtdx.tx_ring[0].control = TXLD | TXFD | CRCEnable | PADEnable;
    538     mtdx.tx_ring[0].control |= (size << PKTSShift); /* pkt size */
    539     mtdx.tx_ring[0].control |= (size << TBSShift); /* buffer size */
    540     mtdx.tx_ring[0].status = TXOWN;
    541 
    542     /* Point to transmit descriptor */
    543     outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA);
    544     /* Enable Tx */
    545     outl( mtdx.crvalue | TxEnable, mtdx.ioaddr + TCRRCR);
    546     /* Wake the potentially-idle transmit channel. */
    547     outl(0, mtdx.ioaddr + TXPDR);
    548 
    549     to = currticks() + TX_TIME_OUT;
    550     while(( mtdx.tx_ring[0].status & TXOWN) && (currticks() < to));
    551 
    552     /* Disable Tx */
    553     outl( mtdx.crvalue & (~TxEnable), mtdx.ioaddr + TCRRCR);
    554 
    555     tx_status = mtdx.tx_ring[0].status;
    556     if (currticks() >= to){
    557         DBG ( "TX Time Out" );
    558     } else if( tx_status & (CSL | LC | EC | UDF | HF)){
    559         printf( "Transmit error: %8.8x %s %s %s %s %s\n",
    560                 (unsigned int) tx_status,
    561                 tx_status & EC ? "abort" : "",
    562                 tx_status & CSL ? "carrier" : "",
    563                 tx_status & LC ? "late" : "",
    564                 tx_status & UDF ? "fifo" : "",
    565                 tx_status & HF ? "heartbeat" : "" );
    566     }
    567 
    568     /*hex_dump( txb, size );*/
    569     /*pause();*/
    570 
    571     DBG ( "TRANSMIT\n" );
    572 }
    573 
    574 /**************************************************************************
    575 DISABLE - Turn off ethernet interface
    576 ***************************************************************************/
    577 static void mtd_disable ( struct nic *nic ) {
    578 
    579     /* Disable Tx Rx*/
    580     outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR );
    581 
    582     /* Reset the chip to erase previous misconfiguration. */
    583     mtd_reset(nic);
    584 
    585     DBG ( "DISABLE\n" );
    586 }
    587 
    588 static struct nic_operations mtd_operations = {
    589 	.connect	= dummy_connect,
    590 	.poll		= mtd_poll,
    591 	.transmit	= mtd_transmit,
    592 	.irq		= dummy_irq,
    593 
    594 };
    595 
    596 static struct pci_device_id mtd80x_nics[] = {
    597         PCI_ROM(0x1516, 0x0800, "MTD800", "Myson MTD800", 0),
    598         PCI_ROM(0x1516, 0x0803, "MTD803", "Surecom EP-320X", 0),
    599         PCI_ROM(0x1516, 0x0891, "MTD891", "Myson MTD891", 0),
    600 };
    601 
    602 PCI_DRIVER ( mtd80x_driver, mtd80x_nics, PCI_NO_CLASS );
    603 
    604 /**************************************************************************
    605 PROBE - Look for an adapter, this routine's visible to the outside
    606 ***************************************************************************/
    607 
    608 static int mtd_probe ( struct nic *nic, struct pci_device *pci ) {
    609 
    610     int i;
    611 
    612     if (pci->ioaddr == 0)
    613 	    return 0;
    614 
    615     adjust_pci_device(pci);
    616 
    617     nic->ioaddr = pci->ioaddr;
    618     nic->irqno = 0;
    619 
    620     mtdx.nic_name = pci->driver_name;
    621     mtdx.dev_id = pci->device;
    622     mtdx.ioaddr = nic->ioaddr;
    623 
    624     /* read ethernet id */
    625     for (i = 0; i < 6; ++i)
    626     {
    627         nic->node_addr[i] = inb(mtdx.ioaddr + PAR0 + i);
    628     }
    629 
    630     if (memcmp(nic->node_addr, "\0\0\0\0\0\0", 6) == 0)
    631     {
    632         return 0;
    633     }
    634 
    635     DBG ( "%s: ioaddr %4.4x MAC %s\n", mtdx.nic_name, mtdx.ioaddr, eth_ntoa ( nic->node_addr ) );
    636 
    637     /* Reset the chip to erase previous misconfiguration. */
    638     outl(0x00000001, mtdx.ioaddr + BCR);
    639 
    640     /* find the connected MII xcvrs */
    641 
    642     if( mtdx.dev_id != 0x803 )
    643     {
    644         int phy, phy_idx = 0;
    645 
    646         for (phy = 1; phy < 32 && phy_idx < 1; phy++) {
    647             int mii_status = mdio_read(nic, phy, 1);
    648 
    649             if (mii_status != 0xffff && mii_status != 0x0000) {
    650                 mtdx.phys[phy_idx] = phy;
    651 
    652                 DBG ( "%s: MII PHY found at address %d, status "
    653 		      "0x%4.4x.\n", mtdx.nic_name, phy, mii_status );
    654                 /* get phy type */
    655                 {
    656                     unsigned int data;
    657 
    658                     data = mdio_read(nic, mtdx.phys[phy_idx], 2);
    659                     if (data == SeeqPHYID0)
    660                         mtdx.PHYType = SeeqPHY;
    661                     else if (data == AhdocPHYID0)
    662                         mtdx.PHYType = AhdocPHY;
    663                     else if (data == MarvellPHYID0)
    664                         mtdx.PHYType = MarvellPHY;
    665                     else if (data == MysonPHYID0)
    666                         mtdx.PHYType = Myson981;
    667                     else if (data == LevelOnePHYID0)
    668                         mtdx.PHYType = LevelOnePHY;
    669                     else
    670                         mtdx.PHYType = OtherPHY;
    671                 }
    672                 phy_idx++;
    673             }
    674         }
    675 
    676         mtdx.mii_cnt = phy_idx;
    677         if (phy_idx == 0) {
    678             printf("%s: MII PHY not found -- this device may "
    679                    "not operate correctly.\n", mtdx.nic_name);
    680         }
    681     } else {
    682         mtdx.phys[0] = 32;
    683         /* get phy type */
    684         if (inl(mtdx.ioaddr + PHYIDENTIFIER) == MysonPHYID ) {
    685             mtdx.PHYType = MysonPHY;
    686             DBG ( "MysonPHY\n" );
    687         } else {
    688             mtdx.PHYType = OtherPHY;
    689             DBG ( "OtherPHY\n" );
    690         }
    691     }
    692 
    693     getlinkstatus(nic);
    694     if( !mtdx.linkok )
    695     {
    696         printf("No link!!!\n");
    697         return 0;
    698     }
    699 
    700     mtd_reset( nic );
    701 
    702     /* point to NIC specific routines */
    703     nic->nic_op	= &mtd_operations;
    704     return 1;
    705 }
    706 
    707 
    708 /**************************************************************************/
    709 static void set_rx_mode(struct nic *nic __unused)
    710 {
    711     u32 mc_filter[2];                       /* Multicast hash filter */
    712     u32 rx_mode;
    713 
    714     /* Too many to match, or accept all multicasts. */
    715     mc_filter[1] = mc_filter[0] = ~0;
    716     rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
    717 
    718     outl(mc_filter[0], mtdx.ioaddr + MAR0);
    719     outl(mc_filter[1], mtdx.ioaddr + MAR1);
    720 
    721     mtdx.crvalue = ( mtdx.crvalue & ~RxModeMask ) | rx_mode;
    722     outb( mtdx.crvalue, mtdx.ioaddr + TCRRCR);
    723 }
    724 /**************************************************************************/
    725 static unsigned int m80x_read_tick(void)
    726 /* function: Reads the Timer tick count register which decrements by 2 from  */
    727 /*           65536 to 0 every 1/36.414 of a second. Each 2 decrements of the */
    728 /*           count represents 838 nsec's.                                    */
    729 /* input   : none.                                                           */
    730 /* output  : none.                                                           */
    731 {
    732     unsigned char tmp;
    733     int value;
    734 
    735     outb((char) 0x06, 0x43); // Command 8254 to latch T0's count
    736 
    737     // now read the count.
    738     tmp = (unsigned char) inb(0x40);
    739     value = ((int) tmp) << 8;
    740     tmp = (unsigned char) inb(0x40);
    741     value |= (((int) tmp) & 0xff);
    742     return (value);
    743 }
    744 
    745 static void m80x_delay(unsigned int interval)
    746 /* function: to wait for a specified time.                                   */
    747 /* input   : interval ... the specified time.                                */
    748 /* output  : none.                                                           */
    749 {
    750     unsigned int interval1, interval2, i = 0;
    751 
    752     interval1 = m80x_read_tick(); // get initial value
    753     do
    754     {
    755         interval2 = m80x_read_tick();
    756         if (interval1 < interval2)
    757             interval1 += 65536;
    758         ++i;
    759     } while (((interval1 - interval2) < (u16) interval) && (i < 65535));
    760 }
    761 
    762 
    763 static u32 m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad)
    764 {
    765     u32 miir;
    766     int i;
    767     unsigned int mask, data;
    768 
    769     /* enable MII output */
    770     miir = (u32) inl(miiport);
    771     miir &= 0xfffffff0;
    772 
    773     miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO;
    774 
    775     /* send 32 1's preamble */
    776     for (i = 0; i < 32; i++) {
    777         /* low MDC; MDO is already high (miir) */
    778         miir &= ~MASK_MIIR_MII_MDC;
    779         outl(miir, miiport);
    780 
    781         /* high MDC */
    782         miir |= MASK_MIIR_MII_MDC;
    783         outl(miir, miiport);
    784     }
    785 
    786     /* calculate ST+OP+PHYAD+REGAD+TA */
    787     data = opcode | (phyad << 7) | (regad << 2);
    788 
    789     /* sent out */
    790     mask = 0x8000;
    791     while (mask) {
    792         /* low MDC, prepare MDO */
    793         miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
    794         if (mask & data)
    795             miir |= MASK_MIIR_MII_MDO;
    796 
    797         outl(miir, miiport);
    798         /* high MDC */
    799         miir |= MASK_MIIR_MII_MDC;
    800         outl(miir, miiport);
    801         m80x_delay(30);
    802 
    803         /* next */
    804         mask >>= 1;
    805         if (mask == 0x2 && opcode == OP_READ)
    806             miir &= ~MASK_MIIR_MII_WRITE;
    807     }
    808     return miir;
    809 }
    810 
    811 static int mdio_read(struct nic *nic __unused, int phyad, int regad)
    812 {
    813     long miiport = mtdx.ioaddr + MANAGEMENT;
    814     u32 miir;
    815     unsigned int mask, data;
    816 
    817     miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad);
    818 
    819     /* read data */
    820     mask = 0x8000;
    821     data = 0;
    822     while (mask)
    823     {
    824         /* low MDC */
    825         miir &= ~MASK_MIIR_MII_MDC;
    826         outl(miir, miiport);
    827 
    828         /* read MDI */
    829         miir = inl(miiport);
    830         if (miir & MASK_MIIR_MII_MDI)
    831             data |= mask;
    832 
    833         /* high MDC, and wait */
    834         miir |= MASK_MIIR_MII_MDC;
    835         outl(miir, miiport);
    836         m80x_delay((int) 30);
    837 
    838         /* next */
    839         mask >>= 1;
    840     }
    841 
    842     /* low MDC */
    843     miir &= ~MASK_MIIR_MII_MDC;
    844     outl(miir, miiport);
    845 
    846     return data & 0xffff;
    847 }
    848 
    849 #if 0 /* not used */
    850 static void mdio_write(struct nic *nic __unused, int phyad, int regad,
    851 		       int data)
    852 {
    853     long miiport = mtdx.ioaddr + MANAGEMENT;
    854     u32 miir;
    855     unsigned int mask;
    856 
    857     miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad);
    858 
    859     /* write data */
    860     mask = 0x8000;
    861     while (mask)
    862     {
    863         /* low MDC, prepare MDO */
    864         miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
    865         if (mask & data)
    866             miir |= MASK_MIIR_MII_MDO;
    867         outl(miir, miiport);
    868 
    869         /* high MDC */
    870         miir |= MASK_MIIR_MII_MDC;
    871         outl(miir, miiport);
    872 
    873         /* next */
    874         mask >>= 1;
    875     }
    876 
    877     /* low MDC */
    878     miir &= ~MASK_MIIR_MII_MDC;
    879     outl(miir, miiport);
    880 
    881     return;
    882 }
    883 #endif
    884 
    885 static void getlinkstatus(struct nic *nic)
    886 /* function: Routine will read MII Status Register to get link status.       */
    887 /* input   : dev... pointer to the adapter block.                            */
    888 /* output  : none.                                                           */
    889 {
    890     unsigned int i, DelayTime = 0x1000;
    891 
    892     mtdx.linkok = 0;
    893 
    894     if (mtdx.PHYType == MysonPHY)
    895     {
    896         for (i = 0; i < DelayTime; ++i) {
    897             if (inl(mtdx.ioaddr + BMCRSR) & LinkIsUp2) {
    898                 mtdx.linkok = 1;
    899                 return;
    900             }
    901             // delay
    902             m80x_delay(100);
    903         }
    904     } else
    905     {
    906         for (i = 0; i < DelayTime; ++i) {
    907             if (mdio_read(nic, mtdx.phys[0], MII_BMSR) & BMSR_LSTATUS) {
    908                 mtdx.linkok = 1;
    909                 return;
    910             }
    911             // delay
    912             m80x_delay(100);
    913         }
    914     }
    915 }
    916 
    917 
    918 static void getlinktype(struct nic *dev)
    919 {
    920     if (mtdx.PHYType == MysonPHY)
    921     { /* 3-in-1 case */
    922         if (inl(mtdx.ioaddr + TCRRCR) & FD)
    923             mtdx.duplexmode = 2; /* full duplex */
    924         else
    925             mtdx.duplexmode = 1; /* half duplex */
    926         if (inl(mtdx.ioaddr + TCRRCR) & PS10)
    927             mtdx.line_speed = 1; /* 10M */
    928         else
    929             mtdx.line_speed = 2; /* 100M */
    930     } else
    931     {
    932         if (mtdx.PHYType == SeeqPHY) { /* this PHY is SEEQ 80225 */
    933             unsigned int data;
    934 
    935             data = mdio_read(dev, mtdx.phys[0], MIIRegister18);
    936             if (data & SPD_DET_100)
    937                 mtdx.line_speed = 2; /* 100M */
    938             else
    939                 mtdx.line_speed = 1; /* 10M */
    940             if (data & DPLX_DET_FULL)
    941                 mtdx.duplexmode = 2; /* full duplex mode */
    942             else
    943                 mtdx.duplexmode = 1; /* half duplex mode */
    944         } else if (mtdx.PHYType == AhdocPHY) {
    945             unsigned int data;
    946 
    947             data = mdio_read(dev, mtdx.phys[0], DiagnosticReg);
    948             if (data & Speed_100)
    949                 mtdx.line_speed = 2; /* 100M */
    950             else
    951                 mtdx.line_speed = 1; /* 10M */
    952             if (data & DPLX_FULL)
    953                 mtdx.duplexmode = 2; /* full duplex mode */
    954             else
    955                 mtdx.duplexmode = 1; /* half duplex mode */
    956         }
    957         /* 89/6/13 add, (begin) */
    958         else if (mtdx.PHYType == MarvellPHY) {
    959             unsigned int data;
    960 
    961             data = mdio_read(dev, mtdx.phys[0], SpecificReg);
    962             if (data & Full_Duplex)
    963                 mtdx.duplexmode = 2; /* full duplex mode */
    964             else
    965                 mtdx.duplexmode = 1; /* half duplex mode */
    966             data &= SpeedMask;
    967             if (data == Speed_1000M)
    968                 mtdx.line_speed = 3; /* 1000M */
    969             else if (data == Speed_100M)
    970                 mtdx.line_speed = 2; /* 100M */
    971             else
    972                 mtdx.line_speed = 1; /* 10M */
    973         }
    974         /* 89/6/13 add, (end) */
    975         /* 89/7/27 add, (begin) */
    976         else if (mtdx.PHYType == Myson981) {
    977             unsigned int data;
    978 
    979             data = mdio_read(dev, mtdx.phys[0], StatusRegister);
    980 
    981             if (data & SPEED100)
    982                 mtdx.line_speed = 2;
    983             else
    984                 mtdx.line_speed = 1;
    985 
    986             if (data & FULLMODE)
    987                 mtdx.duplexmode = 2;
    988             else
    989                 mtdx.duplexmode = 1;
    990         }
    991         /* 89/7/27 add, (end) */
    992         /* 89/12/29 add */
    993         else if (mtdx.PHYType == LevelOnePHY) {
    994             unsigned int data;
    995 
    996             data = mdio_read(dev, mtdx.phys[0], SpecificReg);
    997             if (data & LXT1000_Full)
    998                 mtdx.duplexmode = 2; /* full duplex mode */
    999             else
   1000                 mtdx.duplexmode = 1; /* half duplex mode */
   1001             data &= SpeedMask;
   1002             if (data == LXT1000_1000M)
   1003                 mtdx.line_speed = 3; /* 1000M */
   1004             else if (data == LXT1000_100M)
   1005                 mtdx.line_speed = 2; /* 100M */
   1006             else
   1007                 mtdx.line_speed = 1; /* 10M */
   1008         }
   1009         // chage crvalue
   1010         // mtdx.crvalue&=(~PS10)&(~FD);
   1011         mtdx.crvalue &= (~PS10) & (~FD) & (~PS1000);
   1012         if (mtdx.line_speed == 1)
   1013             mtdx.crvalue |= PS10;
   1014         else if (mtdx.line_speed == 3)
   1015             mtdx.crvalue |= PS1000;
   1016         if (mtdx.duplexmode == 2)
   1017             mtdx.crvalue |= FD;
   1018     }
   1019 }
   1020 
   1021 DRIVER ( "MTD80X", nic_driver, pci_driver, mtd80x_driver,
   1022 	 mtd_probe, mtd_disable );
   1023