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