Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2465 | Serge | 3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
431 | serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; PCNET32.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Ethernet driver for Menuet OS ;; |
||
9 | ;; ;; |
||
781 | hidnplayr | 10 | ;; - Version 1.0 31 July 2004: ;; |
11 | ;; Initial release ;; |
||
431 | serge | 12 | ;; ;; |
781 | hidnplayr | 13 | ;; - Version 1.01 29 March 2008: ;; |
14 | ;; Adapted to work with kolibrios flat kernel ;; |
||
15 | ;; Debug info is updated, and now uses DEBUGF macro ;; |
||
16 | ;; by hidnplayr@kolibrios.org ;; |
||
17 | ;; ;; |
||
431 | serge | 18 | ;; This driver is based on the PCNet32 driver from ;; |
19 | ;; the etherboot 5.0.6 project. The copyright statement is ;; |
||
20 | ;; ;; |
||
21 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
22 | ;; Version 2, June 1991 ;; |
||
23 | ;; ;; |
||
24 | ;; remaining parts Copyright 2004 Jarek Pelczar, ;; |
||
25 | ;; jpelczar@interia.pl ;; |
||
26 | ;; ;; |
||
27 | ;; See file COPYING for details ;; |
||
28 | ;; ;; |
||
29 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
593 | mikedld | 30 | |
31 | $Revision: 2465 $ |
||
32 | |||
33 | |||
261 | hidnplayr | 34 | PCNET32_PORT_AUI equ 0x00 |
35 | PCNET32_PORT_10BT equ 0x01 |
||
36 | PCNET32_PORT_GPSI equ 0x02 |
||
37 | PCNET32_PORT_MII equ 0x03 |
||
38 | PCNET32_PORT_PORTSEL equ 0x03 |
||
39 | PCNET32_PORT_ASEL equ 0x04 |
||
40 | PCNET32_PORT_100 equ 0x40 |
||
41 | PCNET32_PORT_FD equ 0x80 |
||
42 | PCNET32_DMA_MASK equ 0xffffffff |
||
781 | hidnplayr | 43 | |
2434 | Serge | 44 | PCNET32_LOG_TX_BUFFERS equ 1 |
45 | PCNET32_LOG_RX_BUFFERS equ 2 |
||
781 | hidnplayr | 46 | |
2434 | Serge | 47 | PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) |
48 | PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) |
||
49 | PCNET32_TX_RING_LEN_BITS equ 0 |
||
50 | PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) |
||
51 | PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) |
||
52 | PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) |
||
53 | PCNET32_PKT_BUF_SZ equ 1544 |
||
54 | PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 |
||
781 | hidnplayr | 55 | |
261 | hidnplayr | 56 | pcnet32_txb equ (eth_data_start) |
57 | pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
||
58 | pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
||
59 | pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
||
781 | hidnplayr | 60 | |
261 | hidnplayr | 61 | virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
62 | pcnet32_private: |
||
2434 | Serge | 63 | .mode dw ? |
64 | .tlen_rlen dw ? |
||
65 | .phys_addr db ?,?,?,?,?,? |
||
66 | .reserved dw ? |
||
67 | .filter dd ?,? |
||
68 | .rx_ring dd ? |
||
69 | .tx_ring dd ? |
||
70 | .cur_rx dd ? |
||
71 | .cur_tx dd ? |
||
72 | .dirty_rx dd ? |
||
73 | .dirty_tx dd ? |
||
74 | .tx_full db ? |
||
75 | .options dd ? |
||
76 | .full_duplex db ? |
||
77 | .chip_version dd ? |
||
78 | .mii db ? |
||
79 | .ltint db ? |
||
80 | .dxsuflo db ? |
||
81 | .fset db ? |
||
82 | .fdx db ? |
||
261 | hidnplayr | 83 | end virtual |
781 | hidnplayr | 84 | |
261 | hidnplayr | 85 | virtual at 0 |
86 | pcnet32_rx_head: |
||
2434 | Serge | 87 | .base dd ? |
88 | .buf_length dw ? |
||
89 | .status dw ? |
||
90 | .msg_length dd ? |
||
91 | .reserved dd ? |
||
261 | hidnplayr | 92 | end virtual |
781 | hidnplayr | 93 | |
261 | hidnplayr | 94 | virtual at 0 |
95 | pcnet32_tx_head: |
||
2434 | Serge | 96 | .base dd ? |
97 | .length dw ? |
||
98 | .status dw ? |
||
99 | .misc dd ? |
||
100 | .reserved dd ? |
||
261 | hidnplayr | 101 | end virtual |
102 | |||
103 | uglobal |
||
104 | pcnet32_access: |
||
2434 | Serge | 105 | .read_csr dd ? |
106 | .write_csr dd ? |
||
107 | .read_bcr dd ? |
||
108 | .write_bcr dd ? |
||
109 | .read_rap dd ? |
||
110 | .write_rap dd ? |
||
111 | .reset dd ? |
||
261 | hidnplayr | 112 | endg |
113 | |||
114 | iglobal |
||
115 | pcnet32_options_mapping: |
||
2434 | Serge | 116 | dd PCNET32_PORT_ASEL ; 0 Auto-select |
117 | dd PCNET32_PORT_AUI ; 1 BNC/AUI |
||
118 | dd PCNET32_PORT_AUI ; 2 AUI/BNC |
||
119 | dd PCNET32_PORT_ASEL ; 3 not supported |
||
261 | hidnplayr | 120 | dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD |
2434 | Serge | 121 | dd PCNET32_PORT_ASEL ; 5 not supported |
122 | dd PCNET32_PORT_ASEL ; 6 not supported |
||
123 | dd PCNET32_PORT_ASEL ; 7 not supported |
||
124 | dd PCNET32_PORT_ASEL ; 8 not supported |
||
125 | dd PCNET32_PORT_MII ; 9 MII 10baseT |
||
126 | dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD |
||
127 | dd PCNET32_PORT_MII ; 11 MII (autosel) |
||
128 | dd PCNET32_PORT_10BT ; 12 10BaseT |
||
261 | hidnplayr | 129 | dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx |
2434 | Serge | 130 | dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD |
131 | dd PCNET32_PORT_ASEL ; 15 not supported |
||
261 | hidnplayr | 132 | endg |
133 | |||
2434 | Serge | 134 | PCNET32_WIO_RDP equ 0x10 |
135 | PCNET32_WIO_RAP equ 0x12 |
||
136 | PCNET32_WIO_RESET equ 0x14 |
||
137 | PCNET32_WIO_BDP equ 0x16 |
||
138 | PCNET32_DWIO_RDP equ 0x10 |
||
139 | PCNET32_DWIO_RAP equ 0x14 |
||
140 | PCNET32_DWIO_RESET equ 0x18 |
||
141 | PCNET32_DWIO_BDP equ 0x1C |
||
142 | PCNET32_TOTAL_SIZE equ 0x20 |
||
261 | hidnplayr | 143 | ; ebx - index |
144 | ; return: |
||
145 | ; eax - data |
||
146 | pcnet32_wio_read_csr: |
||
2434 | Serge | 147 | push edx |
148 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
149 | mov ax, bx |
||
150 | out dx, ax |
||
151 | lea edx, [ebp+PCNET32_WIO_RDP] |
||
152 | in ax, dx |
||
153 | and eax, 0xffff |
||
154 | pop edx |
||
155 | ret |
||
261 | hidnplayr | 156 | ; eax - data |
157 | ; ebx - index |
||
158 | pcnet32_wio_write_csr: |
||
2434 | Serge | 159 | push edx |
160 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
161 | xchg eax, ebx |
||
162 | out dx, ax |
||
163 | xchg eax, ebx |
||
164 | lea edx, [ebp+PCNET32_WIO_RDP] |
||
165 | out dx, ax |
||
166 | pop edx |
||
167 | ret |
||
261 | hidnplayr | 168 | ; ebx - index |
169 | ; return: |
||
170 | ; eax - data |
||
171 | pcnet32_wio_read_bcr: |
||
2434 | Serge | 172 | push edx |
173 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
174 | mov ax, bx |
||
175 | out dx, ax |
||
176 | lea edx, [ebp+PCNET32_WIO_BDP] |
||
177 | in ax, dx |
||
178 | and eax, 0xffff |
||
179 | pop edx |
||
180 | ret |
||
261 | hidnplayr | 181 | ; eax - data |
182 | ; ebx - index |
||
183 | pcnet32_wio_write_bcr: |
||
2434 | Serge | 184 | push edx |
185 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
186 | xchg eax, ebx |
||
187 | out dx, ax |
||
188 | xchg eax, ebx |
||
189 | lea edx, [ebp+PCNET32_WIO_BDP] |
||
190 | out dx, ax |
||
191 | pop edx |
||
192 | ret |
||
261 | hidnplayr | 193 | pcnet32_wio_read_rap: |
2434 | Serge | 194 | push edx |
195 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
196 | in ax, dx |
||
197 | and eax, 0xffff |
||
198 | pop edx |
||
199 | ret |
||
261 | hidnplayr | 200 | ; eax - val |
201 | pcnet32_wio_write_rap: |
||
2434 | Serge | 202 | push edx |
203 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
204 | out dx, ax |
||
205 | pop edx |
||
206 | ret |
||
261 | hidnplayr | 207 | pcnet32_wio_reset: |
2434 | Serge | 208 | push edx |
209 | push eax |
||
210 | lea edx, [ebp+PCNET32_WIO_RESET] |
||
211 | in ax, dx |
||
212 | pop eax |
||
213 | pop edx |
||
214 | ret |
||
261 | hidnplayr | 215 | pcnet32_wio_check: |
2434 | Serge | 216 | push edx |
217 | mov ax, 88 |
||
218 | lea edx, [ebp+PCNET32_WIO_RAP] |
||
219 | out dx, ax |
||
220 | nop |
||
221 | nop |
||
222 | in ax, dx |
||
223 | cmp ax, 88 |
||
224 | sete al |
||
225 | pop edx |
||
226 | ret |
||
261 | hidnplayr | 227 | |
228 | iglobal |
||
229 | pcnet32_wio: |
||
230 | dd pcnet32_wio_read_csr |
||
231 | dd pcnet32_wio_write_csr |
||
232 | dd pcnet32_wio_read_bcr |
||
233 | dd pcnet32_wio_write_bcr |
||
234 | dd pcnet32_wio_read_rap |
||
235 | dd pcnet32_wio_write_rap |
||
236 | dd pcnet32_wio_reset |
||
237 | endg |
||
238 | |||
239 | ; ebx - index |
||
240 | ; return: |
||
241 | ; eax - data |
||
242 | pcnet32_dwio_read_csr: |
||
2434 | Serge | 243 | push edx |
244 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
245 | mov ebx, eax |
||
246 | out dx, eax |
||
247 | lea edx, [ebp+PCNET32_DWIO_RDP] |
||
248 | in eax, dx |
||
249 | and eax, 0xffff |
||
250 | pop edx |
||
251 | ret |
||
261 | hidnplayr | 252 | ; ebx - index |
253 | ; eax - data |
||
254 | pcnet32_dwio_write_csr: |
||
2434 | Serge | 255 | push edx |
256 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
257 | xchg eax, ebx |
||
258 | out dx, eax |
||
259 | lea edx, [ebp+PCNET32_DWIO_RDP] |
||
260 | xchg eax, ebx |
||
261 | out dx, eax |
||
262 | pop edx |
||
263 | ret |
||
261 | hidnplayr | 264 | ; ebx - index |
265 | ; return: |
||
266 | ; eax - data |
||
267 | pcnet32_dwio_read_bcr: |
||
2434 | Serge | 268 | push edx |
269 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
270 | mov ebx, eax |
||
271 | out dx, eax |
||
272 | lea edx, [ebp+PCNET32_DWIO_BDP] |
||
273 | in eax, dx |
||
274 | and eax, 0xffff |
||
275 | pop edx |
||
276 | ret |
||
261 | hidnplayr | 277 | ; ebx - index |
278 | ; eax - data |
||
279 | pcnet32_dwio_write_bcr: |
||
2434 | Serge | 280 | push edx |
281 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
282 | xchg eax, ebx |
||
283 | out dx, eax |
||
284 | lea edx, [ebp+PCNET32_DWIO_BDP] |
||
285 | xchg eax, ebx |
||
286 | out dx, eax |
||
287 | pop edx |
||
288 | ret |
||
261 | hidnplayr | 289 | pcnet32_dwio_read_rap: |
2434 | Serge | 290 | push edx |
291 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
292 | in eax, dx |
||
293 | and eax, 0xffff |
||
294 | pop edx |
||
295 | ret |
||
261 | hidnplayr | 296 | ; eax - val |
297 | pcnet32_dwio_write_rap: |
||
2434 | Serge | 298 | push edx |
299 | lea edx, [ebp+PCNET32_DWIO_RAP] |
||
300 | out dx, eax |
||
301 | pop edx |
||
302 | ret |
||
261 | hidnplayr | 303 | pcnet32_dwio_reset: |
2434 | Serge | 304 | push edx |
305 | push eax |
||
306 | lea edx, [ebp+PCNET32_DWIO_RESET] |
||
307 | in eax, dx |
||
308 | pop eax |
||
309 | pop edx |
||
310 | ret |
||
261 | hidnplayr | 311 | pcnet32_dwio_check: |
2434 | Serge | 312 | push edx |
313 | lea edx, [PCNET32_DWIO_RAP] |
||
314 | mov eax, 88 |
||
315 | out dx, eax |
||
316 | nop |
||
317 | nop |
||
318 | in eax, dx |
||
319 | and eax, 0xffff |
||
320 | cmp eax, 88 |
||
321 | sete al |
||
322 | pop edx |
||
323 | ret |
||
261 | hidnplayr | 324 | |
325 | iglobal |
||
326 | pcnet32_dwio: |
||
327 | dd pcnet32_dwio_read_csr |
||
328 | dd pcnet32_dwio_write_csr |
||
329 | dd pcnet32_dwio_read_bcr |
||
330 | dd pcnet32_dwio_write_bcr |
||
331 | dd pcnet32_dwio_read_rap |
||
332 | dd pcnet32_dwio_write_rap |
||
333 | dd pcnet32_dwio_reset |
||
334 | endg |
||
335 | |||
781 | hidnplayr | 336 | |
337 | |||
261 | hidnplayr | 338 | pcnet32_init_ring: |
2434 | Serge | 339 | mov [pcnet32_private.tx_full], 0 |
340 | mov [pcnet32_private.cur_rx], 0 |
||
341 | mov [pcnet32_private.cur_tx], 0 |
||
342 | mov [pcnet32_private.dirty_rx], 0 |
||
343 | mov [pcnet32_private.dirty_tx], 0 |
||
344 | mov edi, pcnet32_rx_ring |
||
345 | mov ecx, PCNET32_RX_RING_SIZE |
||
346 | mov ebx, pcnet32_rxb |
||
347 | sub ebx, OS_BASE |
||
261 | hidnplayr | 348 | .rx_init: |
2434 | Serge | 349 | mov [edi+pcnet32_rx_head.base], ebx |
350 | mov [edi+pcnet32_rx_head.buf_length], word PCNET32_PKT_BUF_SZ_NEG |
||
351 | mov [edi+pcnet32_rx_head.status], word 0x8000 |
||
352 | add ebx, PCNET32_PKT_BUF_SZ |
||
261 | hidnplayr | 353 | ; inc ebx |
2434 | Serge | 354 | add edi, 16 |
355 | loop .rx_init |
||
356 | mov edi, pcnet32_tx_ring |
||
357 | mov ecx, PCNET32_TX_RING_SIZE |
||
261 | hidnplayr | 358 | .tx_init: |
2434 | Serge | 359 | mov [edi+pcnet32_tx_head.base], dword 0 |
360 | mov [edi+pcnet32_tx_head.status], word 0 |
||
361 | add edi, 16 |
||
362 | loop .tx_init |
||
363 | mov [pcnet32_private.tlen_rlen], (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
||
364 | mov esi, node_addr |
||
365 | mov edi, pcnet32_private.phys_addr |
||
366 | cld |
||
367 | movsd |
||
368 | movsw |
||
369 | mov eax, pcnet32_rx_ring |
||
370 | sub eax, OS_BASE |
||
371 | mov dword [pcnet32_private.rx_ring], eax |
||
781 | hidnplayr | 372 | |
2434 | Serge | 373 | mov eax, pcnet32_tx_ring |
374 | sub eax, OS_BASE |
||
375 | mov dword [pcnet32_private.tx_ring], eax |
||
376 | ret |
||
781 | hidnplayr | 377 | |
378 | |||
379 | |||
261 | hidnplayr | 380 | pcnet32_reset: |
381 | ; Reset PCNET32 |
||
2434 | Serge | 382 | mov ebp, [io_addr] |
383 | call dword [pcnet32_access.reset] |
||
261 | hidnplayr | 384 | ; set 32bit mode |
2434 | Serge | 385 | mov ebx, 20 |
386 | mov eax, 2 |
||
387 | call dword [pcnet32_access.write_bcr] |
||
261 | hidnplayr | 388 | ; set/reset autoselect bit |
2434 | Serge | 389 | mov ebx, 2 |
390 | call dword [pcnet32_access.read_bcr] |
||
391 | and eax, not 2 |
||
392 | test [pcnet32_private.options], PCNET32_PORT_ASEL |
||
393 | jz .L1 |
||
394 | or eax, 2 |
||
261 | hidnplayr | 395 | .L1: |
2434 | Serge | 396 | call dword [pcnet32_access.write_bcr] |
261 | hidnplayr | 397 | ; Handle full duplex setting |
2434 | Serge | 398 | cmp byte [pcnet32_private.full_duplex], 0 |
399 | je .L2 |
||
400 | mov ebx, 9 |
||
401 | call dword [pcnet32_access.read_bcr] |
||
402 | and eax, not 3 |
||
403 | test [pcnet32_private.options], PCNET32_PORT_FD |
||
404 | jz .L3 |
||
405 | or eax, 1 |
||
406 | cmp [pcnet32_private.options], PCNET32_PORT_FD or PCNET32_PORT_AUI |
||
407 | jne .L4 |
||
408 | or eax, 2 |
||
409 | jmp .L4 |
||
261 | hidnplayr | 410 | .L3: |
2434 | Serge | 411 | test [pcnet32_private.options], PCNET32_PORT_ASEL |
412 | jz .L4 |
||
413 | cmp [pcnet32_private.chip_version], 0x2627 |
||
414 | jne .L4 |
||
415 | or eax, 3 |
||
261 | hidnplayr | 416 | .L4: |
2434 | Serge | 417 | mov ebx, 9 |
418 | call dword [pcnet32_access.write_bcr] |
||
261 | hidnplayr | 419 | .L2: |
420 | ; set/reset GPSI bit |
||
2434 | Serge | 421 | mov ebx, 124 |
422 | call dword [pcnet32_access.read_csr] |
||
423 | mov ecx, [pcnet32_private.options] |
||
424 | and ecx, PCNET32_PORT_PORTSEL |
||
425 | cmp ecx, PCNET32_PORT_GPSI |
||
426 | jne .L5 |
||
427 | or eax, 0x10 |
||
261 | hidnplayr | 428 | .L5: |
2434 | Serge | 429 | call dword [pcnet32_access.write_csr] |
430 | cmp [pcnet32_private.mii], 0 |
||
431 | je .L6 |
||
432 | test [pcnet32_private.options], PCNET32_PORT_ASEL |
||
433 | jnz .L6 |
||
434 | mov ebx, 32 |
||
435 | call dword [pcnet32_access.read_bcr] |
||
436 | and eax, not 0x38 |
||
437 | test [pcnet32_private.options], PCNET32_PORT_FD |
||
438 | jz .L7 |
||
439 | or eax, 0x10 |
||
261 | hidnplayr | 440 | .L7: |
2434 | Serge | 441 | test [pcnet32_private.options], PCNET32_PORT_100 |
442 | jz .L8 |
||
443 | or eax, 0x08 |
||
261 | hidnplayr | 444 | .L8: |
2434 | Serge | 445 | call dword [pcnet32_access.write_bcr] |
446 | jmp .L9 |
||
261 | hidnplayr | 447 | .L6: |
2434 | Serge | 448 | test [pcnet32_private.options], PCNET32_PORT_ASEL |
449 | jz .L9 |
||
450 | mov ebx, 32 |
||
781 | hidnplayr | 451 | ; DEBUGF 1," K : ASEL, enable auto-negotiation\n" |
2434 | Serge | 452 | call dword [pcnet32_access.read_bcr] |
453 | and eax, not 0x98 |
||
454 | or eax, 0x20 |
||
455 | call dword [pcnet32_access.write_bcr] |
||
261 | hidnplayr | 456 | .L9: |
2434 | Serge | 457 | cmp [pcnet32_private.ltint], 0 |
458 | je .L10 |
||
459 | mov ebx, 5 |
||
460 | call dword [pcnet32_access.read_csr] |
||
461 | or eax, (1 shl 14) |
||
462 | call dword [pcnet32_access.write_csr] |
||
261 | hidnplayr | 463 | .L10: |
2434 | Serge | 464 | mov eax, [pcnet32_private.options] |
465 | and eax, PCNET32_PORT_PORTSEL |
||
466 | shl eax, 7 |
||
467 | mov [pcnet32_private.mode], ax |
||
468 | mov [pcnet32_private.filter], dword 0xffffffff |
||
469 | mov [pcnet32_private.filter+4], dword 0xffffffff |
||
470 | call pcnet32_init_ring |
||
471 | mov ebx, 1 |
||
472 | mov eax, pcnet32_private |
||
473 | sub eax, OS_BASE |
||
474 | and eax, 0xffff |
||
475 | call dword [pcnet32_access.write_csr] |
||
476 | mov eax, pcnet32_private |
||
477 | sub eax, OS_BASE |
||
478 | mov ebx, 2 |
||
479 | shr eax, 16 |
||
480 | call dword [pcnet32_access.write_csr] |
||
481 | mov ebx, 4 |
||
482 | mov eax, 0x0915 |
||
483 | call dword [pcnet32_access.write_csr] |
||
484 | mov ebx, 0 |
||
485 | mov eax, 1 |
||
486 | call dword [pcnet32_access.write_csr] |
||
487 | mov ecx, 100 |
||
261 | hidnplayr | 488 | .L11: |
2434 | Serge | 489 | xor ebx, ebx |
490 | call dword [pcnet32_access.read_csr] |
||
491 | test ax, 0x100 |
||
492 | jnz .L12 |
||
493 | loop .L11 |
||
261 | hidnplayr | 494 | .L12: |
781 | hidnplayr | 495 | ; DEBUGF 1," K : hardware reset\n" |
2434 | Serge | 496 | xor ebx, ebx |
497 | mov eax, 0x0002 |
||
498 | call dword [pcnet32_access.write_csr] |
||
499 | xor ebx, ebx |
||
500 | call dword [pcnet32_access.read_csr] |
||
781 | hidnplayr | 501 | ; DEBUGF 1," K : PCNET reset complete\n" |
2434 | Serge | 502 | ret |
781 | hidnplayr | 503 | |
504 | |||
505 | |||
261 | hidnplayr | 506 | pcnet32_adjust_pci_device: |
507 | ;*******Get current setting************************ |
||
2434 | Serge | 508 | mov al, 2 ;read a word |
509 | mov bh, [pci_dev] |
||
510 | mov ah, [pci_bus] |
||
511 | mov bl, 0x04 ;from command Register |
||
512 | call pci_read_reg |
||
261 | hidnplayr | 513 | ;******see if its already set as bus master******** |
2434 | Serge | 514 | mov bx, ax |
515 | and bx, 5 |
||
516 | cmp bx, 5 |
||
517 | je pcnet32_adjust_pci_device_Latency |
||
261 | hidnplayr | 518 | ;******Make card a bus master******* |
2434 | Serge | 519 | mov cx, ax ;value to write |
520 | mov bh, [pci_dev] |
||
521 | mov al, 2 ;write a word |
||
522 | or cx, 5 |
||
523 | mov ah, [pci_bus] |
||
524 | mov bl, 0x04 ;to command register |
||
525 | call pci_write_reg |
||
261 | hidnplayr | 526 | ;******Check latency setting*********** |
527 | pcnet32_adjust_pci_device_Latency: |
||
528 | ;*******Get current latency setting************************ |
||
529 | ; mov al, 1 ;read a byte |
||
530 | ; mov bh, [pci_dev] |
||
531 | ; mov ah, [pci_bus] |
||
532 | ; mov bl, 0x0D ;from Lantency Timer Register |
||
533 | ; call pci_read_reg |
||
534 | ;******see if its aat least 64 clocks******** |
||
535 | ; cmp ax,64 |
||
536 | ; jge pcnet32_adjust_pci_device_Done |
||
537 | ;******Set latency to 32 clocks******* |
||
538 | ; mov cx, 64 ;value to write |
||
539 | ; mov bh, [pci_dev] |
||
540 | ; mov al, 1 ;write a byte |
||
541 | ; mov ah, [pci_bus] |
||
542 | ; mov bl, 0x0D ;to Lantency Timer Register |
||
543 | ; call pci_write_reg |
||
544 | ;******Check latency setting*********** |
||
545 | pcnet32_adjust_pci_device_Done: |
||
2434 | Serge | 546 | ret |
781 | hidnplayr | 547 | |
548 | |||
549 | |||
550 | |||
261 | hidnplayr | 551 | pcnet32_probe: |
2434 | Serge | 552 | mov ebp, [io_addr] |
553 | call pcnet32_wio_reset |
||
554 | xor ebx, ebx |
||
555 | call pcnet32_wio_read_csr |
||
556 | cmp eax, 4 |
||
557 | jne .try_dwio |
||
558 | call pcnet32_wio_check |
||
559 | and al, al |
||
560 | jz .try_dwio |
||
781 | hidnplayr | 561 | ; DEBUGF 1," K : Using WIO\n" |
2434 | Serge | 562 | mov esi, pcnet32_wio |
563 | jmp .L1 |
||
261 | hidnplayr | 564 | .try_dwio: |
2434 | Serge | 565 | call pcnet32_dwio_reset |
566 | xor ebx, ebx |
||
567 | call pcnet32_dwio_read_csr |
||
568 | cmp eax, 4 |
||
569 | jne .no_dev |
||
570 | call pcnet32_dwio_check |
||
571 | and al, al |
||
572 | jz .no_dev |
||
781 | hidnplayr | 573 | ; DEBUGF 1," K : Using DWIO\n" |
2434 | Serge | 574 | mov esi, pcnet32_dwio |
575 | jmp .L1 |
||
261 | hidnplayr | 576 | .no_dev: |
781 | hidnplayr | 577 | DEBUGF 1," K : PCNET32 not found\n" |
2434 | Serge | 578 | ret |
261 | hidnplayr | 579 | .L1: |
2434 | Serge | 580 | mov edi, pcnet32_access |
581 | mov ecx, 7 |
||
582 | cld |
||
583 | rep movsd |
||
584 | mov ebx, 88 |
||
585 | call dword [pcnet32_access.read_csr] |
||
586 | mov ecx, eax |
||
587 | mov ebx, 89 |
||
588 | call dword [pcnet32_access.read_csr] |
||
589 | shl eax, 16 |
||
590 | or eax, ecx |
||
591 | mov ecx, eax |
||
592 | and ecx, 0xfff |
||
593 | cmp ecx, 3 |
||
594 | jne .no_dev |
||
595 | shr eax, 12 |
||
596 | and eax, 0xffff |
||
597 | mov [pcnet32_private.chip_version], eax |
||
781 | hidnplayr | 598 | ; DEBUGF 1," K : PCNET32 chip version OK\n" |
2434 | Serge | 599 | mov [pcnet32_private.fdx], 0 |
600 | mov [pcnet32_private.mii], 0 |
||
601 | mov [pcnet32_private.fset], 0 |
||
602 | mov [pcnet32_private.dxsuflo], 0 |
||
603 | mov [pcnet32_private.ltint], 0 |
||
604 | mov eax, [pcnet32_private.chip_version] |
||
605 | cmp eax, 0x2420 |
||
606 | je .L2 |
||
607 | cmp eax, 0x2430 |
||
608 | je .L3 |
||
609 | cmp eax, 0x2621 |
||
610 | je .L4 |
||
611 | cmp eax, 0x2623 |
||
612 | je .L5 |
||
613 | cmp eax, 0x2624 |
||
614 | je .L6 |
||
615 | cmp eax, 0x2625 |
||
616 | je .L7 |
||
617 | cmp eax, 0x2626 |
||
618 | je .L8 |
||
619 | cmp eax, 0x2627 |
||
620 | je .L9 |
||
781 | hidnplayr | 621 | DEBUGF 1," K : Invalid chip rev\n" |
2434 | Serge | 622 | jmp .no_dev |
261 | hidnplayr | 623 | .L2: |
781 | hidnplayr | 624 | ; DEBUGF 1," K : PCnet/PCI 79C970\n" |
2434 | Serge | 625 | jmp .L10 |
261 | hidnplayr | 626 | .L3: |
781 | hidnplayr | 627 | ; DEBUGF 1," K : PCnet/PCI 79C970\n" |
2434 | Serge | 628 | jmp .L10 |
261 | hidnplayr | 629 | .L4: |
781 | hidnplayr | 630 | ; DEBUGF 1," K : PCnet/PCI II 79C970A\n" |
2434 | Serge | 631 | mov [pcnet32_private.fdx], 1 |
632 | jmp .L10 |
||
261 | hidnplayr | 633 | .L5: |
781 | hidnplayr | 634 | ; DEBUGF 1," K : PCnet/FAST 79C971\n" |
2434 | Serge | 635 | mov [pcnet32_private.fdx], 1 |
636 | mov [pcnet32_private.mii], 1 |
||
637 | mov [pcnet32_private.fset], 1 |
||
638 | mov [pcnet32_private.ltint], 1 |
||
639 | jmp .L10 |
||
261 | hidnplayr | 640 | .L6: |
781 | hidnplayr | 641 | ; DEBUGF 1," K : PCnet/FAST+ 79C972\n" |
2434 | Serge | 642 | mov [pcnet32_private.fdx], 1 |
643 | mov [pcnet32_private.mii], 1 |
||
644 | mov [pcnet32_private.fset], 1 |
||
645 | jmp .L10 |
||
261 | hidnplayr | 646 | .L7: |
781 | hidnplayr | 647 | ; DEBUGF 1," K : PCnet/FAST III 79C973\n" |
2434 | Serge | 648 | mov [pcnet32_private.fdx], 1 |
649 | mov [pcnet32_private.mii], 1 |
||
650 | jmp .L10 |
||
261 | hidnplayr | 651 | .L8: |
781 | hidnplayr | 652 | ; DEBUGF 1," K : PCnet/Home 79C978\n" |
2434 | Serge | 653 | mov [pcnet32_private.fdx], 1 |
654 | mov ebx, 49 |
||
655 | call dword [pcnet32_access.read_bcr] |
||
656 | call dword [pcnet32_access.write_bcr] |
||
657 | jmp .L10 |
||
261 | hidnplayr | 658 | .L9: |
781 | hidnplayr | 659 | ; DEBUGF 1," K : PCnet/FAST III 79C975\n" |
2434 | Serge | 660 | mov [pcnet32_private.fdx], 1 |
661 | mov [pcnet32_private.mii], 1 |
||
261 | hidnplayr | 662 | .L10: |
2434 | Serge | 663 | cmp [pcnet32_private.fset], 1 |
664 | jne .L11 |
||
665 | mov ebx, 18 |
||
666 | call dword [pcnet32_access.read_bcr] |
||
667 | or eax, 0x800 |
||
668 | call dword [pcnet32_access.write_bcr] |
||
669 | mov ebx, 80 |
||
670 | call dword [pcnet32_access.read_csr] |
||
671 | and eax, 0xc00 |
||
672 | or eax, 0xc00 |
||
673 | call dword [pcnet32_access.write_csr] |
||
674 | mov [pcnet32_private.dxsuflo], 1 |
||
675 | mov [pcnet32_private.ltint], 1 |
||
261 | hidnplayr | 676 | .L11: |
677 | ; read MAC |
||
2434 | Serge | 678 | mov edi, node_addr |
679 | mov edx, ebp |
||
680 | mov ecx, 6 |
||
261 | hidnplayr | 681 | .Lmac: |
2434 | Serge | 682 | in al, dx |
683 | stosb |
||
684 | inc edx |
||
685 | loop .Lmac |
||
781 | hidnplayr | 686 | ; DEBUGF 1," K : MAC read\n" |
2434 | Serge | 687 | call pcnet32_adjust_pci_device |
781 | hidnplayr | 688 | ; DEBUGF 1," K : PCI done\n" |
2434 | Serge | 689 | mov eax, PCNET32_PORT_ASEL |
690 | mov [pcnet32_private.options], eax |
||
691 | mov [pcnet32_private.mode], word 0x0003 |
||
692 | mov [pcnet32_private.tlen_rlen], word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
||
693 | mov esi, node_addr |
||
694 | mov edi, pcnet32_private.phys_addr |
||
695 | cld |
||
696 | movsd |
||
697 | movsw |
||
698 | mov [pcnet32_private.filter], dword 0 |
||
699 | mov [pcnet32_private.filter+4], dword 0 |
||
700 | mov eax, pcnet32_rx_ring |
||
701 | sub eax, OS_BASE |
||
702 | mov dword [pcnet32_private.rx_ring], eax |
||
781 | hidnplayr | 703 | |
2434 | Serge | 704 | mov eax, pcnet32_tx_ring |
705 | sub eax, OS_BASE |
||
706 | mov dword [pcnet32_private.tx_ring], eax |
||
781 | hidnplayr | 707 | ; DEBUGF 1," K : Switching to 32\n" |
2434 | Serge | 708 | mov ebx, 20 |
709 | mov eax, 2 |
||
710 | call dword [pcnet32_access.write_bcr] |
||
711 | mov ebx, 1 |
||
712 | mov eax, (pcnet32_private and 0xffff) |
||
713 | call dword [pcnet32_access.write_csr] |
||
714 | mov ebx, 2 |
||
715 | mov eax, (pcnet32_private shr 16) and 0xffff |
||
716 | call dword [pcnet32_access.write_csr] |
||
717 | mov ebx, 0 |
||
718 | mov eax, 1 |
||
719 | call dword [pcnet32_access.write_csr] |
||
720 | mov esi, 1 |
||
721 | call delay_ms |
||
722 | call pcnet32_reset |
||
723 | mov eax, [pci_data] |
||
724 | mov [eth_status], eax |
||
725 | ret |
||
781 | hidnplayr | 726 | |
727 | |||
728 | |||
261 | hidnplayr | 729 | pcnet32_poll: |
2434 | Serge | 730 | xor ax, ax |
731 | mov [eth_rx_data_len], ax |
||
732 | mov eax, [pcnet32_private.cur_rx] |
||
733 | and eax, PCNET32_RX_RING_MOD_MASK |
||
734 | mov ebx, eax |
||
735 | imul esi, eax, PCNET32_PKT_BUF_SZ |
||
736 | add esi, pcnet32_rxb |
||
737 | shl ebx, 4 |
||
738 | add ebx, pcnet32_rx_ring |
||
739 | mov cx, [ebx+pcnet32_rx_head.status] |
||
740 | test cx, 0x8000 |
||
741 | jnz .L1 |
||
742 | cmp ch, 3 |
||
743 | jne .L1 |
||
744 | mov ecx, [ebx+pcnet32_rx_head.msg_length] |
||
745 | and ecx, 0xfff |
||
746 | sub ecx, 4 |
||
747 | mov [eth_rx_data_len], cx |
||
781 | hidnplayr | 748 | ; DEBUGF 1," K : PCNETRX: %ub\n",cx |
2434 | Serge | 749 | push ecx |
750 | shr ecx, 2 |
||
751 | mov edi, Ether_buffer |
||
752 | cld |
||
753 | rep movsd |
||
754 | pop ecx |
||
755 | and ecx, 3 |
||
756 | rep movsb |
||
757 | mov [ebx+pcnet32_rx_head.buf_length], word PCNET32_PKT_BUF_SZ_NEG |
||
758 | or [ebx+pcnet32_rx_head.status], word 0x8000 |
||
759 | inc [pcnet32_private.cur_rx] |
||
261 | hidnplayr | 760 | .L1: |
2434 | Serge | 761 | ret |
781 | hidnplayr | 762 | |
763 | |||
764 | |||
765 | |||
261 | hidnplayr | 766 | ; Pointer to 48 bit destination address in edi |
767 | ; Type of packet in bx |
||
768 | ; size of packet in ecx |
||
769 | ; pointer to packet data in esi |
||
770 | pcnet32_xmit: |
||
2434 | Serge | 771 | push edi |
772 | push esi |
||
773 | push ebx |
||
774 | push ecx |
||
781 | hidnplayr | 775 | ; DEBUGF 1," K : PCNETTX\n" |
2434 | Serge | 776 | mov esi, edi |
777 | mov edi, [pcnet32_private.cur_tx] |
||
778 | imul edi, PCNET32_PKT_BUF_SZ |
||
779 | add edi, pcnet32_txb; edi=ptxb |
||
780 | mov eax, edi |
||
781 | cld ; copy MAC |
||
782 | movsd |
||
783 | movsw |
||
784 | mov esi, node_addr |
||
785 | cld |
||
786 | movsd |
||
787 | movsw |
||
788 | mov [edi], bx |
||
789 | add edi, 2 |
||
790 | mov esi, [esp+8] |
||
791 | mov ecx, [esp] |
||
792 | push ecx |
||
793 | shr ecx, 2 |
||
794 | cld |
||
795 | rep movsd |
||
796 | pop ecx |
||
797 | and ecx, 3 |
||
798 | rep movsb |
||
261 | hidnplayr | 799 | ; mov ecx,[esp] |
800 | ; add ecx,14 ; ETH_HLEN |
||
801 | ; xor eax,eax |
||
802 | ; pad to min length (60=ETH_ZLEN) |
||
803 | ; cmp ecx,60 |
||
804 | ; jae .L1 |
||
805 | ; sub ecx,60 |
||
806 | ; cld |
||
807 | ; rep stosb |
||
808 | ;.L1: |
||
2434 | Serge | 809 | mov edi, pcnet32_tx_ring+0; entry=0 |
810 | mov ecx, [esp] |
||
811 | add ecx, 14 |
||
812 | cmp cx, 60 |
||
813 | jae .L1 |
||
814 | mov cx, 60 |
||
261 | hidnplayr | 815 | .L1: |
2434 | Serge | 816 | neg cx |
817 | mov [edi+pcnet32_tx_head.length], cx |
||
818 | mov [edi+pcnet32_tx_head.misc], dword 0 |
||
819 | sub eax, OS_BASE |
||
820 | mov [edi+pcnet32_tx_head.base], eax |
||
821 | mov [edi+pcnet32_tx_head.status], word 0x8300 |
||
261 | hidnplayr | 822 | ; trigger an immediate send poll |
2434 | Serge | 823 | mov ebx, 0 |
824 | mov eax, 0x0008; 0x0048 |
||
825 | mov ebp, [io_addr] |
||
826 | call dword [pcnet32_access.write_csr] |
||
827 | mov dword [pcnet32_private.cur_tx], 0 |
||
261 | hidnplayr | 828 | ; wait for TX to complete |
2434 | Serge | 829 | mov ecx, [timer_ticks];[0xfdf0] |
830 | add ecx, 100 |
||
261 | hidnplayr | 831 | .L2: |
2434 | Serge | 832 | mov ax, [edi+pcnet32_tx_head.status] |
833 | test ax, 0x8000 |
||
834 | jz .L3 |
||
835 | cmp ecx, [timer_ticks];[0xfdf0] |
||
836 | jb .L4 |
||
837 | mov esi, 10 |
||
838 | call delay_ms |
||
839 | jnz .L2 |
||
261 | hidnplayr | 840 | .L4: |
781 | hidnplayr | 841 | DEBUGF 1," K : PCNET: Send timeout\n" |
261 | hidnplayr | 842 | .L3: |
2434 | Serge | 843 | mov dword [edi+pcnet32_tx_head.base], 0 |
844 | pop ecx |
||
845 | pop ebx |
||
846 | pop esi |
||
847 | pop edi |
||
848 | ret |