4 Initialization of PCI DP8390-based ethernet cards
6 Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
9 #include <minix/drivers.h>
12 #include <sys/types.h>
13 #include <net/gen/ether.h>
14 #include <net/gen/eth_io.h>
15 #include <machine/pci.h>
25 static void rtl_init(struct dpeth
*dep
);
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
);
33 int rtl_probe(dep
, skip
)
45 r
= pci_first_dev(&devind
, &vid
, &did
);
51 r
= pci_next_dev(&devind
, &vid
, &did
);
56 dname
= pci_dev_name(vid
, did
);
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
)
63 /* printf("cr = 0x%x\n", pci_attr_r16(devind, PCI_CR)); */
64 bar
= pci_attr_r32(devind
, PCI_BAR
) & 0xffffffe0;
67 panic("base address is not properly configured");
69 dep
->de_base_port
= bar
;
71 ilr
= pci_attr_r8(devind
, PCI_ILR
);
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
;
83 static void rtl_init(dep
)
86 u8_t reg_a
, reg_b
, cr
, config0
, config2
, config3
;
89 printf("rtl_init called\n");
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
);
99 printf("rtl_init: '%c', '%c'\n", reg_a
, reg_b
);
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
);
109 printf("rtl_init: config 0/2/3 = %x/%x/%x\n",
110 config0
, config2
, config3
);
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
);
133 printf("rtl_init: config 2 = %x\n", config2
);
134 printf("rtl_init: config 3 = %x\n", config3
);
139 for (i
= 0; i
<64; i
++)
140 printf("%x ", get_ee_word(dep
, i
));
145 if (getenv("RTL8029MN"))
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);
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"))
166 set_ee_word(dep
, 0x76/2, 0x8029);
170 assert(get_ee_word(dep
, 0x76/2) == 0x8029);
176 static u16_t
get_ee_word(dep
, a
)
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
--)
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 */
201 for (i
= 0; i
<16; i
++)
205 /* Data is shifted out on the rising edge. Read at the
208 outb_reg3(dep
, 1, 0x80 | 0x8 | 0x4);
209 outb_reg3(dep
, 1, 0x80 | 0x8 | b
);
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 */
221 static void ee_wen(dep
)
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
--)
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
)
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
--)
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
--)
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)
284 if (!(inb_reg3(dep
, 1) & 1))
285 panic("set_ee_word: device remains busy");
288 static void ee_wds(dep
)
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
--)
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 */
315 #endif /* ENABLE_PCI */
318 * $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $