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