Linking blocktest without libc to allow terminal output
[minix3.git] / drivers / dp8390 / rtl8029.c
blobf69453da9c723567ad663eae12221a94ea456141
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 static void rtl_init(struct dpeth *dep);
26 #if 0
27 static u16_t get_ee_word(dpeth_t *dep, int a);
28 static void ee_wen(dpeth_t *dep);
29 static void set_ee_word(dpeth_t *dep, int a, u16_t w);
30 static void ee_wds(dpeth_t *dep);
31 #endif
33 int rtl_probe(dep, skip)
34 struct dpeth *dep;
35 int skip;
37 int r, devind;
38 u16_t vid, did;
39 u32_t bar;
40 u8_t ilr;
41 char *dname;
43 pci_init();
45 r= pci_first_dev(&devind, &vid, &did);
46 if (r == 0)
47 return 0;
49 while (skip--)
51 r= pci_next_dev(&devind, &vid, &did);
52 if (!r)
53 return 0;
56 dname= pci_dev_name(vid, did);
57 if (!dname)
58 dname= "unknown device";
59 printf("%s: %s (%04X/%04X) at %s\n",
60 dep->de_name, dname, vid, did, pci_slot_name(devind));
61 if(pci_reserve_ok(devind) != OK)
62 return 0;
63 /* printf("cr = 0x%x\n", pci_attr_r16(devind, PCI_CR)); */
64 bar= pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
66 if (bar < 0x400)
67 panic("base address is not properly configured");
69 dep->de_base_port= bar;
71 ilr= pci_attr_r8(devind, PCI_ILR);
72 dep->de_irq= ilr;
73 if (debug)
75 printf("%s: using I/O address 0x%lx, IRQ %d\n",
76 dep->de_name, (unsigned long)bar, ilr);
78 dep->de_initf= rtl_init;
80 return TRUE;
83 static void rtl_init(dep)
84 dpeth_t *dep;
86 u8_t reg_a, reg_b, cr, config0, config2, config3;
88 #if DEBUG
89 printf("rtl_init called\n");
90 #endif
91 ne_init(dep);
93 /* ID */
94 outb_reg0(dep, DP_CR, CR_PS_P0);
95 reg_a = inb_reg0(dep, DP_DUM1);
96 reg_b = inb_reg0(dep, DP_DUM2);
98 #if DEBUG
99 printf("rtl_init: '%c', '%c'\n", reg_a, reg_b);
100 #endif
102 outb_reg0(dep, DP_CR, CR_PS_P3);
103 config0 = inb_reg3(dep, 3);
104 config2 = inb_reg3(dep, 5);
105 config3 = inb_reg3(dep, 6);
106 outb_reg0(dep, DP_CR, CR_PS_P0);
108 #if DEBUG
109 printf("rtl_init: config 0/2/3 = %x/%x/%x\n",
110 config0, config2, config3);
111 #endif
113 if (getenv("RTL8029FD"))
115 printf("rtl_init: setting full-duplex mode\n");
116 outb_reg0(dep, DP_CR, CR_PS_P3);
118 cr= inb_reg3(dep, 1);
119 outb_reg3(dep, 1, cr | 0xc0);
121 outb_reg3(dep, 6, config3 | 0x40);
122 config3 = inb_reg3(dep, 6);
124 config2= inb_reg3(dep, 5);
125 outb_reg3(dep, 5, config2 | 0x20);
126 config2= inb_reg3(dep, 5);
128 outb_reg3(dep, 1, cr);
130 outb_reg0(dep, DP_CR, CR_PS_P0);
132 #if DEBUG
133 printf("rtl_init: config 2 = %x\n", config2);
134 printf("rtl_init: config 3 = %x\n", config3);
135 #endif
138 #if 0
139 for (i= 0; i<64; i++)
140 printf("%x ", get_ee_word(dep, i));
141 printf("\n");
142 #endif
144 #if 0
145 if (getenv("RTL8029MN"))
147 ee_wen(dep);
149 set_ee_word(dep, 0x78/2, 0x10ec);
150 set_ee_word(dep, 0x7A/2, 0x8029);
151 set_ee_word(dep, 0x7C/2, 0x10ec);
152 set_ee_word(dep, 0x7E/2, 0x8029);
154 ee_wds(dep);
156 assert(get_ee_word(dep, 0x78/2) == 0x10ec);
157 assert(get_ee_word(dep, 0x7A/2) == 0x8029);
158 assert(get_ee_word(dep, 0x7C/2) == 0x10ec);
159 assert(get_ee_word(dep, 0x7E/2) == 0x8029);
162 if (getenv("RTL8029XXX"))
164 ee_wen(dep);
166 set_ee_word(dep, 0x76/2, 0x8029);
168 ee_wds(dep);
170 assert(get_ee_word(dep, 0x76/2) == 0x8029);
172 #endif
175 #if 0
176 static u16_t get_ee_word(dep, a)
177 dpeth_t *dep;
178 int a;
180 int b, i, cmd;
181 u16_t w;
183 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
185 /* Switch to 9346 mode and enable CS */
186 outb_reg3(dep, 1, 0x80 | 0x8);
188 cmd= 0x180 | (a & 0x3f); /* 1 1 0 a5 a4 a3 a2 a1 a0 */
189 for (i= 8; i >= 0; i--)
191 b= (cmd & (1 << i));
192 b= (b ? 2 : 0);
194 /* Cmd goes out on the rising edge of the clock */
195 outb_reg3(dep, 1, 0x80 | 0x8 | b);
196 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
198 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
200 w= 0;
201 for (i= 0; i<16; i++)
203 w <<= 1;
205 /* Data is shifted out on the rising edge. Read at the
206 * falling edge.
208 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4);
209 outb_reg3(dep, 1, 0x80 | 0x8 | b);
210 b= inb_reg3(dep, 1);
211 w |= (b & 1);
214 outb_reg3(dep, 1, 0x80); /* drop CS */
215 outb_reg3(dep, 1, 0x00); /* back to normal */
216 outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
218 return w;
221 static void ee_wen(dep)
222 dpeth_t *dep;
224 int b, i, cmd;
226 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
228 /* Switch to 9346 mode and enable CS */
229 outb_reg3(dep, 1, 0x80 | 0x8);
231 cmd= 0x130; /* 1 0 0 1 1 x x x x */
232 for (i= 8; i >= 0; i--)
234 b= (cmd & (1 << i));
235 b= (b ? 2 : 0);
237 /* Cmd goes out on the rising edge of the clock */
238 outb_reg3(dep, 1, 0x80 | 0x8 | b);
239 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
241 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
242 outb_reg3(dep, 1, 0x80); /* Drop CS */
243 micro_delay(1); /* Is this required? */
246 static void set_ee_word(dep, a, w)
247 dpeth_t *dep;
248 int a;
249 u16_t w;
251 int b, i, cmd;
253 outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
255 cmd= 0x140 | (a & 0x3f); /* 1 0 1 a5 a4 a3 a2 a1 a0 */
256 for (i= 8; i >= 0; i--)
258 b= (cmd & (1 << i));
259 b= (b ? 2 : 0);
261 /* Cmd goes out on the rising edge of the clock */
262 outb_reg3(dep, 1, 0x80 | 0x8 | b);
263 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
265 for (i= 15; i >= 0; i--)
267 b= (w & (1 << i));
268 b= (b ? 2 : 0);
270 /* Cmd goes out on the rising edge of the clock */
271 outb_reg3(dep, 1, 0x80 | 0x8 | b);
272 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
274 outb_reg3(dep, 1, 0x80 | 0x8); /* End of data */
275 outb_reg3(dep, 1, 0x80); /* Drop CS */
276 micro_delay(1); /* Is this required? */
277 outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
278 for (i= 0; i<10000; i++)
280 if (inb_reg3(dep, 1) & 1)
281 break;
282 micro_delay(1);
284 if (!(inb_reg3(dep, 1) & 1))
285 panic("set_ee_word: device remains busy");
288 static void ee_wds(dep)
289 dpeth_t *dep;
291 int b, i, cmd;
293 outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
295 /* Switch to 9346 mode and enable CS */
296 outb_reg3(dep, 1, 0x80 | 0x8);
298 cmd= 0x100; /* 1 0 0 0 0 x x x x */
299 for (i= 8; i >= 0; i--)
301 b= (cmd & (1 << i));
302 b= (b ? 2 : 0);
304 /* Cmd goes out on the rising edge of the clock */
305 outb_reg3(dep, 1, 0x80 | 0x8 | b);
306 outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
308 outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
309 outb_reg3(dep, 1, 0x80); /* Drop CS */
310 outb_reg3(dep, 1, 0x00); /* back to normal */
311 outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
313 #endif
315 #endif /* ENABLE_PCI */
318 * $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $