1 /**************************************************************************
3 * mtd80x.c: Etherboot device driver for the mtd80x Ethernet chip.
4 * Written 2004-2004 by Erdem Güven <zuencap@yahoo.com>
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.
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.
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.
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
24 ***************************************************************************/
26 /* to get some global routines like printf */
27 #include "etherboot.h"
28 /* to get the interface to the body of the program */
30 /* to get the PCI support functions, if this is a PCI NIC */
32 #include <gpxe/ethernet.h>
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))
40 /* Operational parameters that are set at compile time. */
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
51 /* Operational parameters that usually are not changed. */
52 /* Time in jiffies before concluding the transmitter is hung. */
54 #define TX_TIME_OUT (6*HZ)
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.
60 #define PKT_BUF_SZ 1536
62 /* Generic MII registers. */
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 */
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 */
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 */
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 */
122 #define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
124 #define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
125 ADVERTISE_100HALF | ADVERTISE_100FULL)
127 /* for different PHY */
128 enum phy_type_flags
{
138 /* A chip capabilities table*/
139 enum chip_capability_flags
{
152 {0x0800, HAS_MII_XCVR
},
153 {0x0803, HAS_CHIP_XCVR
},
154 {0x0891, HAS_MII_XCVR
}
156 static int chip_cnt
= sizeof( mtd80x_chips
) / sizeof( struct chip_info
);
159 /* Offsets to the Command and Status Registers. */
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
184 ANEROCR
= 0x58, /* auto-negotiation expansion and pci conf. */
185 BPREMRPSR
= 0x5c, /* bypass & receive error mask and phy status */
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 */
212 /* Bits in the NetworkConfig register. */
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 */
222 AcceptMyPhys
= 0x00000000,
223 RxEnable
= 0x00000001,
224 RxFlowCtrl
= 0x00002000,
225 TxEnable
= 0x00040000,
226 TxModeFDX
= 0x00100000,
227 TxThreshold
= 0x00e00000,
234 /* Bits in network_desc.status */
235 enum rx_desc_status_bits
{
236 RXOWN
= 0x80000000, /* own bit */
237 FLNGMASK
= 0x0fff0000, /* frame length */
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 */
252 enum rx_desc_control_bits
{
253 RXIC
= 0x00800000, /* interrupt control */
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 */
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 */
280 TBSMask
= 0x000007ff, /* transmit buffer bit 10-0 */
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
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 */
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) */
306 /* ------------------------------------------------------------------------- */
307 /* Constants for Seeq 80225 PHY */
308 /* ------------------------------------------------------------------------- */
309 #define SeeqPHYID0 0x0016
311 #define MIIRegister18 18
312 #define SPD_DET_100 0x80
313 #define DPLX_DET_FULL 0x40
315 /* ------------------------------------------------------------------------- */
316 /* Constants for Ahdoc 101 PHY */
317 /* ------------------------------------------------------------------------- */
318 #define AhdocPHYID0 0x0022
320 #define DiagnosticReg 18
321 #define DPLX_FULL 0x0800
322 #define Speed_100 0x0400
325 /* -------------------------------------------------------------------------- */
327 /* -------------------------------------------------------------------------- */
328 #define MarvellPHYID0 0x0141
329 #define LevelOnePHYID0 0x0013
331 #define MII1000BaseTControlReg 9
332 #define MII1000BaseTStatusReg 10
333 #define SpecificReg 17
335 /* for 1000BaseT Control Register */
336 #define PHYAbletoPerform1000FullDuplex 0x0200
337 #define PHYAbletoPerform1000HalfDuplex 0x0100
338 #define PHY1000AbilityMask 0x300
340 // for phy specific status register, marvell phy.
341 #define SpeedMask 0x0c000
342 #define Speed_1000M 0x08000
343 #define Speed_100M 0x4000
345 #define Full_Duplex 0x2000
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)
354 /* for 3-in-1 case */
355 #define PS10 0x00080000
356 #define FD 0x00100000
357 #define PS1000 0x00010000
361 #define LinkIsUp 0x0004
362 #define LinkIsUp2 0x00040000
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 */
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
374 /* The Tulip Rx and Tx buffer descriptors. */
381 struct mtd_desc
*next_desc_logical
;
389 struct mtd_desc rx_ring
[RX_RING_SIZE
];
390 struct mtd_desc tx_ring
[TX_RING_SIZE
];
392 /* Frequently used values: keep some adjacent for cache effect. */
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
;
401 struct mtd_desc
*cur_tx
;
402 struct mtd_desc
*cur_tx_copy
;
405 unsigned int rx_buf_sz
; /* Based on MTU+slack. */
407 /* These values are keep track of the transceiver/media in use. */
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
;
415 /* MII transceiver section. */
416 int mii_cnt
; /* MII device addresses. */
417 unsigned char phys
[1]; /* MII device addresses. */
420 const char *nic_name
;
425 static struct mtd_private mtdx
;
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
*);
432 /**************************************************************************
433 * init_ring - setup the tx and rx descriptors
434 *************************************************************************/
435 static void init_ring(struct nic
*nic __unused
)
439 mtdx
.cur_rx
= &mtdx
.rx_ring
[0];
441 mtdx
.rx_buf_sz
= PKT_BUF_SZ
;
442 /*mtdx.rx_head_desc = &mtdx.rx_ring[0];*/
444 /* Initialize all Rx descriptors. */
445 /* Fill in the Rx buffers. Handle allocation failure gracefully. */
446 for (i
= 0; i
< RX_RING_SIZE
; i
++)
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
];
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];
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]);
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]);
474 /**************************************************************************
475 RESET - Reset Adapter
476 ***************************************************************************/
477 static void mtd_reset( struct nic
*nic
)
479 /* Reset the chip to erase previous misconfiguration. */
480 outl(0x00000001, mtdx
.ioaddr
+ BCR
);
484 outl(virt_to_bus(mtdx
.rx_ring
), mtdx
.ioaddr
+ RXLBA
);
485 outl(virt_to_bus(mtdx
.tx_ring
), mtdx
.ioaddr
+ TXLBA
);
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 */
492 if ( mtdx
.dev_id
== 0x891 ) {
493 mtdx
.bcrvalue
|= 0x200; /* set PROG bit */
494 mtdx
.crvalue
|= 0x02000000; /* set enhanced bit */
497 outl( mtdx
.bcrvalue
, mtdx
.ioaddr
+ BCR
);
499 /* Restart Rx engine if stopped. */
500 outl(0, mtdx
.ioaddr
+ RXPDR
);
505 static const char* texts
[]={"half","full","10","100","1000"};
507 DBG ( "Link is OK : %s %s\n", texts
[mtdx
.duplexmode
-1], texts
[mtdx
.line_speed
+1] );
510 DBG ( "No link!!!\n" );
513 mtdx
.crvalue
|= /*TxEnable |*/ RxEnable
| TxThreshold
;
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
);
521 /**************************************************************************
522 POLL - Wait for a frame
523 ***************************************************************************/
524 static int mtd_poll(struct nic
*nic
, __unused
int retrieve
)
526 s32 rx_status
= mtdx
.cur_rx
->status
;
529 if( ( rx_status
& RXOWN
) != 0 )
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
, (unsigned int) rx_status
,
538 (rx_status
& (LONG
| RUNT
)) ? "length_error ":"",
539 (rx_status
& RXER
) ? "frame_error ":"",
540 (rx_status
& CRC
) ? "crc_error ":"" );
542 } else if( !((rx_status
& RXFSD
) && (rx_status
& RXLSD
)) )
544 /* this pkt is too long, over one rx buffer */
545 printf("Pkt is too long, over one rx buffer.\n");
548 { /* this received pkt is ok */
549 /* Omit the four octet CRC from the length. */
550 short pkt_len
= ((rx_status
& FLNGMASK
) >> FLNGShift
) - 4;
552 DBG ( " netdev_rx() normal Rx pkt length %d"
553 " status %x.\n", pkt_len
, (unsigned int) rx_status
);
555 nic
->packetlen
= pkt_len
;
556 memcpy(nic
->packet
, mtdx
.cur_rx
->skbuff
, pkt_len
);
561 while( ( mtdx
.cur_rx
->status
& RXOWN
) == 0 )
563 mtdx
.cur_rx
->status
= RXOWN
;
564 mtdx
.cur_rx
= mtdx
.cur_rx
->next_desc_logical
;
567 /* Restart Rx engine if stopped. */
568 outl(0, mtdx
.ioaddr
+ RXPDR
);
573 /**************************************************************************
574 TRANSMIT - Transmit a frame
575 ***************************************************************************/
576 static void mtd_transmit(
578 const char *dest
, /* Destination */
579 unsigned int type
, /* Type */
580 unsigned int size
, /* size */
581 const char *data
) /* Packet */
585 unsigned int nstype
= htons ( type
);
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
);
594 while( size
< ETH_ZLEN
)
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
;
604 /* Point to transmit descriptor */
605 outl(virt_to_bus(mtdx
.tx_ring
), mtdx
.ioaddr
+ TXLBA
);
607 outl( mtdx
.crvalue
| TxEnable
, mtdx
.ioaddr
+ TCRRCR
);
608 /* Wake the potentially-idle transmit channel. */
609 outl(0, mtdx
.ioaddr
+ TXPDR
);
611 to
= currticks() + TX_TIME_OUT
;
612 while(( mtdx
.tx_ring
[0].status
& TXOWN
) && (currticks() < to
));
615 outl( mtdx
.crvalue
& (~TxEnable
), mtdx
.ioaddr
+ TCRRCR
);
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 (unsigned int) 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" : "" );
630 /*hex_dump( txb, size );*/
633 DBG ( "TRANSMIT\n" );
636 /**************************************************************************
637 DISABLE - Turn off ethernet interface
638 ***************************************************************************/
639 static void mtd_disable ( struct nic
*nic
) {
642 outl( mtdx
.crvalue
& (~TxEnable
) & (~RxEnable
), mtdx
.ioaddr
+ TCRRCR
);
644 /* Reset the chip to erase previous misconfiguration. */
650 static struct nic_operations mtd_operations
= {
651 .connect
= dummy_connect
,
653 .transmit
= mtd_transmit
,
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"),
664 PCI_DRIVER ( mtd80x_driver
, mtd80x_nics
, PCI_NO_CLASS
);
666 /**************************************************************************
667 PROBE - Look for an adapter, this routine's visible to the outside
668 ***************************************************************************/
670 static int mtd_probe ( struct nic
*nic
, struct pci_device
*pci
) {
674 if (pci
->ioaddr
== 0)
677 adjust_pci_device(pci
);
679 nic
->ioaddr
= pci
->ioaddr
;
682 mtdx
.nic_name
= pci
->driver_name
;
683 mtdx
.dev_id
= pci
->device
;
684 mtdx
.ioaddr
= nic
->ioaddr
;
686 /* read ethernet id */
687 for (i
= 0; i
< 6; ++i
)
689 nic
->node_addr
[i
] = inb(mtdx
.ioaddr
+ PAR0
+ i
);
692 if (memcmp(nic
->node_addr
, "\0\0\0\0\0\0", 6) == 0)
697 DBG ( "%s: ioaddr %4.4x MAC %s\n", mtdx
.nic_name
, mtdx
.ioaddr
, eth_ntoa ( nic
->node_addr
) );
699 /* Reset the chip to erase previous misconfiguration. */
700 outl(0x00000001, mtdx
.ioaddr
+ BCR
);
702 /* find the connected MII xcvrs */
704 if( mtdx
.dev_id
!= 0x803 )
706 int phy
, phy_idx
= 0;
708 for (phy
= 1; phy
< 32 && phy_idx
< 1; phy
++) {
709 int mii_status
= mdio_read(nic
, phy
, 1);
711 if (mii_status
!= 0xffff && mii_status
!= 0x0000) {
712 mtdx
.phys
[phy_idx
] = phy
;
714 DBG ( "%s: MII PHY found at address %d, status "
715 "0x%4.4x.\n", mtdx
.nic_name
, phy
, mii_status
);
720 data
= mdio_read(nic
, mtdx
.phys
[phy_idx
], 2);
721 if (data
== SeeqPHYID0
)
722 mtdx
.PHYType
= SeeqPHY
;
723 else if (data
== AhdocPHYID0
)
724 mtdx
.PHYType
= AhdocPHY
;
725 else if (data
== MarvellPHYID0
)
726 mtdx
.PHYType
= MarvellPHY
;
727 else if (data
== MysonPHYID0
)
728 mtdx
.PHYType
= Myson981
;
729 else if (data
== LevelOnePHYID0
)
730 mtdx
.PHYType
= LevelOnePHY
;
732 mtdx
.PHYType
= OtherPHY
;
738 mtdx
.mii_cnt
= phy_idx
;
740 printf("%s: MII PHY not found -- this device may "
741 "not operate correctly.\n", mtdx
.nic_name
);
746 if (inl(mtdx
.ioaddr
+ PHYIDENTIFIER
) == MysonPHYID
) {
747 mtdx
.PHYType
= MysonPHY
;
748 DBG ( "MysonPHY\n" );
750 mtdx
.PHYType
= OtherPHY
;
751 DBG ( "OtherPHY\n" );
758 printf("No link!!!\n");
764 /* point to NIC specific routines */
765 nic
->nic_op
= &mtd_operations
;
770 /**************************************************************************/
771 static void set_rx_mode(struct nic
*nic __unused
)
773 u32 mc_filter
[2]; /* Multicast hash filter */
776 /* Too many to match, or accept all multicasts. */
777 mc_filter
[1] = mc_filter
[0] = ~0;
778 rx_mode
= AcceptBroadcast
| AcceptMulticast
| AcceptMyPhys
;
780 outl(mc_filter
[0], mtdx
.ioaddr
+ MAR0
);
781 outl(mc_filter
[1], mtdx
.ioaddr
+ MAR1
);
783 mtdx
.crvalue
= ( mtdx
.crvalue
& ~RxModeMask
) | rx_mode
;
784 outb( mtdx
.crvalue
, mtdx
.ioaddr
+ TCRRCR
);
786 /**************************************************************************/
787 static unsigned int m80x_read_tick(void)
788 /* function: Reads the Timer tick count register which decrements by 2 from */
789 /* 65536 to 0 every 1/36.414 of a second. Each 2 decrements of the */
790 /* count represents 838 nsec's. */
797 outb((char) 0x06, 0x43); // Command 8254 to latch T0's count
799 // now read the count.
800 tmp
= (unsigned char) inb(0x40);
801 value
= ((int) tmp
) << 8;
802 tmp
= (unsigned char) inb(0x40);
803 value
|= (((int) tmp
) & 0xff);
807 static void m80x_delay(unsigned int interval
)
808 /* function: to wait for a specified time. */
809 /* input : interval ... the specified time. */
812 unsigned int interval1
, interval2
, i
= 0;
814 interval1
= m80x_read_tick(); // get initial value
817 interval2
= m80x_read_tick();
818 if (interval1
< interval2
)
821 } while (((interval1
- interval2
) < (u16
) interval
) && (i
< 65535));
825 static u32
m80x_send_cmd_to_phy(long miiport
, int opcode
, int phyad
, int regad
)
829 unsigned int mask
, data
;
831 /* enable MII output */
832 miir
= (u32
) inl(miiport
);
835 miir
|= MASK_MIIR_MII_WRITE
+ MASK_MIIR_MII_MDO
;
837 /* send 32 1's preamble */
838 for (i
= 0; i
< 32; i
++) {
839 /* low MDC; MDO is already high (miir) */
840 miir
&= ~MASK_MIIR_MII_MDC
;
844 miir
|= MASK_MIIR_MII_MDC
;
848 /* calculate ST+OP+PHYAD+REGAD+TA */
849 data
= opcode
| (phyad
<< 7) | (regad
<< 2);
854 /* low MDC, prepare MDO */
855 miir
&= ~(MASK_MIIR_MII_MDC
+ MASK_MIIR_MII_MDO
);
857 miir
|= MASK_MIIR_MII_MDO
;
861 miir
|= MASK_MIIR_MII_MDC
;
867 if (mask
== 0x2 && opcode
== OP_READ
)
868 miir
&= ~MASK_MIIR_MII_WRITE
;
873 static int mdio_read(struct nic
*nic __unused
, int phyad
, int regad
)
875 long miiport
= mtdx
.ioaddr
+ MANAGEMENT
;
877 unsigned int mask
, data
;
879 miir
= m80x_send_cmd_to_phy(miiport
, OP_READ
, phyad
, regad
);
887 miir
&= ~MASK_MIIR_MII_MDC
;
892 if (miir
& MASK_MIIR_MII_MDI
)
895 /* high MDC, and wait */
896 miir
|= MASK_MIIR_MII_MDC
;
898 m80x_delay((int) 30);
905 miir
&= ~MASK_MIIR_MII_MDC
;
908 return data
& 0xffff;
912 static void mdio_write(struct nic
*nic __unused
, int phyad
, int regad
,
915 long miiport
= mtdx
.ioaddr
+ MANAGEMENT
;
919 miir
= m80x_send_cmd_to_phy(miiport
, OP_WRITE
, phyad
, regad
);
925 /* low MDC, prepare MDO */
926 miir
&= ~(MASK_MIIR_MII_MDC
+ MASK_MIIR_MII_MDO
);
928 miir
|= MASK_MIIR_MII_MDO
;
932 miir
|= MASK_MIIR_MII_MDC
;
940 miir
&= ~MASK_MIIR_MII_MDC
;
947 static void getlinkstatus(struct nic
*nic
)
948 /* function: Routine will read MII Status Register to get link status. */
949 /* input : dev... pointer to the adapter block. */
952 unsigned int i
, DelayTime
= 0x1000;
956 if (mtdx
.PHYType
== MysonPHY
)
958 for (i
= 0; i
< DelayTime
; ++i
) {
959 if (inl(mtdx
.ioaddr
+ BMCRSR
) & LinkIsUp2
) {
968 for (i
= 0; i
< DelayTime
; ++i
) {
969 if (mdio_read(nic
, mtdx
.phys
[0], MII_BMSR
) & BMSR_LSTATUS
) {
980 static void getlinktype(struct nic
*dev
)
982 if (mtdx
.PHYType
== MysonPHY
)
984 if (inl(mtdx
.ioaddr
+ TCRRCR
) & FD
)
985 mtdx
.duplexmode
= 2; /* full duplex */
987 mtdx
.duplexmode
= 1; /* half duplex */
988 if (inl(mtdx
.ioaddr
+ TCRRCR
) & PS10
)
989 mtdx
.line_speed
= 1; /* 10M */
991 mtdx
.line_speed
= 2; /* 100M */
994 if (mtdx
.PHYType
== SeeqPHY
) { /* this PHY is SEEQ 80225 */
997 data
= mdio_read(dev
, mtdx
.phys
[0], MIIRegister18
);
998 if (data
& SPD_DET_100
)
999 mtdx
.line_speed
= 2; /* 100M */
1001 mtdx
.line_speed
= 1; /* 10M */
1002 if (data
& DPLX_DET_FULL
)
1003 mtdx
.duplexmode
= 2; /* full duplex mode */
1005 mtdx
.duplexmode
= 1; /* half duplex mode */
1006 } else if (mtdx
.PHYType
== AhdocPHY
) {
1009 data
= mdio_read(dev
, mtdx
.phys
[0], DiagnosticReg
);
1010 if (data
& Speed_100
)
1011 mtdx
.line_speed
= 2; /* 100M */
1013 mtdx
.line_speed
= 1; /* 10M */
1014 if (data
& DPLX_FULL
)
1015 mtdx
.duplexmode
= 2; /* full duplex mode */
1017 mtdx
.duplexmode
= 1; /* half duplex mode */
1019 /* 89/6/13 add, (begin) */
1020 else if (mtdx
.PHYType
== MarvellPHY
) {
1023 data
= mdio_read(dev
, mtdx
.phys
[0], SpecificReg
);
1024 if (data
& Full_Duplex
)
1025 mtdx
.duplexmode
= 2; /* full duplex mode */
1027 mtdx
.duplexmode
= 1; /* half duplex mode */
1029 if (data
== Speed_1000M
)
1030 mtdx
.line_speed
= 3; /* 1000M */
1031 else if (data
== Speed_100M
)
1032 mtdx
.line_speed
= 2; /* 100M */
1034 mtdx
.line_speed
= 1; /* 10M */
1036 /* 89/6/13 add, (end) */
1037 /* 89/7/27 add, (begin) */
1038 else if (mtdx
.PHYType
== Myson981
) {
1041 data
= mdio_read(dev
, mtdx
.phys
[0], StatusRegister
);
1043 if (data
& SPEED100
)
1044 mtdx
.line_speed
= 2;
1046 mtdx
.line_speed
= 1;
1048 if (data
& FULLMODE
)
1049 mtdx
.duplexmode
= 2;
1051 mtdx
.duplexmode
= 1;
1053 /* 89/7/27 add, (end) */
1055 else if (mtdx
.PHYType
== LevelOnePHY
) {
1058 data
= mdio_read(dev
, mtdx
.phys
[0], SpecificReg
);
1059 if (data
& LXT1000_Full
)
1060 mtdx
.duplexmode
= 2; /* full duplex mode */
1062 mtdx
.duplexmode
= 1; /* half duplex mode */
1064 if (data
== LXT1000_1000M
)
1065 mtdx
.line_speed
= 3; /* 1000M */
1066 else if (data
== LXT1000_100M
)
1067 mtdx
.line_speed
= 2; /* 100M */
1069 mtdx
.line_speed
= 1; /* 10M */
1072 // mtdx.crvalue&=(~PS10)&(~FD);
1073 mtdx
.crvalue
&= (~PS10
) & (~FD
) & (~PS1000
);
1074 if (mtdx
.line_speed
== 1)
1075 mtdx
.crvalue
|= PS10
;
1076 else if (mtdx
.line_speed
== 3)
1077 mtdx
.crvalue
|= PS1000
;
1078 if (mtdx
.duplexmode
== 2)
1083 DRIVER ( "MTD80X", nic_driver
, pci_driver
, mtd80x_driver
,
1084 mtd_probe
, mtd_disable
);