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