vm: remove leftover diag print
[minix.git] / drivers / dp8390 / rtl8029.c
blobd2ff930ec27d208239c224e4bcebd0eb3f29d869
1 /*
2 rtl8029.c
4 Initialization of PCI DP8390-based ethernet cards
6 Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
7 */
9 #include <minix/drivers.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <net/gen/ether.h>
14 #include <net/gen/eth_io.h>
15 #include <machine/pci.h>
17 #include "assert.h"
19 #include "local.h"
20 #include "dp8390.h"
21 #include "rtl8029.h"
23 #if ENABLE_PCI
25 PRIVATE struct pcitab
27 u16_t vid;
28 u16_t did;
29 int checkclass;
30 } pcitab[]=
32 { 0x10ec, 0x8029, 0 }, /* Realtek RTL8029 */
34 { 0x0000, 0x0000, 0 }
37 _PROTOTYPE( static void rtl_init, (struct dpeth *dep) );
38 #if 0
39 _PROTOTYPE( static u16_t get_ee_word, (dpeth_t *dep, int a) );
40 _PROTOTYPE( static void ee_wen, (dpeth_t *dep) );
41 _PROTOTYPE( static void set_ee_word, (dpeth_t *dep, int a, u16_t w) );
42 _PROTOTYPE( static void ee_wds, (dpeth_t *dep) );
43 #endif
45 PUBLIC int rtl_probe(dep)
46 struct dpeth *dep;
48 int i, r, devind, just_one;
49 u16_t vid, did;
50 u32_t bar;
51 u8_t ilr;
52 char *dname;
54 pci_init();
56 if ((dep->de_pcibus | dep->de_pcidev | dep->de_pcifunc) != 0)
58 /* Look for specific PCI device */
59 r= pci_find_dev(dep->de_pcibus, dep->de_pcidev,
60 dep->de_pcifunc, &devind);
61 if (r == 0)
63 printf("%s: no PCI found at %d.%d.%d\n",
64 dep->de_name, dep->de_pcibus,
65 dep->de_pcidev, dep->de_pcifunc);
66 return 0;
68 pci_ids(devind, &vid, &did);
69 just_one= TRUE;
71 else
73 r= pci_first_dev(&devind, &vid, &did);
74 if (r == 0)
75 return 0;
76 just_one= FALSE;
79 for(;;)
81 for (i= 0; pcitab[i].vid != 0 || pcitab[i].did != 0; i++)
83 if (pcitab[i].vid != vid)
84 continue;
85 if (pcitab[i].did != did)
86 continue;
87 if (pcitab[i].checkclass) {
88 panic("rtl_probe: class check not implemented");
90 break;
92 if (pcitab[i].vid != 0 || pcitab[i].did != 0)
93 break;
95 if (just_one)
97 printf(
98 "%s: wrong PCI device (%04X/%04X) found at %d.%d.%d\n",
99 dep->de_name, vid, did,
100 dep->de_pcibus,
101 dep->de_pcidev, dep->de_pcifunc);
102 return 0;
105 r= pci_next_dev(&devind, &vid, &did);
106 if (!r)
107 return 0;
110 dname= pci_dev_name(vid, did);
111 if (!dname)
112 dname= "unknown device";
113 printf("%s: %s (%04X/%04X) at %s\n",
114 dep->de_name, dname, vid, did, pci_slot_name(devind));
115 if(pci_reserve_ok(devind) != OK)
116 return 0;
117 /* printf("cr = 0x%x\n", pci_attr_r16(devind, PCI_CR)); */
118 bar= pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
120 if (bar < 0x400)
121 panic("base address is not properly configured");
123 dep->de_base_port= bar;
125 ilr= pci_attr_r8(devind, PCI_ILR);
126 dep->de_irq= ilr;
127 if (debug)
129 printf("%s: using I/O address 0x%lx, IRQ %d\n",
130 dep->de_name, (unsigned long)bar, ilr);
132 dep->de_initf= rtl_init;
134 return TRUE;
137 static void rtl_init(dep)
138 dpeth_t *dep;
140 u8_t reg_a, reg_b, cr, config0, config2, config3;
141 int i;
143 #if DEBUG
144 printf("rtl_init called\n");
145 #endif
146 ne_init(dep);
148 /* ID */
149 outb_reg0(dep, DP_CR, CR_PS_P0);
150 reg_a = inb_reg0(dep, DP_DUM1);
151 reg_b = inb_reg0(dep, DP_DUM2);
153 #if DEBUG
154 printf("rtl_init: '%c', '%c'\n", reg_a, reg_b);
155 #endif
157 outb_reg0(dep, DP_CR, CR_PS_P3);
158 config0 = inb_reg3(dep, 3);
159 config2 = inb_reg3(dep, 5);
160 config3 = inb_reg3(dep, 6);
161 outb_reg0(dep, DP_CR, CR_PS_P0);
163 #if DEBUG
164 printf("rtl_init: config 0/2/3 = %x/%x/%x\n",
165 config0, config2, config3);
166 #endif
168 if (getenv("RTL8029FD"))
170 printf("rtl_init: setting full-duplex mode\n");
171 outb_reg0(dep, DP_CR, CR_PS_P3);
173 cr= inb_reg3(dep, 1);
174 outb_reg3(dep, 1, cr | 0xc0);
176 outb_reg3(dep, 6, config3 | 0x40);
177 config3 = inb_reg3(dep, 6);
179 config2= inb_reg3(dep, 5);
180 outb_reg3(dep, 5, config2 | 0x20);
181 config2= inb_reg3(dep, 5);
183 outb_reg3(dep, 1, cr);
185 outb_reg0(dep, DP_CR, CR_PS_P0);
187 #if DEBUG
188 printf("rtl_init: config 2 = %x\n", config2);
189 printf("rtl_init: config 3 = %x\n", config3);
190 #endif
193 #if DEBUG
194 for (i= 0; i<64; i++)
195 printf("%x ", get_ee_word(dep, i));
196 printf("\n");
197 #endif
199 #if 0
200 if (getenv("RTL8029MN"))
202 ee_wen(dep);
204 set_ee_word(dep, 0x78/2, 0x10ec);
205 set_ee_word(dep, 0x7A/2, 0x8029);
206 set_ee_word(dep, 0x7C/2, 0x10ec);
207 set_ee_word(dep, 0x7E/2, 0x8029);
209 ee_wds(dep);
211 assert(get_ee_word(dep, 0x78/2) == 0x10ec);
212 assert(get_ee_word(dep, 0x7A/2) == 0x8029);
213 assert(get_ee_word(dep, 0x7C/2) == 0x10ec);
214 assert(get_ee_word(dep, 0x7E/2) == 0x8029);
217 if (getenv("RTL8029XXX"))
219 ee_wen(dep);
221 set_ee_word(dep, 0x76/2, 0x8029);
223 ee_wds(dep);
225 assert(get_ee_word(dep, 0x76/2) == 0x8029);
227 #endif
230 #if 0
231 static u16_t get_ee_word(dep, a)
232 dpeth_t *dep;
233 int a;
235 int b, i, cmd;
236 u16_t w;
238 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
240 /* Switch to 9346 mode and enable CS */
241 outb_reg3(dep, 1, 0x80 | 0x8);
243 cmd= 0x180 | (a & 0x3f); /* 1 1 0 a5 a4 a3 a2 a1 a0 */
244 for (i= 8; i >= 0; i--)
246 b= (cmd & (1 << i));
247 b= (b ? 2 : 0);
249 /* Cmd goes out on the rising edge of the clock */
250 outb_reg3(dep, 1, 0x80 | 0x8 | b);
251 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
253 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
255 w= 0;
256 for (i= 0; i<16; i++)
258 w <<= 1;
260 /* Data is shifted out on the rising edge. Read at the
261 * falling edge.
263 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4);
264 outb_reg3(dep, 1, 0x80 | 0x8 | b);
265 b= inb_reg3(dep, 1);
266 w |= (b & 1);
269 outb_reg3(dep, 1, 0x80); /* drop CS */
270 outb_reg3(dep, 1, 0x00); /* back to normal */
271 outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
273 return w;
276 static void ee_wen(dep)
277 dpeth_t *dep;
279 int b, i, cmd;
281 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
283 /* Switch to 9346 mode and enable CS */
284 outb_reg3(dep, 1, 0x80 | 0x8);
286 cmd= 0x130; /* 1 0 0 1 1 x x x x */
287 for (i= 8; i >= 0; i--)
289 b= (cmd & (1 << i));
290 b= (b ? 2 : 0);
292 /* Cmd goes out on the rising edge of the clock */
293 outb_reg3(dep, 1, 0x80 | 0x8 | b);
294 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
296 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
297 outb_reg3(dep, 1, 0x80); /* Drop CS */
298 micro_delay(1); /* Is this required? */
301 static void set_ee_word(dep, a, w)
302 dpeth_t *dep;
303 int a;
304 u16_t w;
306 int b, i, cmd;
308 outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
310 cmd= 0x140 | (a & 0x3f); /* 1 0 1 a5 a4 a3 a2 a1 a0 */
311 for (i= 8; i >= 0; i--)
313 b= (cmd & (1 << i));
314 b= (b ? 2 : 0);
316 /* Cmd goes out on the rising edge of the clock */
317 outb_reg3(dep, 1, 0x80 | 0x8 | b);
318 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
320 for (i= 15; i >= 0; i--)
322 b= (w & (1 << i));
323 b= (b ? 2 : 0);
325 /* Cmd goes out on the rising edge of the clock */
326 outb_reg3(dep, 1, 0x80 | 0x8 | b);
327 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
329 outb_reg3(dep, 1, 0x80 | 0x8); /* End of data */
330 outb_reg3(dep, 1, 0x80); /* Drop CS */
331 micro_delay(1); /* Is this required? */
332 outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
333 for (i= 0; i<10000; i++)
335 if (inb_reg3(dep, 1) & 1)
336 break;
337 micro_delay(1);
339 if (!(inb_reg3(dep, 1) & 1))
340 panic("set_ee_word: device remains busy");
343 static void ee_wds(dep)
344 dpeth_t *dep;
346 int b, i, cmd;
348 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
350 /* Switch to 9346 mode and enable CS */
351 outb_reg3(dep, 1, 0x80 | 0x8);
353 cmd= 0x100; /* 1 0 0 0 0 x x x x */
354 for (i= 8; i >= 0; i--)
356 b= (cmd & (1 << i));
357 b= (b ? 2 : 0);
359 /* Cmd goes out on the rising edge of the clock */
360 outb_reg3(dep, 1, 0x80 | 0x8 | b);
361 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
363 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
364 outb_reg3(dep, 1, 0x80); /* Drop CS */
365 outb_reg3(dep, 1, 0x00); /* back to normal */
366 outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
368 #endif
370 #endif /* ENABLE_PCI */
373 * $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $