Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / common / boot / grub / netboot / davicom.c
blob5a9865691fd561f2708af4de022896412f9fa710
1 /*
2 DAVICOM DM9009/DM9102/DM9102A Etherboot Driver V1.00
4 This driver was ported from Marty Conner's Tulip Etherboot driver.
5 Thanks Marty Connor (mdc@thinguin.org)
6 You can get Tulip driver source file from this URL:
8 "http://etherboot.sourceforge..net/#Distribution"
10 This davicom etherboot driver supports DM9009/DM9102/DM9102A/
11 DM9102A+DM9801/DM9102A+DM9802 NICs.
13 This software may be used and distributed according to the terms
14 of the GNU Public License, incorporated herein by reference.
18 /*********************************************************************/
19 /* Revision History */
20 /*********************************************************************/
23 19 OCT 2000 Sten 1.00
24 Different half and full duplex mode
25 Do the different programming for DM9801/DM9802
27 12 OCT 2000 Sten 0.90
28 This driver was ported from tulip driver and it
29 has the following difference.
30 Changed symbol tulip/TULIP to davicom/DAVICOM
31 Deleted some code that did not use in this driver.
32 Used chain-strcture to replace ring structure
33 for both TX/RX descriptor.
34 Allocated two tx descriptor.
35 According current media mode to set operating
36 register(CR6)
40 /*********************************************************************/
41 /* Declarations */
42 /*********************************************************************/
44 #include "etherboot.h"
45 #include "nic.h"
46 #include "pci.h"
47 #include "cards.h"
49 #undef DAVICOM_DEBUG
50 #undef DAVICOM_DEBUG_WHERE
52 #define TX_TIME_OUT 2*TICKS_PER_SEC
54 typedef unsigned char u8;
55 typedef signed char s8;
56 typedef unsigned short u16;
57 typedef signed short s16;
58 typedef unsigned int u32;
59 typedef signed int s32;
61 /* Register offsets for davicom device */
62 enum davicom_offsets {
63 CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
64 CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
65 CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
68 /* EEPROM Address width definitions */
69 #define EEPROM_ADDRLEN 6
70 #define EEPROM_SIZE 32 /* 1 << EEPROM_ADDRLEN */
71 /* Used to be 128, but we only need to read enough to get the MAC
72 address at bytes 20..25 */
74 /* Data Read from the EEPROM */
75 static unsigned char ee_data[EEPROM_SIZE];
77 /* The EEPROM commands include the alway-set leading bit. */
78 #define EE_WRITE_CMD (5 << addr_len)
79 #define EE_READ_CMD (6 << addr_len)
80 #define EE_ERASE_CMD (7 << addr_len)
82 /* EEPROM_Ctrl bits. */
83 #define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
84 #define EE_CS 0x01 /* EEPROM chip select. */
85 #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
86 #define EE_WRITE_0 0x01
87 #define EE_WRITE_1 0x05
88 #define EE_DATA_READ 0x08 /* EEPROM chip data out. */
89 #define EE_ENB (0x4800 | EE_CS)
91 /* Sten 10/11 for phyxcer */
92 #define PHY_DATA_0 0x0
93 #define PHY_DATA_1 0x20000
94 #define MDCLKH 0x10000
96 /* Delay between EEPROM clock transitions. Even at 33Mhz current PCI
97 implementations don't overrun the EEPROM clock. We add a bus
98 turn-around to insure that this remains true. */
99 #define eeprom_delay() inl(ee_addr)
101 /* helpful macro if on a big_endian machine for changing byte order.
102 not strictly needed on Intel */
103 #define le16_to_cpu(val) (val)
105 /* transmit and receive descriptor format */
106 struct txdesc {
107 volatile unsigned long status; /* owner, status */
108 unsigned long buf1sz:11, /* size of buffer 1 */
109 buf2sz:11, /* size of buffer 2 */
110 control:10; /* control bits */
111 const unsigned char *buf1addr; /* buffer 1 address */
112 const unsigned char *buf2addr; /* buffer 2 address */
115 struct rxdesc {
116 volatile unsigned long status; /* owner, status */
117 unsigned long buf1sz:11, /* size of buffer 1 */
118 buf2sz:11, /* size of buffer 2 */
119 control:10; /* control bits */
120 unsigned char *buf1addr; /* buffer 1 address */
121 unsigned char *buf2addr; /* buffer 2 address */
124 /* Size of transmit and receive buffers */
125 #define BUFLEN 1536
127 /*********************************************************************/
128 /* Global Storage */
129 /*********************************************************************/
131 /* PCI Bus parameters */
132 static unsigned short vendor, dev_id;
133 static unsigned long ioaddr;
135 /* Note: transmit and receive buffers must be longword aligned and
136 longword divisable */
138 /* transmit descriptor and buffer */
139 #define NTXD 2
140 static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
141 #ifdef USE_LOWMEM_BUFFER
142 #define txb ((char *)0x10000 - BUFLEN)
143 #else
144 static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
145 #endif
147 /* receive descriptor(s) and buffer(s) */
148 #define NRXD 4
149 static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
150 #ifdef USE_LOWMEM_BUFFER
151 #define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
152 #else
153 static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
154 #endif
155 static int rxd_tail;
156 static int TxPtr;
159 /*********************************************************************/
160 /* Function Prototypes */
161 /*********************************************************************/
162 static void whereami(const char *str);
163 static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
164 struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
165 struct pci_device *pci);
166 static void davicom_init_chain(struct nic *nic); /* Sten 10/9 */
167 static void davicom_reset(struct nic *nic);
168 static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
169 unsigned int s, const char *p);
170 static int davicom_poll(struct nic *nic);
171 static void davicom_disable(struct nic *nic);
172 static void whereami (const char *str);
173 #ifdef DAVICOM_DEBUG
174 static void davicom_more(void);
175 #endif /* DAVICOM_DEBUG */
176 static void davicom_wait(unsigned int nticks);
177 static int phy_read(int);
178 static void phy_write(int, u16);
179 static void phy_write_1bit(u32, u32);
180 static int phy_read_1bit(u32);
181 static void davicom_media_chk(struct nic *);
184 /*********************************************************************/
185 /* Utility Routines */
186 /*********************************************************************/
188 static inline void whereami (const char *str)
190 #ifdef DAVICOM_DEBUG_WHERE
191 printf("%s\n", str);
192 /* sleep(2); */
193 #endif
196 #ifdef DAVICOM_DEBUG
197 static void davicom_more()
199 printf("\n\n-- more --");
200 while (!iskey())
201 /* wait */;
202 getchar();
203 printf("\n\n");
205 #endif /* DAVICOM_DEBUG */
207 static void davicom_wait(unsigned int nticks)
209 unsigned int to = currticks() + nticks;
210 while (currticks() < to)
211 /* wait */ ;
215 /*********************************************************************/
216 /* For DAVICOM phyxcer register by MII interface */
217 /*********************************************************************/
219 Read a word data from phy register
221 static int phy_read(int location)
223 int i, phy_addr=1;
224 u16 phy_data;
225 u32 io_dcr9;
227 whereami("phy_read\n");
229 io_dcr9 = ioaddr + CSR9;
231 /* Send 33 synchronization clock to Phy controller */
232 for (i=0; i<34; i++)
233 phy_write_1bit(io_dcr9, PHY_DATA_1);
235 /* Send start command(01) to Phy */
236 phy_write_1bit(io_dcr9, PHY_DATA_0);
237 phy_write_1bit(io_dcr9, PHY_DATA_1);
239 /* Send read command(10) to Phy */
240 phy_write_1bit(io_dcr9, PHY_DATA_1);
241 phy_write_1bit(io_dcr9, PHY_DATA_0);
243 /* Send Phy addres */
244 for (i=0x10; i>0; i=i>>1)
245 phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
247 /* Send register addres */
248 for (i=0x10; i>0; i=i>>1)
249 phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
251 /* Skip transition state */
252 phy_read_1bit(io_dcr9);
254 /* read 16bit data */
255 for (phy_data=0, i=0; i<16; i++) {
256 phy_data<<=1;
257 phy_data|=phy_read_1bit(io_dcr9);
260 return phy_data;
264 Write a word to Phy register
266 static void phy_write(int location, u16 phy_data)
268 u16 i, phy_addr=1;
269 u32 io_dcr9;
271 whereami("phy_write\n");
273 io_dcr9 = ioaddr + CSR9;
275 /* Send 33 synchronization clock to Phy controller */
276 for (i=0; i<34; i++)
277 phy_write_1bit(io_dcr9, PHY_DATA_1);
279 /* Send start command(01) to Phy */
280 phy_write_1bit(io_dcr9, PHY_DATA_0);
281 phy_write_1bit(io_dcr9, PHY_DATA_1);
283 /* Send write command(01) to Phy */
284 phy_write_1bit(io_dcr9, PHY_DATA_0);
285 phy_write_1bit(io_dcr9, PHY_DATA_1);
287 /* Send Phy addres */
288 for (i=0x10; i>0; i=i>>1)
289 phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
291 /* Send register addres */
292 for (i=0x10; i>0; i=i>>1)
293 phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
295 /* written trasnition */
296 phy_write_1bit(io_dcr9, PHY_DATA_1);
297 phy_write_1bit(io_dcr9, PHY_DATA_0);
299 /* Write a word data to PHY controller */
300 for (i=0x8000; i>0; i>>=1)
301 phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
305 Write one bit data to Phy Controller
307 static void phy_write_1bit(u32 ee_addr, u32 phy_data)
309 whereami("phy_write_1bit\n");
310 outl(phy_data, ee_addr); /* MII Clock Low */
311 eeprom_delay();
312 outl(phy_data|MDCLKH, ee_addr); /* MII Clock High */
313 eeprom_delay();
314 outl(phy_data, ee_addr); /* MII Clock Low */
315 eeprom_delay();
319 Read one bit phy data from PHY controller
321 static int phy_read_1bit(u32 ee_addr)
323 int phy_data;
325 whereami("phy_read_1bit\n");
327 outl(0x50000, ee_addr);
328 eeprom_delay();
330 phy_data=(inl(ee_addr)>>19) & 0x1;
332 outl(0x40000, ee_addr);
333 eeprom_delay();
335 return phy_data;
339 DM9801/DM9802 present check and program
341 static void HPNA_process(void)
344 if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
345 if ( phy_read(31) == 0x4404 ) {
346 /* DM9801 present */
347 if (phy_read(3) == 0xb901)
348 phy_write(16, 0x5); /* DM9801 E4 */
349 else
350 phy_write(16, 0x1005); /* DM9801 E3 and others */
351 phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
352 } else {
353 /* DM9802 present */
354 phy_write(16, 0x5);
355 phy_write(25, (phy_read(25) & 0xff00) + 2);
361 Sense media mode and set CR6
363 static void davicom_media_chk(struct nic * nic)
365 unsigned long to, csr6;
367 csr6 = 0x00200000; /* SF */
368 outl(csr6, ioaddr + CSR6);
370 if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
371 /* Set to 10BaseT mode for DM9009 */
372 phy_write(0, 0);
373 } else {
374 /* For DM9102/DM9102A */
375 to = currticks() + 2 * TICKS_PER_SEC;
376 while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
377 /* wait */ ;
379 if ( (phy_read(1) & 0x24) == 0x24 ) {
380 if (phy_read(17) & 0xa000)
381 csr6 |= 0x00000200; /* Full Duplex mode */
382 } else
383 csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
386 /* set the chip's operating mode */
387 outl(csr6, ioaddr + CSR6);
389 /* DM9801/DM9802 present check & program */
390 if (csr6 & 0x40000)
391 HPNA_process();
395 /*********************************************************************/
396 /* EEPROM Reading Code */
397 /*********************************************************************/
398 /* EEPROM routines adapted from the Linux Tulip Code */
399 /* Reading a serial EEPROM is a "bit" grungy, but we work our way
400 through:->.
402 static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
404 int i;
405 unsigned short retval = 0;
406 long ee_addr = ioaddr + CSR9;
407 int read_cmd = location | EE_READ_CMD;
409 whereami("read_eeprom\n");
411 outl(EE_ENB & ~EE_CS, ee_addr);
412 outl(EE_ENB, ee_addr);
414 /* Shift the read command bits out. */
415 for (i = 4 + addr_len; i >= 0; i--) {
416 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
417 outl(EE_ENB | dataval, ee_addr);
418 eeprom_delay();
419 outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
420 eeprom_delay();
422 outl(EE_ENB, ee_addr);
424 for (i = 16; i > 0; i--) {
425 outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
426 eeprom_delay();
427 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
428 outl(EE_ENB, ee_addr);
429 eeprom_delay();
432 /* Terminate the EEPROM access. */
433 outl(EE_ENB & ~EE_CS, ee_addr);
434 return retval;
437 /*********************************************************************/
438 /* davicom_init_chain - setup the tx and rx descriptors */
439 /* Sten 10/9 */
440 /*********************************************************************/
441 static void davicom_init_chain(struct nic *nic)
443 int i;
445 /* setup the transmit descriptor */
446 /* Sten: Set 2 TX descriptor but use one TX buffer because
447 it transmit a packet and wait complete every time. */
448 for (i=0; i<NTXD; i++) {
449 txd[i].buf1addr = &txb[0]; /* Used same TX buffer */
450 txd[i].buf2addr = (unsigned char *)&txd[i+1]; /* Point to Next TX desc */
451 txd[i].buf1sz = 0;
452 txd[i].buf2sz = 0;
453 txd[i].control = 0x184; /* Begin/End/Chain */
454 txd[i].status = 0x00000000; /* give ownership to Host */
457 /* construct perfect filter frame with mac address as first match
458 and broadcast address for all others */
459 for (i=0; i<192; i++) txb[i] = 0xFF;
460 txb[0] = nic->node_addr[0];
461 txb[1] = nic->node_addr[1];
462 txb[4] = nic->node_addr[2];
463 txb[5] = nic->node_addr[3];
464 txb[8] = nic->node_addr[4];
465 txb[9] = nic->node_addr[5];
467 /* setup receive descriptor */
468 for (i=0; i<NRXD; i++) {
469 rxd[i].buf1addr = &rxb[i * BUFLEN];
470 rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
471 rxd[i].buf1sz = BUFLEN;
472 rxd[i].buf2sz = 0; /* not used */
473 rxd[i].control = 0x4; /* Chain Structure */
474 rxd[i].status = 0x80000000; /* give ownership to device */
477 /* Chain the last descriptor to first */
478 txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
479 rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
480 TxPtr = 0;
481 rxd_tail = 0;
485 /*********************************************************************/
486 /* davicom_reset - Reset adapter */
487 /*********************************************************************/
488 static void davicom_reset(struct nic *nic)
490 unsigned long to;
491 u32 addr_low, addr_high;
493 whereami("davicom_reset\n");
495 /* Stop Tx and RX */
496 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
498 /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
499 outl(0x00000001, ioaddr + CSR0);
501 davicom_wait(TICKS_PER_SEC);
503 /* TX/RX descriptor burst */
504 outl(0x0C00000, ioaddr + CSR0); /* Sten 10/9 */
506 /* set up transmit and receive descriptors */
507 davicom_init_chain(nic); /* Sten 10/9 */
509 /* Point to receive descriptor */
510 outl((unsigned long)&rxd[0], ioaddr + CSR3);
511 outl((unsigned long)&txd[0], ioaddr + CSR4); /* Sten 10/9 */
513 /* According phyxcer media mode to set CR6,
514 DM9102/A phyxcer can auto-detect media mode */
515 davicom_media_chk(nic);
517 /* Prepare Setup Frame Sten 10/9 */
518 txd[TxPtr].buf1sz = 192;
519 txd[TxPtr].control = 0x024; /* SF/CE */
520 txd[TxPtr].status = 0x80000000; /* Give ownership to device */
522 /* Start Tx */
523 outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
524 /* immediate transmit demand */
525 outl(0, ioaddr + CSR1);
527 to = currticks() + TX_TIME_OUT;
528 while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
529 /* wait */ ;
531 if (currticks() >= to) {
532 printf ("TX Setup Timeout!\n");
534 /* Point to next TX descriptor */
535 TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
537 #ifdef DAVICOM_DEBUG
538 printf("txd.status = %X\n", txd.status);
539 printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
540 davicom_more();
541 #endif
543 /* enable RX */
544 outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
545 /* immediate poll demand */
546 outl(0, ioaddr + CSR2);
550 /*********************************************************************/
551 /* eth_transmit - Transmit a frame */
552 /*********************************************************************/
553 static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
554 unsigned int s, const char *p)
556 unsigned long to;
558 whereami("davicom_transmit\n");
560 /* Stop Tx */
561 /* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
563 /* setup ethernet header */
564 memcpy(&txb[0], d, ETH_ALEN); /* DA 6byte */
565 memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
566 txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
567 txb[ETH_ALEN*2+1] = t & 0xFF;
568 memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
570 /* setup the transmit descriptor */
571 txd[TxPtr].buf1sz = ETH_HLEN+s;
572 txd[TxPtr].control = 0x00000184; /* LS+FS+CE */
573 txd[TxPtr].status = 0x80000000; /* give ownership to device */
575 /* immediate transmit demand */
576 outl(0, ioaddr + CSR1);
578 to = currticks() + TX_TIME_OUT;
579 while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
580 /* wait */ ;
582 if (currticks() >= to) {
583 printf ("TX Timeout!\n");
586 /* Point to next TX descriptor */
587 TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr; /* Sten 10/9 */
591 /*********************************************************************/
592 /* eth_poll - Wait for a frame */
593 /*********************************************************************/
594 static int davicom_poll(struct nic *nic)
596 whereami("davicom_poll\n");
598 if (rxd[rxd_tail].status & 0x80000000)
599 return 0;
601 whereami("davicom_poll got one\n");
603 nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
605 if( rxd[rxd_tail].status & 0x00008000){
606 rxd[rxd_tail].status = 0x80000000;
607 rxd_tail++;
608 if (rxd_tail == NRXD) rxd_tail = 0;
609 return 0;
612 /* copy packet to working buffer */
613 /* XXX - this copy could be avoided with a little more work
614 but for now we are content with it because the optimised
615 memcpy is quite fast */
617 memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
619 /* return the descriptor and buffer to receive ring */
620 rxd[rxd_tail].status = 0x80000000;
621 rxd_tail++;
622 if (rxd_tail == NRXD) rxd_tail = 0;
624 return 1;
627 /*********************************************************************/
628 /* eth_disable - Disable the interface */
629 /*********************************************************************/
630 static void davicom_disable(struct nic *nic)
632 whereami("davicom_disable\n");
634 /* disable interrupts */
635 outl(0x00000000, ioaddr + CSR7);
637 /* Stop the chip's Tx and Rx processes. */
638 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
640 /* Clear the missed-packet counter. */
641 (volatile unsigned long)inl(ioaddr + CSR8);
644 /*********************************************************************/
645 /* eth_probe - Look for an adapter */
646 /*********************************************************************/
647 struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
648 struct pci_device *pci)
650 unsigned int i;
651 u32 l1, l2;
653 whereami("davicom_probe\n");
655 if (io_addrs == 0 || *io_addrs == 0)
656 return 0;
658 vendor = pci->vendor;
659 dev_id = pci->dev_id;
660 ioaddr = *io_addrs;
662 /* wakeup chip */
663 pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
665 /* Stop the chip's Tx and Rx processes. */
666 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
668 /* Clear the missed-packet counter. */
669 (volatile unsigned long)inl(ioaddr + CSR8);
671 /* Get MAC Address */
672 /* read EEPROM data */
673 for (i = 0; i < sizeof(ee_data)/2; i++)
674 ((unsigned short *)ee_data)[i] =
675 le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
677 /* extract MAC address from EEPROM buffer */
678 for (i=0; i<ETH_ALEN; i++)
679 nic->node_addr[i] = ee_data[20+i];
681 printf("Davicom %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
683 /* initialize device */
684 davicom_reset(nic);
686 nic->reset = davicom_reset;
687 nic->poll = davicom_poll;
688 nic->transmit = davicom_transmit;
689 nic->disable = davicom_disable;
691 return nic;