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