Subversion Repositories Kolibri OS

Rev

Rev 1263 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1196 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                  ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.     ;;
4
;; Distributed under terms of the GNU General Public License        ;;
5
;;                                                                  ;;
6
;;          GNU GENERAL PUBLIC LICENSE                              ;;
7
;;             Version 2, June 1991                                 ;;
8
;;                                                                  ;;
9
;; Status: under construction                                       ;;
10
;;                                                                  ;;
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
 
1251 clevermous 13
; $Revision: 1377 $
1196 hidnplayr 14
 
15
format MS COFF
16
 
17
	API_VERSION		equ 0x01000100
18
 
19
	DEBUG			equ 1
20
	__DEBUG__		equ 1
21
	__DEBUG_LEVEL__ 	equ 1
22
 
23
MAX_PCNET equ 4
24
MAX_ETH_FRAME_SIZE equ 1514
25
 
26
include 'proc32.inc'
27
include 'imports.inc'
28
include 'fdo.inc'
29
 
30
OS_BASE 	equ 0;
31
new_app_base	equ 0x60400000
32
PROC_BASE	equ OS_BASE+0x0080000
33
 
34
public START
35
public service_proc
36
public version
37
 
38
struc IOCTL {
39
      .handle		dd ?
40
      .io_code		dd ?
41
      .input		dd ?
42
      .inp_size 	dd ?
43
      .output		dd ?
44
      .out_size 	dd ?
45
}
46
 
47
virtual at 0
48
  IOCTL IOCTL
49
end virtual
50
 
51
struc ETH_DEVICE {
52
; pointers to procedures
53
      .unload		dd ?
54
      .reset		dd ?
55
      .transmit 	dd ?
56
      .set_MAC		dd ?
57
      .get_MAC		dd ?
58
      .set_mode 	dd ?
59
      .get_mode 	dd ?
60
; status
61
      .bytes_tx 	dq ?
62
      .bytes_rx 	dq ?
63
      .packets_tx	dd ?
64
      .packets_rx	dd ?
65
      .mode		dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
66
      .name		dd ?
67
      .mac		dp ?
68
; device specific
69
 
70
      .rx_buffer	dd ?
71
      .tx_buffer	dd ?
72
 
73
      .io_addr		dd ?
74
      .irq_line 	db ?
75
      .pci_bus		db ?
76
      .pci_dev		db ?
77
 
1201 clevermous 78
	; The following fields up to .tx_ring_phys inclusive form
79
	; initialization block for hardware; do not modify
1206 hidnplayr 80
	align 4 ; initialization block must be dword-aligned
1196 hidnplayr 81
      .private:
82
      .mode_		dw ?
83
      .tlen_rlen	dw ?
1201 clevermous 84
      .phys_addr	dp ?
1196 hidnplayr 85
      .reserved 	dw ?
86
      .filter		dq ?
1201 clevermous 87
      .rx_ring_phys	dd ?
88
      .tx_ring_phys	dd ?
1196 hidnplayr 89
      .rx_ring		dd ?
90
      .tx_ring		dd ?
91
      .cur_rx		db ?
92
      .cur_tx		db ?
93
      .dirty_rx 	dd ?
94
      .dirty_tx 	dd ?
95
      .tx_full		db ?
96
      .options		dd ?
97
      .full_duplex	db ?
98
      .chip_version	dd ?
99
      .mii		db ?
100
      .ltint		db ?
101
      .dxsuflo		db ?
102
      .fset		db ?
103
      .fdx		db ?
104
 
105
      .access_read_csr		dd ?
106
      .access_write_csr 	dd ?
107
      .access_read_bcr		dd ?
108
      .access_write_bcr 	dd ?
109
      .access_read_rap		dd ?
110
      .access_write_rap 	dd ?
111
      .access_reset		dd ?
112
 
113
      .size:
114
 
115
}
116
 
117
virtual at 0
118
 device ETH_DEVICE
119
end virtual
120
 
121
struc buf_head {
122
	.base		dd ?
123
	.length 	dw ?
124
	.status 	dw ?
1201 clevermous 125
	.msg_length	dw ?
126
	.misc		dw ?
1196 hidnplayr 127
	.reserved	dd ?
128
 
129
	.size:
130
}
131
 
132
virtual at 0
133
 buf_head buf_head
134
end virtual
135
 
136
struc rx_desc_2 { ; Swstyle 2
137
 
138
	.rbadr		dd ?
139
	.status 	dd ?
140
	.rfrtag 	dd ?
141
 
142
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
143
; |Address |  31 |  30 |  29 |  28 |  27 |  26 |  25 |  24 |  23 |  22 |  21 |  20 |19-16|15-12|11-0 |
144
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
145
; |CRDA+00h|                                       RBADR[31:0]                                       |
146
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
147
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | PAM |LAFM | BAM | RES |1111 |BCNT |
148
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
149
; |CRDA+08h| RES |                              RFRTAG[14:0]                             |0000 |MCNT |
150
; +--------+-----+-----------------------------------------------------------------------+-----+-----+
151
; |CRDA+0Ch|                                    USER SPACE                               |     |     |
152
; +--------+-----------------------------------------------------------------------------+-----+-----+
153
 
154
}
155
 
156
struc rx_desc_3 {  ; Swstyle 3
157
 
158
	.mcnt		dd ?
159
	.status 	dd ?
160
	.rbadr		dd ?
161
 
162
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
163
; |Address |  31 |  30 |  29 |  28 |  27 |  26 |  25 |  24 |  23 |22-16|15-12|11-0 |
164
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
165
; |CRDA+00h|                      RES                      | RES | RES |0000 |MCNT |
166
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
167
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | RES |1111 |BCNT |
168
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
169
; |CRDA+08h|                            RBADR[31:0]                                |
170
; +--------+-----------------------------------------------------------------------+
171
; |CRDA+0Ch|                             USER SPACE                                |
172
; +--------+-----------------------------------------------------------------------+
173
 
174
}
175
 
176
virtual at 0
177
 rx_desc rx_desc_2
178
end virtual
179
 
180
 
181
; PCI Bus defines
182
 
183
	PCI_HEADER_TYPE 	      equ 0x0e	;8 bit
184
	PCI_BASE_ADDRESS_0	      equ 0x10	;32 bit
185
	PCI_BASE_ADDRESS_5	      equ 0x24	;32 bits
186
	PCI_BASE_ADDRESS_SPACE_IO     equ 0x01
187
	PCI_VENDOR_ID		      equ 0x00	;16 bit
188
	PCI_BASE_ADDRESS_IO_MASK      equ 0xFFFFFFFC
189
 
190
	PCNET_PORT_AUI		      equ 0x00
191
	PCNET_PORT_10BT 	      equ 0x01
192
	PCNET_PORT_GPSI 	      equ 0x02
193
	PCNET_PORT_MII		      equ 0x03
194
	PCNET_PORT_PORTSEL	      equ 0x03
195
	PCNET_PORT_ASEL 	      equ 0x04
196
	PCNET_PORT_100		      equ 0x40
197
	PCNET_PORT_FD		      equ 0x80
198
 
199
	PCNET_DMA_MASK		      equ 0xffffffff
200
 
1201 clevermous 201
	PCNET_LOG_TX_BUFFERS	      equ 2
1196 hidnplayr 202
	PCNET_LOG_RX_BUFFERS	      equ 2
203
 
204
	PCNET_TX_RING_SIZE	      equ 4
205
	PCNET_TX_RING_MOD_MASK	      equ (PCNET_TX_RING_SIZE-1)
1201 clevermous 206
	PCNET_TX_RING_LEN_BITS	      equ (PCNET_LOG_TX_BUFFERS shl 12)
1196 hidnplayr 207
 
208
	PCNET_RX_RING_SIZE	      equ 4
209
	PCNET_RX_RING_MOD_MASK	      equ (PCNET_RX_RING_SIZE-1)
210
	PCNET_RX_RING_LEN_BITS	      equ (PCNET_LOG_RX_BUFFERS shl 4)
211
 
212
	PCNET_PKT_BUF_SZ	      equ 1544
213
	PCNET_PKT_BUF_SZ_NEG	      equ 0xf9f8
214
 
215
	PCNET_WIO_RDP		      equ 0x10
216
	PCNET_WIO_RAP		      equ 0x12
217
	PCNET_WIO_RESET 	      equ 0x14
218
	PCNET_WIO_BDP		      equ 0x16
219
	PCNET_DWIO_RDP		      equ 0x10
220
	PCNET_DWIO_RAP		      equ 0x14
221
	PCNET_DWIO_RESET	      equ 0x18
222
	PCNET_DWIO_BDP		      equ 0x1C
223
	PCNET_TOTAL_SIZE	      equ 0x20
224
 
225
; CSR registers
226
 
227
	PCNET_CSR_CSR		      equ 0x00
228
	PCNET_CSR_IAB0		      equ 0x01
229
	PCNET_CSR_IAB1		      equ 0x02
230
	PCNET_CSR_IMR		      equ 0x03
231
	PCNET_CSR_TFEAT 	      equ 0x04
232
	PCNET_CSR_EXTCTL1	      equ 0x05
233
	PCNET_CSR_DTBLLEN	      equ 0x06
234
	PCNET_CSR_EXTCTL2	      equ 0x07
235
	PCNET_CSR_MAR0		      equ 0x08
236
	PCNET_CSR_MAR1		      equ 0x09
237
	PCNET_CSR_MAR2		      equ 0x0A
238
	PCNET_CSR_MAR3		      equ 0x0B
239
	PCNET_CSR_PAR0		      equ 0x0C
240
	PCNET_CSR_PAR1		      equ 0x0D
241
	PCNET_CSR_PAR2		      equ 0x0E
242
	PCNET_CSR_MODE		      equ 0x0F
243
	PCNET_CSR_RXADDR0	      equ 0x18
244
	PCNET_CSR_RXADDR1	      equ 0x19
245
	PCNET_CSR_TXADDR0	      equ 0x1E
246
	PCNET_CSR_TXADDR1	      equ 0x1F
247
	PCNET_CSR_TXPOLL	      equ 0x2F
248
	PCNET_CSR_RXPOLL	      equ 0x31
249
	PCNET_CSR_RXRINGLEN	      equ 0x4C
250
	PCNET_CSR_TXRINGLEN	      equ 0x4E
251
	PCNET_CSR_DMACTL	      equ 0x50
252
	PCNET_CSR_BUSTIMER	      equ 0x52
253
	PCNET_CSR_MEMERRTIMEO	      equ 0x64
254
	PCNET_CSR_ONNOWMISC	      equ 0x74
255
	PCNET_CSR_ADVFEAT	      equ 0x7A
256
	PCNET_CSR_MACCFG	      equ 0x7D
257
	PCNET_CSR_CHIPID0	      equ 0x58
258
	PCNET_CSR_CHIPID1	      equ 0x59
259
 
260
; Control and Status Register (CSR0)
261
 
262
	PCNET_CSR_INIT		      equ 1 shl 0
263
	PCNET_CSR_START 	      equ 1 shl 1
264
	PCNET_CSR_STOP		      equ 1 shl 2
265
	PCNET_CSR_TX		      equ 1 shl 3
266
	PCNET_CSR_TXON		      equ 1 shl 4
267
	PCNET_CSR_RXON		      equ 1 shl 5
268
	PCNET_CSR_INTEN 	      equ 1 shl 6
269
	PCNET_CSR_INTR		      equ 1 shl 7
270
	PCNET_CSR_IDONE 	      equ 1 shl 8
271
	PCNET_CSR_TINT		      equ 1 shl 9
272
	PCNET_CSR_RINT		      equ 1 shl 10
273
	PCNET_CSR_MERR		      equ 1 shl 11
274
	PCNET_CSR_MISS		      equ 1 shl 12
275
	PCNET_CSR_CERR		      equ 1 shl 13
276
 
277
; Interrupt masks and deferral control (CSR3)
278
 
279
	PCNET_IMR_BSWAP 	      equ 0x0004
280
	PCNET_IMR_ENMBA 	      equ 0x0008  ; enable modified backoff alg
281
	PCNET_IMR_DXMT2PD	      equ 0x0010
282
	PCNET_IMR_LAPPEN	      equ 0x0020  ; lookahead packet processing enb
283
	PCNET_IMR_DXSUFLO	      equ 0x0040  ; disable TX stop on underflow
284
	PCNET_IMR_IDONE 	      equ 0x0100
285
	PCNET_IMR_TINT		      equ 0x0200
286
	PCNET_IMR_RINT		      equ 0x0400
287
	PCNET_IMR_MERR		      equ 0x0800
288
	PCNET_IMR_MISS		      equ 0x1000
289
 
290
	PCNET_IMR		      equ PCNET_IMR_TINT+PCNET_IMR_RINT+PCNET_IMR_IDONE+PCNET_IMR_MERR+PCNET_IMR_MISS
291
 
292
; Test and features control (CSR4)
293
 
294
	PCNET_TFEAT_TXSTRTMASK	      equ 0x0004
295
	PCNET_TFEAT_TXSTRT	      equ 0x0008
296
	PCNET_TFEAT_RXCCOFLOWM	      equ 0x0010  ; Rx collision counter oflow
297
	PCNET_TFEAT_RXCCOFLOW	      equ 0x0020
298
	PCNET_TFEAT_UINT	      equ 0x0040
299
	PCNET_TFEAT_UINTREQ	      equ 0x0080
300
	PCNET_TFEAT_MISSOFLOWM	      equ 0x0100
301
	PCNET_TFEAT_MISSOFLOW	      equ 0x0200
302
	PCNET_TFEAT_STRIP_FCS	      equ 0x0400
303
	PCNET_TFEAT_PAD_TX	      equ 0x0800
304
	PCNET_TFEAT_TXDPOLL	      equ 0x1000
305
	PCNET_TFEAT_DMAPLUS	      equ 0x4000
306
 
307
; Extended control and interrupt 1 (CSR5)
308
 
309
	PCNET_EXTCTL1_SPND	      equ 0x0001  ; suspend
310
	PCNET_EXTCTL1_MPMODE	      equ 0x0002  ; magic packet mode
311
	PCNET_EXTCTL1_MPENB	      equ 0x0004  ; magic packet enable
312
	PCNET_EXTCTL1_MPINTEN	      equ 0x0008  ; magic packet interrupt enable
313
	PCNET_EXTCTL1_MPINT	      equ 0x0010  ; magic packet interrupt
314
	PCNET_EXTCTL1_MPPLBA	      equ 0x0020  ; magic packet phys. logical bcast
315
	PCNET_EXTCTL1_EXDEFEN	      equ 0x0040  ; excessive deferral interrupt enb.
316
	PCNET_EXTCTL1_EXDEF	      equ 0x0080  ; excessive deferral interrupt
317
	PCNET_EXTCTL1_SINTEN	      equ 0x0400  ; system interrupt enable
318
	PCNET_EXTCTL1_SINT	      equ 0x0800  ; system interrupt
319
	PCNET_EXTCTL1_LTINTEN	      equ 0x4000  ; last TX interrupt enb
320
	PCNET_EXTCTL1_TXOKINTD	      equ 0x8000  ; TX OK interrupt disable
321
 
322
; RX/TX descriptor len (CSR6)
323
 
324
	PCNET_DTBLLEN_RLEN	      equ 0x0F00
325
	PCNET_DTBLLEN_TLEN	      equ 0xF000
326
 
327
; Extended control and interrupt 2 (CSR7)
328
 
329
	PCNET_EXTCTL2_MIIPDTINTE      equ 0x0001
330
	PCNET_EXTCTL2_MIIPDTINT       equ 0x0002
331
	PCNET_EXTCTL2_MCCIINTE	      equ 0x0004
332
	PCNET_EXTCTL2_MCCIINT	      equ 0x0008
333
	PCNET_EXTCTL2_MCCINTE	      equ 0x0010
334
	PCNET_EXTCTL2_MCCINT	      equ 0x0020
335
	PCNET_EXTCTL2_MAPINTE	      equ 0x0040
336
	PCNET_EXTCTL2_MAPINT	      equ 0x0080
337
	PCNET_EXTCTL2_MREINTE	      equ 0x0100
338
	PCNET_EXTCTL2_MREINT	      equ 0x0200
339
	PCNET_EXTCTL2_STINTE	      equ 0x0400
340
	PCNET_EXTCTL2_STINT	      equ 0x0800
341
	PCNET_EXTCTL2_RXDPOLL	      equ 0x1000
342
	PCNET_EXTCTL2_RDMD	      equ 0x2000
343
	PCNET_EXTCTL2_RXFRTG	      equ 0x4000
344
	PCNET_EXTCTL2_FASTSPNDE       equ 0x8000
345
 
346
; Mode (CSR15)
347
 
348
	PCNET_MODE_RXD		      equ 0x0001  ; RX disable
349
	PCNET_MODE_TXD		      equ 0x0002  ; TX disable
350
	PCNET_MODE_LOOP 	      equ 0x0004  ; loopback enable
351
	PCNET_MODE_TXCRCD	      equ 0x0008
352
	PCNET_MODE_FORCECOLL	      equ 0x0010
353
	PCNET_MODE_RETRYD	      equ 0x0020
354
	PCNET_MODE_INTLOOP	      equ 0x0040
355
	PCNET_MODE_PORTSEL	      equ 0x0180
356
	PCNET_MODE_RXVPAD	      equ 0x2000
357
	PCNET_MODE_RXNOBROAD	      equ 0x4000
358
	PCNET_MODE_PROMISC	      equ 0x8000
359
 
360
; BCR (Bus Control Registers)
361
 
362
	PCNET_BCR_MMRA		      equ 0x00	  ; Master Mode Read Active
363
	PCNET_BCR_MMW		      equ 0x01	  ; Master Mode Write Active
364
	PCNET_BCR_MISCCFG	      equ 0x02
365
	PCNET_BCR_LED0		      equ 0x04
366
	PCNET_BCR_LED1		      equ 0x05
367
	PCNET_BCR_LED2		      equ 0x06
368
	PCNET_BCR_LED3		      equ 0x07
369
	PCNET_BCR_DUPLEX	      equ 0x09
370
	PCNET_BCR_BUSCTL	      equ 0x12
371
	PCNET_BCR_EECTL 	      equ 0x13
372
	PCNET_BCR_SSTYLE	      equ 0x14
373
	PCNET_BCR_PCILAT	      equ 0x16
374
	PCNET_BCR_PCISUBVENID	      equ 0x17
375
	PCNET_BCR_PCISUBSYSID	      equ 0x18
376
	PCNET_BCR_SRAMSIZE	      equ 0x19
377
	PCNET_BCR_SRAMBOUND	      equ 0x1A
378
	PCNET_BCR_SRAMCTL	      equ 0x1B
379
	PCNET_BCR_MIICTL	      equ 0x20
380
	PCNET_BCR_MIIADDR	      equ 0x21
381
	PCNET_BCR_MIIDATA	      equ 0x22
382
	PCNET_BCR_PCIVENID	      equ 0x23
383
	PCNET_BCR_PCIPCAP	      equ 0x24
384
	PCNET_BCR_DATA0 	      equ 0x25
385
	PCNET_BCR_DATA1 	      equ 0x26
386
	PCNET_BCR_DATA2 	      equ 0x27
387
	PCNET_BCR_DATA3 	      equ 0x28
388
	PCNET_BCR_DATA4 	      equ 0x29
389
	PCNET_BCR_DATA5 	      equ 0x2A
390
	PCNET_BCR_DATA6 	      equ 0x2B
391
	PCNET_BCR_DATA7 	      equ 0x2C
392
	PCNET_BCR_ONNOWPAT0	      equ 0x2D
393
	PCNET_BCR_ONNOWPAT1	      equ 0x2E
394
	PCNET_BCR_ONNOWPAT2	      equ 0x2F
395
	PCNET_BCR_PHYSEL	      equ 0x31
396
 
397
; RX status register
398
 
399
	PCNET_RXSTAT_BPE	      equ 0x0080  ; bus parity error
400
	PCNET_RXSTAT_ENP	      equ 0x0100  ; end of packet
401
	PCNET_RXSTAT_STP	      equ 0x0200  ; start of packet
402
	PCNET_RXSTAT_BUFF	      equ 0x0400  ; buffer error
403
	PCNET_RXSTAT_CRC	      equ 0x0800  ; CRC error
404
	PCNET_RXSTAT_OFLOW	      equ 0x1000  ; rx overrun
405
	PCNET_RXSTAT_FRAM	      equ 0x2000  ; framing error
406
	PCNET_RXSTAT_ERR	      equ 0x4000  ; error summary
407
	PCNET_RXSTAT_OWN	      equ 0x8000
408
 
409
; TX status register
410
 
411
	PCNET_TXSTAT_TRC	      equ 0x0000000F	  ; transmit retries
412
	PCNET_TXSTAT_RTRY	      equ 0x04000000	  ; retry
413
	PCNET_TXSTAT_LCAR	      equ 0x08000000	  ; lost carrier
414
	PCNET_TXSTAT_LCOL	      equ 0x10000000	  ; late collision
415
	PCNET_TXSTAT_EXDEF	      equ 0x20000000	  ; excessive deferrals
416
	PCNET_TXSTAT_UFLOW	      equ 0x40000000	  ; transmit underrun
417
	PCNET_TXSTAT_BUFF	      equ 0x80000000	  ; buffer error
418
 
419
	PCNET_TXCTL_OWN 	      equ 0x80000000
420
	PCNET_TXCTL_ERR 	      equ 0x40000000	  ; error summary
421
	PCNET_TXCTL_ADD_FCS	      equ 0x20000000	  ; add FCS to pkt
422
	PCNET_TXCTL_MORE_LTINT	      equ 0x10000000
423
	PCNET_TXCTL_ONE 	      equ 0x08000000
424
	PCNET_TXCTL_DEF 	      equ 0x04000000
425
	PCNET_TXCTL_STP 	      equ 0x02000000
426
	PCNET_TXCTL_ENP 	      equ 0x01000000
427
	PCNET_TXCTL_BPE 	      equ 0x00800000
428
	PCNET_TXCTL_MBO 	      equ 0x0000F000
429
	PCNET_TXCTL_BUFSZ	      equ 0x00000FFF
430
 
431
 
432
 
433
 
434
section '.flat' code readable align 16
435
 
436
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
437
;;                        ;;
438
;; proc START             ;;
439
;;                        ;;
440
;; (standard driver proc) ;;
441
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
442
 
443
proc START stdcall, state:dword
444
 
445
	cmp [state], 1
446
	jne .exit
447
 
448
  .entry:
449
 
450
	DEBUGF 1,"Loading PCnet driver\n"
451
	stdcall RegService, my_service, service_proc
452
	ret
453
 
454
  .fail:
455
  .exit:
456
	xor eax, eax
457
	ret
458
 
459
endp
460
 
461
 
462
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
463
;;                        ;;
464
;; proc SERVICE_PROC      ;;
465
;;                        ;;
466
;; (standard driver proc) ;;
467
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
468
 
469
align 4
470
proc service_proc stdcall, ioctl:dword
471
 
472
	mov	edx, [ioctl]
1377 clevermous 473
	mov	eax, [edx+IOCTL.io_code]
1196 hidnplayr 474
 
475
;------------------------------------------------------
476
 
477
	cmp	eax, 0 ;SRV_GETVERSION
478
	jne	@F
479
 
480
	cmp	[edx+IOCTL.out_size], 4
481
	jl	.fail
482
	mov	eax, [edx+IOCTL.output]
483
	mov	[eax], dword API_VERSION
484
 
485
	xor	eax, eax
486
	ret
487
 
488
;------------------------------------------------------
489
  @@:
490
	cmp	eax, 1 ;SRV_HOOK
491
	jne	.fail
492
 
493
	mov	eax, [esp]
494
 
495
	cmp	[edx + IOCTL.inp_size], 3		; Data input must be at least 3 bytes
496
	jl	.fail
497
 
498
	mov	eax, [edx + IOCTL.input]
499
	cmp	byte [eax], 1				; 1 means device number and bus number (pci) are given
500
	jne	.fail					; other types arent supported for this card yet
501
 
502
; check if the device is already listed
503
 
504
	mov	esi, PCNET_LIST
505
	mov	ecx, [PCNET_DEV]
506
	test	ecx, ecx
507
	jz	.firstdevice
508
	mov	eax, [edx+IOCTL.input]			; get the pci bus and device numbers
509
	mov	bx , [eax+1]				;
510
  .nextdevice:
511
	lodsd
512
	cmp	bx , word [eax + device.pci_bus]	; compare with pci and device num in RTL8139 list (notice the usage of word instead of byte)
513
	je	.find_devicenum 			; Device is already loaded, let's find it's device number
514
 
515
	loop	.nextdevice
516
 
517
; This device doesnt have its own eth_device structure yet, lets create one
518
 
519
  .firstdevice:
520
	cmp	[PCNET_DEV], MAX_PCNET			; First check if the driver can handle one more card
521
	jge	.fail
522
 
523
	push	edx
524
	stdcall KernelAlloc, device.size		; Allocate the buffer for eth_device structure
525
	pop	edx
526
	test	eax, eax
527
	jz	.fail
528
	mov	ebx, eax				; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
529
 
530
; Fill in the direct call addresses into the struct
531
 
532
	mov	dword [ebx+device.reset], reset
533
	mov	dword [ebx+device.transmit], transmit
534
	mov	dword [ebx+device.get_MAC], read_mac
535
	mov	dword [ebx+device.set_MAC], write_mac
536
	mov	dword [ebx+device.unload], unload
537
	mov	dword [ebx+device.name], my_service
538
 
539
; save the pci bus and device numbers
540
 
541
	mov	eax, [edx+IOCTL.input]
542
	mov	cl , [eax+1]
543
	mov	[ebx+device.pci_bus], cl
544
	mov	cl , [eax+2]
545
	mov	[ebx+device.pci_dev], cl
546
 
547
; Now, it's time to find the base io addres of the PCI device
548
; TODO: implement check if bus and dev exist on this machine
549
 
550
	mov	edx, PCI_BASE_ADDRESS_0
551
  .reg_check:
552
	movzx	eax, byte [ebx+device.pci_bus]
553
	movzx	ecx, byte [ebx+device.pci_dev]
554
 
555
	push	edx ecx
556
	stdcall PciRead16, eax ,ecx ,edx
557
	pop	ecx edx
558
 
559
	mov	[ebx+device.io_addr], eax
560
	and	eax, PCI_BASE_ADDRESS_IO_MASK
561
	test	eax, eax
562
	jz	.inc_reg
563
	mov	eax, [ebx+device.io_addr]
564
	and	eax, PCI_BASE_ADDRESS_SPACE_IO
565
	test	eax, eax
566
	jz	.inc_reg
567
 
568
	mov	eax, [ebx+device.io_addr]
569
	and	eax, PCI_BASE_ADDRESS_IO_MASK
570
	mov	[ebx+device.io_addr], eax
571
	jmp	.got_io
572
 
573
  .inc_reg:
574
	add	edx, 4
575
	cmp	edx, PCI_BASE_ADDRESS_5
576
	jbe	.reg_check
577
 
578
  .got_io:
579
 
580
; We've found the io address, find IRQ now
581
 
582
	movzx	eax, byte [ebx+device.pci_bus]
583
	movzx	ecx, byte [ebx+device.pci_dev]
584
	push	ebx
585
	stdcall PciRead8, eax ,ecx ,0x3c				; 0x3c is the offset where irq can be found
586
	pop	ebx
587
	mov	byte [ebx+device.irq_line], al
588
 
589
	DEBUGF	1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
590
	[ebx+device.pci_dev]:1,[ebx+device.pci_bus]:1,[ebx+device.irq_line]:1,[ebx+device.io_addr]:4
591
 
592
 
593
; Allocate the Receive buffer
594
 
595
	stdcall KernelAlloc, PCNET_RX_RING_SIZE * PCNET_PKT_BUF_SZ
596
	test	eax, eax
597
	jz	.err
598
	mov	[ebx+device.rx_buffer], eax				; Save the address to it into the device struct
599
 
600
; Allocate the Transmit Buffer
601
 
602
	stdcall KernelAlloc, PCNET_TX_RING_SIZE * PCNET_PKT_BUF_SZ
603
	test	eax, eax
604
	jz	.err
605
	mov	[ebx+device.tx_buffer], eax
606
 
607
; Allocate the RX Ring
608
 
609
	stdcall KernelAlloc, PCNET_RX_RING_SIZE * buf_head.size
610
	test	eax, eax
611
	jz	.err
612
	mov	dword [ebx + device.rx_ring], eax
1201 clevermous 613
	call	GetPgAddr
614
	mov	dword [ebx + device.rx_ring_phys], eax
1196 hidnplayr 615
 
616
; Allocate the TX ring
617
 
618
	stdcall KernelAlloc, PCNET_TX_RING_SIZE * buf_head.size
619
	test	eax, eax
620
	jz	.err
621
	mov	dword [ebx + device.tx_ring], eax
1201 clevermous 622
	call	GetPgAddr
623
	mov	dword [ebx + device.tx_ring_phys], eax
1196 hidnplayr 624
 
625
; fill in some of the structure variables
626
 
627
	call	switch_to_wio
628
 
629
	mov	edi, [ebx + device.rx_ring]
630
	mov	ecx, PCNET_RX_RING_SIZE
631
	mov	eax, [ebx + device.rx_buffer]
632
	call	GetPgAddr
633
  .rx_init:
634
	mov	[edi + buf_head.base], eax
635
	mov	[edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG
636
	mov	[edi + buf_head.status], 0x8000
1263 clevermous 637
	and	dword [edi + buf_head.msg_length], 0
638
	and	dword [edi + buf_head.reserved], 0
1196 hidnplayr 639
	add	eax, PCNET_PKT_BUF_SZ
640
;        inc     eax
641
	add	 edi, buf_head.size
642
	loop	 .rx_init
643
 
644
	mov	edi, [ebx + device.tx_ring]
645
	mov	ecx, PCNET_TX_RING_SIZE
1201 clevermous 646
	mov	eax, [ebx + device.tx_buffer]
647
	call	GetPgAddr
1196 hidnplayr 648
  .tx_init:
1201 clevermous 649
	mov	[edi + buf_head.base], eax
1263 clevermous 650
	and	dword [edi + buf_head.length], 0
651
	and	dword [edi + buf_head.msg_length], 0
652
	and	dword [edi + buf_head.reserved], 0
1201 clevermous 653
	add	eax, PCNET_PKT_BUF_SZ
1196 hidnplayr 654
	add	edi, buf_head.size
655
	loop	.tx_init
656
 
657
	mov	[ebx + device.tlen_rlen],(PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
658
 
659
; Ok, the eth_device structure is ready, let's probe the device
1201 clevermous 660
; Because initialization fires IRQ, IRQ handler must be aware of this device
661
	mov	eax, [PCNET_DEV]					; Add the device structure to our device list
662
	mov	[PCNET_LIST+4*eax], ebx 				; (IRQ handler uses this list to find device)
663
	inc	[PCNET_DEV]						;
1196 hidnplayr 664
 
665
	call	probe							; this function will output in eax
666
	test	eax, eax
1201 clevermous 667
	jnz	.destroy							; If an error occured, exit
1196 hidnplayr 668
 
669
	call	EthRegDev
670
	cmp	eax, -1
671
	je	.destroy
672
 
673
	ret
674
 
675
; If the device was already loaded, find the device number and return it in eax
676
 
677
  .find_devicenum:
678
	DEBUGF	1,"Trying to find device number of already registered device\n"
679
	mov	ebx, eax
680
	call	EthStruc2Dev						; This kernel procedure converts a pointer to device struct in ebx
681
									; into a device number in edi
682
	mov	eax, edi						; Application wants it in eax instead
683
	DEBUGF	1,"Kernel says: %u\n", eax
684
	ret
685
 
686
; If an error occured, remove all allocated data and exit (returning -1 in eax)
687
 
688
  .destroy:
689
	; todo: reset device into virgin state
690
 
1201 clevermous 691
	dec	[PCNET_DEV]
1196 hidnplayr 692
  .err:
693
	DEBUGF	1,"Error, removing all data !\n"
694
	stdcall KernelFree, dword [ebx+device.rx_buffer]
695
	stdcall KernelFree, dword [ebx+device.tx_buffer]
696
	stdcall KernelFree, ebx
697
 
698
  .fail:
699
	or	eax, -1
700
	ret
701
 
702
;------------------------------------------------------
703
endp
704
 
705
 
706
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
707
;;                                                                        ;;
708
;;        Actual Hardware dependent code starts here                      ;;
709
;;                                                                        ;;
710
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
711
 
712
align 4
713
unload:
714
	; TODO: (in this particular order)
715
	;
716
	; - Stop the device
717
	; - Detach int handler
718
	; - Remove device from local list (RTL8139_LIST)
719
	; - call unregister function in kernel
720
	; - Remove all allocated structures and buffers the card used
721
 
722
	or	eax,-1
723
 
724
ret
725
 
726
 
727
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
728
;;
729
;;  probe: enables the device (if it really is a PCnet device)
730
;;
731
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
732
 
733
align 4
734
probe:
735
	mov	edx, [ebx + device.io_addr]
736
 
737
	call	wio_reset
738
 
739
	xor	ecx, ecx
740
	call	wio_read_csr
741
	cmp	eax, 4
742
	jne	.try_dwio
743
 
744
	; Try Word I/O
745
	mov	ax , 88
746
	add	edx, PCNET_WIO_RAP
747
	out	dx , ax
748
	nop
749
	nop
750
	in	ax , dx
751
	sub	edx, PCNET_WIO_RAP
752
	cmp	ax , 88
753
	jne	.try_dwio
754
 
755
	DEBUGF 1,"Using WIO\n"
756
 
757
	call	switch_to_wio
758
 
759
	jmp	.L1
760
 
761
  .try_dwio:
762
	call	dwio_reset
763
 
764
	xor	ecx, ecx
765
	call	dwio_read_csr
766
	cmp	eax, 4
767
	jne	.no_dev
768
 
769
	; Try Dword I/O
770
	add	edx, PCNET_DWIO_RAP
771
	mov	eax, 88
772
	out	dx , eax
773
	nop
774
	nop
775
	in	eax, dx
776
	sub	edx, PCNET_DWIO_RAP
777
	and	eax, 0xffff
778
	cmp	eax, 88
779
	jne	.no_dev
780
 
781
	DEBUGF 1,"Using DWIO\n"
782
 
783
	call	switch_to_dwio
784
 
785
	jmp	.L1
786
 
787
  .no_dev:
788
	DEBUGF 1,"PCnet device not found!\n"
789
	mov	eax, 1
790
	ret
791
  .L1:
792
	; TODO: remember to use WORD or DWORD operations
793
 
794
;;;        stdcall Sleep, 10
795
 
796
;---------------------------------------------
797
; Switch to dword operations
798
 
799
 ;       DEBUGF 1,"Switching to 32\n"
800
 ;
801
 ;       mov     ecx, PCNET_DWIO_RDP
802
 ;       mov     eax, 0
803
 ;       call    wio_write_csr
804
 
805
;---------------------------------------------
806
 
807
	mov	ecx, PCNET_CSR_CHIPID0
808
	call	[ebx + device.access_read_csr]
809
	mov	esi, eax
810
 
811
	mov	ecx, PCNET_CSR_CHIPID1
812
	call	[ebx + device.access_read_csr]
813
	shl	eax, 16
814
	or	eax, esi
815
 
816
	mov	ecx, eax
817
	and	ecx, 0xfff
818
	cmp	ecx, 3
819
	jne	.no_dev
820
 
821
	shr	eax, 12
822
	and	eax, 0xffff
823
	mov	[ebx + device.chip_version], eax
824
 
825
	DEBUGF 1,"chip version ok\n"
826
	mov	[ebx + device.fdx], 0
827
	mov	[ebx + device.mii], 0
828
	mov	[ebx + device.fset], 0
829
	mov	[ebx + device.dxsuflo], 0
830
	mov	[ebx + device.ltint], 0
831
 
832
	cmp	eax, 0x2420
833
	je	.L2
834
	cmp	eax, 0x2430
835
	je	.L2
836
 
837
	mov	[ebx + device.fdx], 1
838
 
839
	cmp	eax, 0x2621
840
	je	.L4
841
	cmp	eax, 0x2623
842
	je	.L5
843
	cmp	eax, 0x2624
844
	je	.L6
845
	cmp	eax, 0x2625
846
	je	.L7
847
	cmp	eax, 0x2626
848
	je	.L8
849
	cmp	eax, 0x2627
850
	je	.L9
851
 
852
	DEBUGF 1,"Invalid chip rev\n"
853
	jmp	.no_dev
854
  .L2:
855
	mov	[ebx + device.name], device_l2
856
	jmp	.L10
857
  .L4:
858
	mov	[ebx + device.name], device_l4
859
;        mov     [ebx + device.fdx], 1
860
	jmp	.L10
861
  .L5:
862
	mov	[ebx + device.name], device_l5
863
;        mov     [ebx + device.fdx], 1
864
	mov	[ebx + device.mii], 1
865
	mov	[ebx + device.fset], 1
866
	mov	[ebx + device.ltint], 1
867
	jmp	.L10
868
  .L6:
869
	mov	[ebx + device.name], device_l6
870
;        mov     [ebx + device.fdx], 1
871
	mov	[ebx + device.mii], 1
872
	mov	[ebx + device.fset], 1
873
	jmp	.L10
874
  .L7:
875
	mov	[ebx + device.name], device_l7
876
;        mov     [ebx + device.fdx], 1
877
	mov	[ebx + device.mii], 1
878
	jmp	.L10
879
  .L8:
880
	mov	[ebx + device.name], device_l8
881
;        mov     [ebx + device.fdx], 1
882
	mov	ecx, PCNET_CSR_RXPOLL
883
	call	dword [ebx + device.access_read_bcr]
884
	call	dword [ebx + device.access_write_bcr]
885
	jmp	.L10
886
  .L9:
887
	mov	[ebx + device.name], device_l9
888
;        mov     [ebx + device.fdx], 1
889
	mov	[ebx + device.mii], 1
890
  .L10:
891
	DEBUGF 1,"device name: %s\n",[ebx + device.name]
892
 
893
	cmp	[ebx + device.fset], 1
894
	jne	.L11
895
	mov	ecx, PCNET_BCR_BUSCTL
896
	call	[ebx + device.access_read_bcr]
897
	or	eax, 0x800
898
	call	[ebx + device.access_write_bcr]
899
 
900
	mov	ecx, PCNET_CSR_DMACTL
901
	call	[ebx + device.access_read_csr]
902
;        and     eax, 0xc00
903
;        or      eax, 0xc00
904
	mov	eax, 0xc00
905
	call	[ebx + device.access_write_csr]
906
 
907
	mov	[ebx + device.dxsuflo],1
908
	mov	[ebx + device.ltint],1
909
  .L11:
910
 
911
	push	ebx
912
	call	adjust_pci_device
913
	pop	ebx
914
 
915
	DEBUGF 1,"PCI done\n"
916
	mov	eax, PCNET_PORT_ASEL
917
	mov	[ebx + device.options], eax
918
	mov	[ebx + device.mode_], word 0x0003
919
	mov	[ebx + device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
920
 
921
	mov	dword [ebx + device.filter], 0
922
	mov	dword [ebx + device.filter+4], 0
923
 
924
	mov	eax, PCNET_IMR
925
	mov	ecx, PCNET_CSR_IMR			; Write interrupt mask
926
	call	[ebx + device.access_write_csr]
927
 
928
if 0
929
 
930
	mov	ecx, PCNET_BCR_SSTYLE		; Select Software style 2       TODO: freebsd driver uses style 3, why?
931
	mov	eax, 2
932
	call	[ebx + device.access_write_bcr]
933
 
934
 
935
; ------------ really nescessary??? ----------------
936
	lea	eax, [ebx + device.private]
937
	mov	ecx, eax
938
	and	ecx, 0xFFF ; KolibriOS PAGE SIZE
939
	call	GetPgAddr
940
	add	eax, ecx
941
 
942
	and	eax, 0xffff
943
	mov	ecx, PCNET_CSR_IAB0
944
	call	[ebx + device.access_write_csr]
945
 
946
 
947
	lea	eax, [ebx + device.private]
948
	mov	ecx, eax
949
	and	ecx, 0xFFF ; KolibriOS PAGE SIZE
950
	call	GetPgAddr
951
	add	eax, ecx
952
 
953
	shr	eax,16
954
	mov	ecx, PCNET_CSR_IAB1
955
	call	[ebx + device.access_write_csr]
956
 
957
	mov	ecx, PCNET_CSR_CSR
958
	mov	eax, 1
959
	call	[ebx + device.access_write_csr]
960
; ------------------------------------------------
961
end if
962
 
1206 hidnplayr 963
;       mov     esi, 1
964
;       call    Sleep
1196 hidnplayr 965
 
966
 
967
reset:
968
 
969
; attach int handler
970
 
971
	movzx	eax, [ebx+device.irq_line]
972
	DEBUGF	1,"Attaching int handler to irq %x\n",eax:1
973
	stdcall AttachIntHandler, eax, int_handler, dword 0
974
	test	eax, eax
975
	jnz	@f
976
	DEBUGF	1,"\nCould not attach int handler!\n"
977
;        or      eax, -1
978
;        ret
979
  @@:
980
 
981
	mov	edx, [ebx + device.io_addr]
982
	call	[ebx + device.access_reset]
983
 
984
	; Switch pcnet32 to 32bit mode
985
	mov	ecx, PCNET_BCR_SSTYLE
986
	mov	eax, 2
987
	call	[ebx + device.access_write_bcr]
988
 
989
	; set/reset autoselect bit
990
	mov	ecx, PCNET_BCR_MISCCFG
991
	call	[ebx + device.access_read_bcr]
992
	and	eax,not 2
993
	test	[ebx + device.options], PCNET_PORT_ASEL
994
	jz	.L1
995
	or	eax, 2
996
  .L1:
997
	call	[ebx + device.access_write_bcr]
998
 
999
 
1000
	; Handle full duplex setting
1001
	cmp	byte [ebx + device.full_duplex], 0
1002
	je	.L2
1003
	mov	ecx, PCNET_BCR_DUPLEX
1004
	call	[ebx + device.access_read_bcr]
1005
	and	eax, not 3
1006
	test	[ebx + device.options], PCNET_PORT_FD
1007
	jz	.L3
1008
	or	eax, 1
1009
	cmp	[ebx + device.options], PCNET_PORT_FD or PCNET_PORT_AUI
1010
	jne	.L4
1011
	or	eax, 2
1012
	jmp	.L4
1013
  .L3:
1014
	test	[ebx + device.options], PCNET_PORT_ASEL
1015
	jz	.L4
1016
	cmp	[ebx + device.chip_version], 0x2627
1017
	jne	.L4
1018
	or	eax, 3
1019
  .L4:
1020
	mov	ecx, PCNET_BCR_DUPLEX
1021
	call	[ebx + device.access_write_bcr]
1022
  .L2:
1023
 
1024
 
1025
	; set/reset GPSI bit in test register
1026
	mov	ecx, 124
1027
	call	[ebx + device.access_read_csr]
1028
	mov	ecx, [ebx + device.options]
1029
	and	ecx, PCNET_PORT_PORTSEL
1030
	cmp	ecx, PCNET_PORT_GPSI
1031
	jne	.L5
1032
	or	eax, 0x10
1033
  .L5:
1034
	call	[ebx + device.access_write_csr]
1035
	cmp	[ebx + device.mii], 0
1036
	je	.L6
1037
	test	[ebx + device.options], PCNET_PORT_ASEL
1038
	jnz	.L6
1039
	mov	ecx, PCNET_BCR_MIICTL
1040
	call	[ebx + device.access_read_bcr]
1041
	and	eax,not 0x38
1042
	test	[ebx + device.options], PCNET_PORT_FD
1043
	jz	.L7
1044
	or	eax, 0x10
1045
  .L7:
1046
	test	[ebx + device.options], PCNET_PORT_100
1047
	jz	.L8
1048
	or	eax, 0x08
1049
  .L8:
1050
	call	[ebx + device.access_write_bcr]
1051
	jmp	.L9
1052
.L6:
1053
	test	[ebx + device.options], PCNET_PORT_ASEL
1054
	jz	.L9
1055
	mov	ecx, PCNET_BCR_MIICTL
1056
	DEBUGF 1,"ASEL, enable auto-negotiation\n"
1057
	call	[ebx + device.access_read_bcr]
1058
	and	eax, not 0x98
1059
	or	eax, 0x20
1060
	call	[ebx + device.access_write_bcr]
1061
.L9:
1062
	cmp	[ebx + device.ltint],0
1063
	je	.L10
1064
	mov	ecx,5
1065
	call	[ebx + device.access_read_csr]
1066
	or	eax,(1 shl 14)
1067
	call	[ebx + device.access_write_csr]
1068
.L10:
1069
	mov	eax,[ebx  + device.options]
1070
	and	eax,PCNET_PORT_PORTSEL
1071
	shl	eax,7
1072
	mov	[ebx + device.mode_],ax
1073
	mov	dword [ebx + device.filter], -1
1074
	mov	dword [ebx + device.filter+4], -1
1075
 
1201 clevermous 1076
	call	read_mac
1196 hidnplayr 1077
 
1201 clevermous 1078
	lea	esi, [ebx + device.mac]
1079
	lea	edi, [ebx + device.phys_addr]
1080
	movsd
1081
	movsw
1082
 
1196 hidnplayr 1083
	lea	eax, [ebx + device.private]
1084
	mov	ecx, eax
1085
	and	ecx, 0xFFF ; KolibriOS PAGE SIZE
1086
	call	GetPgAddr
1087
	add	eax, ecx
1088
 
1089
	push	eax
1090
	and	eax, 0xffff
1091
	mov	ecx, 1
1092
	call	[ebx + device.access_write_csr]
1093
	pop	eax
1094
	shr	eax,16
1095
	mov	ecx,2
1096
	call	[ebx + device.access_write_csr]
1097
 
1098
	mov	ecx,4
1099
	mov	eax,0x0915
1100
	call	[ebx + device.access_write_csr]
1101
 
1102
	mov	ecx,0
1103
	mov	eax,1
1104
	call	[ebx + device.access_write_csr]
1105
 
1106
	mov	[ebx + device.tx_full],0
1107
	mov	[ebx + device.cur_rx],0
1108
	mov	[ebx + device.cur_tx],0
1109
	mov	[ebx + device.dirty_rx],0
1110
	mov	[ebx + device.dirty_tx],0
1111
 
1112
	mov	ecx,100
1113
.L11:
1114
	push	ecx
1115
	xor	ecx,ecx
1116
	call	[ebx + device.access_read_csr]
1117
	pop	ecx
1118
	test	ax,0x100
1119
	jnz	.L12
1120
	loop	.L11
1121
.L12:
1122
 
1123
	DEBUGF 1,"hardware reset\n"
1124
	xor	ecx, ecx
1125
	mov	eax, 0x0002
1126
	call	[ebx + device.access_write_csr]
1127
 
1128
	xor	ecx, ecx
1129
	call	[ebx + device.access_read_csr]
1130
 
1131
	xor	ecx, ecx
1132
	mov	eax, PCNET_CSR_INTEN or PCNET_CSR_START
1133
	call	[ebx + device.access_write_csr]
1134
 
1135
	DEBUGF 1,"PCNET reset complete\n"
1136
	xor	eax, eax
1137
	ret
1138
 
1139
 
1140
 
1141
 
1142
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1143
;;                                         ;;
1144
;; Transmit                                ;;
1145
;;                                         ;;
1263 clevermous 1146
;; In: buffer pointer in [esp+4]           ;;
1254 hidnplayr 1147
;;     size of buffer in [esp+8]           ;;
1196 hidnplayr 1148
;;     pointer to device structure in ebx  ;;
1149
;;                                         ;;
1150
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1151
 
1152
align 4
1153
transmit:
1263 clevermous 1154
	DEBUGF	1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
1254 hidnplayr 1155
	mov	eax, [esp+4]
1196 hidnplayr 1156
	DEBUGF	1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1157
	[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1158
	[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1159
	[eax+13]:2,[eax+12]:2
1160
 
1254 hidnplayr 1161
	cmp	dword [esp+8], 1514
1196 hidnplayr 1162
	jg	.finish 			; packet is too long
1254 hidnplayr 1163
	cmp	dword [esp+8], 60
1196 hidnplayr 1164
	jl	.finish 			; packet is too short
1165
 
1166
; check descriptor
1167
	movzx	eax, [ebx + device.cur_tx]
1201 clevermous 1168
	imul	edi, eax, PCNET_PKT_BUF_SZ
1169
	shl	eax, 4
1170
	add	edi, [ebx + device.tx_buffer]
1171
	add	eax, [ebx + device.tx_ring]
1172
	test	byte [eax + buf_head.status + 1], 80h
1173
	jnz	.nospace
1174
; descriptor is free, copy data
1254 hidnplayr 1175
	mov	esi, [esp+4]
1176
	mov	ecx, [esp+8]
1201 clevermous 1177
	mov	edx, ecx
1178
	shr	ecx, 2
1179
	and	edx, 3
1180
	rep	movsd
1181
	mov	ecx, edx
1182
	rep	movsb
1183
; set length
1254 hidnplayr 1184
	mov	ecx, [esp+8]
1201 clevermous 1185
	neg	ecx
1186
	mov	[eax + buf_head.length], cx
1187
; put to transfer queue
1188
	mov	[eax + buf_head.status], 0x8300
1196 hidnplayr 1189
 
1190
; trigger an immediate send
1201 clevermous 1191
	xor	ecx, ecx	 ; CSR0
1196 hidnplayr 1192
	call	[ebx + device.access_read_csr]
1193
	or	eax, PCNET_CSR_TX
1194
	call	[ebx + device.access_write_csr]
1195
 
1196
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
1197
	inc	[ebx + device.cur_tx]
1198
	and	[ebx + device.cur_tx], 3
1199
	DEBUGF	2," - Packet Sent! "
1200
 
1201
.finish:
1202
	DEBUGF	2," - Done!\n"
1203
	ret
1204
 
1201 clevermous 1205
.nospace:
1206
	DEBUGF	1, 'ERROR: no free transmit descriptors\n'
1207
; todo: maybe somehow notify the kernel about the error?
1208
	ret
1196 hidnplayr 1209
 
1210
 
1211
 
1212
;;;;;;;;;;;;;;;;;;;;;;;
1213
;;                   ;;
1214
;; Interrupt handler ;;
1215
;;                   ;;
1216
;;;;;;;;;;;;;;;;;;;;;;;
1217
 
1218
align 4
1219
int_handler:
1220
 
1206 hidnplayr 1221
;       DEBUGF  1,"IRQ %x ",eax:2                   ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
1196 hidnplayr 1222
 
1223
; find pointer of device wich made IRQ occur
1224
 
1225
	mov	esi, PCNET_LIST
1226
	mov	ecx, [PCNET_DEV]
1227
	test	ecx, ecx
1228
	jz	.abort
1229
  .nextdevice:
1230
	mov	ebx, dword [esi]
1231
	mov	edx, [ebx + device.io_addr]	; get IRQ reason
1232
 
1233
	push	ecx
1201 clevermous 1234
	xor	ecx, ecx ; CSR0
1196 hidnplayr 1235
	call	[ebx + device.access_read_csr]
1236
	pop	ecx
1237
 
1201 clevermous 1238
	test	al , al
1239
	js	.got_it
1196 hidnplayr 1240
 
1241
	add	esi, 4
1242
	loop	.nextdevice
1243
 
1244
	ret					    ; If no device was found, abort (The irq was probably for a device, not registered to this driver
1245
 
1246
  .got_it:
1247
;-------------------------------------------------------
1201 clevermous 1248
; Possible reasons:
1249
; initialization done - ignore
1250
; transmit done - ignore
1251
; packet received - handle
1252
; Clear ALL IRQ reasons.
1253
; N.B. One who wants to handle more than one reason must be ready
1254
; to two or more reasons in one IRQ.
1255
	xor	ecx, ecx
1256
	call	[ebx + device.access_write_csr]
1196 hidnplayr 1257
; Received packet ok?
1258
 
1259
	test	ax, PCNET_CSR_RINT
1260
	jz	@f
1261
 
1251 clevermous 1262
.receiver_test_loop:
1196 hidnplayr 1263
	movzx	eax, [ebx + device.cur_rx]
1264
;        and     eax, PCNET_RX_RING_MOD_MASK
1265
	mov	edi, eax
1266
 
1267
	imul	esi, eax, PCNET_PKT_BUF_SZ	;
1268
	add	esi, [ebx + device.rx_buffer]	; esi now points to rx buffer
1269
 
1270
	shl	edi, 4				; desc * 16 (16 is size of one ring entry)
1271
	add	edi, [ebx + device.rx_ring]	; edi now points to current rx ring entry
1272
 
1273
	mov	cx , [edi + buf_head.status]
1274
 
1275
	test	cx , PCNET_RXSTAT_OWN		; If this bit is set, the controller OWN's the packet, if not, we do
1276
	jnz	.abort
1277
 
1201 clevermous 1278
	test	cx , PCNET_RXSTAT_ENP
1196 hidnplayr 1279
	jz	.abort
1280
 
1201 clevermous 1281
	test	cx , PCNET_RXSTAT_STP
1196 hidnplayr 1282
	jz	.abort
1283
 
1201 clevermous 1284
	movzx	ecx, [edi + buf_head.msg_length]	; get packet length in ecx
1196 hidnplayr 1285
	sub	ecx, 4				;
1286
 
1201 clevermous 1287
	push	ecx
1196 hidnplayr 1288
	stdcall KernelAlloc, ecx		; Allocate a buffer to put packet into
1201 clevermous 1289
	pop	ecx
1196 hidnplayr 1290
	test	eax, eax			; Test if we allocated succesfully
1291
	jz	.abort				;
1292
 
1251 clevermous 1293
	push	.receiver_test_loop		;
1196 hidnplayr 1294
	push	ecx				; for eth_receiver
1295
	push	eax				;
1296
 
1297
	xchg	edi, eax
1298
	push	ecx
1299
	shr	ecx, 2
1300
	cld
1301
	rep	movsd
1302
	pop	ecx
1303
	and	ecx, 3
1304
	rep	movsb
1305
 
1206 hidnplayr 1306
;       mov     word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG
1201 clevermous 1307
	mov	word [eax + buf_head.status], PCNET_RXSTAT_OWN	    ; Set OWN bit back to 1 (controller may write to tx-buffer again now)
1196 hidnplayr 1308
 
1309
	inc	[ebx + device.cur_rx]		; update descriptor
1310
	and	[ebx + device.cur_rx], 3	;
1311
 
1312
	jmp	EthReceiver			; Send the copied packet to kernel
1313
 
1314
  .abort:
1315
 
1316
  @@:
1317
 
1318
	ret
1319
 
1320
 
1321
 
1322
 
1323
;;;;;;;;;;;;;;;;;;;;;;;
1324
;;                   ;;
1325
;; Write MAC address ;;
1326
;;                   ;;
1327
;;;;;;;;;;;;;;;;;;;;;;;
1328
 
1329
align 4
1330
write_mac:	; in: mac pushed onto stack (as 3 words)
1331
 
1332
	DEBUGF	1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
1333
 
1334
	mov	edx, [ebx + device.io_addr]
1335
	add	dx, 2
1336
	xor	eax, eax
1337
 
1338
	mov	ecx, PCNET_CSR_PAR0
1339
       @@:
1340
	pop	ax
1341
	call	[ebx + device.access_write_csr]
1342
	DEBUGF	1,"."
1343
	inc	ecx
1344
	cmp	ecx, PCNET_CSR_PAR2
1345
	jl	@r
1346
 
1347
	DEBUGF	1,"\n"
1348
 
1349
; Notice this procedure does not ret, but continues to read_mac instead.
1350
 
1351
;;;;;;;;;;;;;;;;;;;;;;
1352
;;                  ;;
1353
;; Read MAC address ;;
1354
;;                  ;;
1355
;;;;;;;;;;;;;;;;;;;;;;
1356
 
1357
read_mac:				; T- OK
1358
	DEBUGF	1,"Reading MAC"
1359
 
1360
	mov	edx, [ebx + device.io_addr]
1361
	add	dx, 6
1362
       @@:
1363
	dec	dx
1364
	dec	dx
1365
	in	ax, dx
1366
	push	ax
1367
	DEBUGF	1,"."
1368
	cmp	edx, [ebx + device.io_addr]
1369
	jg	@r
1370
 
1371
	DEBUGF	1," %x-%x-%x-%x-%x-%x\n",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
1372
 
1373
	lea	edi, [ebx + device.mac]
1374
	pop	ax
1375
	stosw
1376
	pop	ax
1377
	stosw
1378
	pop	ax
1379
	stosw
1380
 
1381
	ret
1382
 
1383
 
1384
switch_to_wio:
1385
 
1386
	mov	[ebx + device.access_read_csr], wio_read_csr
1387
	mov	[ebx + device.access_write_csr], wio_write_csr
1388
	mov	[ebx + device.access_read_bcr], wio_read_bcr
1389
	mov	[ebx + device.access_write_bcr], wio_write_bcr
1390
	mov	[ebx + device.access_read_rap], wio_read_rap
1391
	mov	[ebx + device.access_write_rap], wio_write_rap
1392
	mov	[ebx + device.access_reset], wio_reset
1393
 
1394
	ret
1395
 
1396
switch_to_dwio:
1397
 
1398
	mov	[ebx + device.access_read_csr], dwio_read_csr
1399
	mov	[ebx + device.access_write_csr], dwio_write_csr
1400
	mov	[ebx + device.access_read_bcr], dwio_read_bcr
1401
	mov	[ebx + device.access_write_bcr], dwio_write_bcr
1402
	mov	[ebx + device.access_read_rap], dwio_read_rap
1403
	mov	[ebx + device.access_write_rap], dwio_write_rap
1404
	mov	[ebx + device.access_reset], dwio_reset
1405
 
1406
	ret
1407
 
1408
 
1409
 
1410
 
1411
 
1412
; ecx - index
1413
; return:
1414
; eax - data
1415
wio_read_csr:
1416
 
1417
	add	edx, PCNET_WIO_RAP
1418
	mov	ax , cx
1419
	out	dx , ax
1420
	add	edx, PCNET_WIO_RDP - PCNET_WIO_RAP
1421
	in	ax , dx
1422
	and	eax, 0xffff
1423
	sub	edx, PCNET_WIO_RDP
1424
 
1425
	ret
1426
 
1427
 
1428
; eax - data
1429
; ecx - index
1430
wio_write_csr:
1431
 
1432
	add	edx, PCNET_WIO_RAP
1433
	xchg	eax, ecx
1434
	out	dx , ax
1435
	xchg	eax, ecx
1436
	add	edx, PCNET_WIO_RDP - PCNET_WIO_RAP
1437
	out	dx , ax
1438
	sub	edx, PCNET_WIO_RDP
1439
 
1440
	ret
1441
 
1442
 
1443
; ecx - index
1444
; return:
1445
; eax - data
1446
wio_read_bcr:
1447
 
1448
	add	edx, PCNET_WIO_RAP
1449
	mov	ax , cx
1450
	out	dx , ax
1451
	add	edx, PCNET_WIO_BDP - PCNET_WIO_RAP
1452
	in	ax , dx
1453
	and	eax, 0xffff
1454
	sub	edx, PCNET_WIO_BDP
1455
 
1456
	ret
1457
 
1458
 
1459
; eax - data
1460
; ecx - index
1461
wio_write_bcr:
1462
 
1463
	add	edx, PCNET_WIO_RAP
1464
	xchg	eax, ecx
1465
	out	dx , ax
1466
	xchg	eax, ecx
1467
	add	edx, PCNET_WIO_BDP - PCNET_WIO_RAP
1468
	out	dx , ax
1469
	sub	edx, PCNET_WIO_BDP
1470
 
1471
	ret
1472
 
1473
 
1474
wio_read_rap:
1475
 
1476
	add	edx, PCNET_WIO_RAP
1477
	in	ax , dx
1478
	and	eax, 0xffff
1479
	sub	edx, PCNET_WIO_RAP
1480
 
1481
	ret
1482
 
1483
; eax - val
1484
wio_write_rap:
1485
 
1486
	add	edx, PCNET_WIO_RAP
1487
	out	dx , ax
1488
	sub	edx, PCNET_WIO_RAP
1489
 
1490
	ret
1491
 
1492
 
1493
wio_reset:
1494
 
1495
	push	eax
1496
	add	edx, PCNET_WIO_RESET
1497
	in	ax , dx
1498
	pop	eax
1499
	sub	edx, PCNET_WIO_RESET
1500
 
1501
	ret
1502
 
1503
 
1504
 
1505
; ecx - index
1506
; return:
1507
; eax - data
1508
dwio_read_csr:
1509
 
1510
	add	edx, PCNET_DWIO_RAP
1201 clevermous 1511
	mov	eax, ecx
1196 hidnplayr 1512
	out	dx , eax
1513
	add	edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
1514
	in	eax, dx
1515
	and	eax, 0xffff
1516
	sub	edx, PCNET_DWIO_RDP
1517
 
1518
	ret
1519
 
1520
 
1521
; ecx - index
1522
; eax - data
1523
dwio_write_csr:
1524
 
1525
	add	edx, PCNET_DWIO_RAP
1526
	xchg	eax, ecx
1527
	out	dx , eax
1528
	add	edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
1529
	xchg	eax, ecx
1530
	out	dx , eax
1531
	sub	edx, PCNET_DWIO_RDP
1532
 
1533
	ret
1534
 
1535
; ecx - index
1536
; return:
1537
; eax - data
1538
dwio_read_bcr:
1539
 
1540
	add	edx, PCNET_DWIO_RAP
1201 clevermous 1541
	mov	eax, ecx
1196 hidnplayr 1542
	out	dx , eax
1543
	add	edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
1544
	in	eax, dx
1545
	and	eax, 0xffff
1546
	sub	edx, PCNET_DWIO_BDP
1547
 
1548
	ret
1549
 
1550
 
1551
; ecx - index
1552
; eax - data
1553
dwio_write_bcr:
1554
 
1555
	add	edx, PCNET_DWIO_RAP
1556
	xchg	eax, ecx
1557
	out	dx , eax
1558
	add	edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
1559
	xchg	eax, ecx
1560
	out	dx , eax
1561
	sub	edx, PCNET_DWIO_BDP
1562
 
1563
	ret
1564
 
1565
 
1566
dwio_read_rap:
1567
 
1568
	add	edx, PCNET_DWIO_RAP
1569
	in	eax, dx
1570
	and	eax, 0xffff
1571
	sub	edx, PCNET_DWIO_RAP
1572
 
1573
	ret
1574
 
1575
 
1576
; eax - val
1577
dwio_write_rap:
1578
 
1579
	add	edx, PCNET_DWIO_RAP
1580
	out	dx , eax
1581
	sub	edx, PCNET_DWIO_RAP
1582
 
1583
	ret
1584
 
1585
 
1586
dwio_reset:
1587
 
1588
	push	eax
1589
	add	edx, PCNET_DWIO_RESET
1590
	in	eax, dx
1591
	pop	eax
1592
	sub	edx, PCNET_DWIO_RESET
1593
 
1594
	ret
1595
 
1596
 
1597
 
1598
adjust_pci_device:
1599
	;*******Get current setting************************
1600
	movzx	 edx, byte [ebx + device.pci_dev]
1601
	movzx	 ecx, byte [ebx + device.pci_bus]
1202 clevermous 1602
	push	ecx edx
1603
	stdcall  PciRead16, ecx ,edx ,0x04
1604
	pop	edx ecx
1196 hidnplayr 1605
;        ;******see if its already set as bus master********
1606
;        and      ax,5
1607
;        cmp      ax,5
1608
;        je       .Latency
1609
	;******Make card a bus master*******
1202 clevermous 1610
	or	 al, 5
1611
	stdcall  PciWrite16, ecx ,edx ,0x04, eax
1196 hidnplayr 1612
	;******Check latency setting***********
1613
  .Latency:
1614
   ;*******Get current latency setting************************
1615
;   mov     al, 1                                       ;read a byte
1616
;   mov     bh, [pci_dev]
1617
;   mov     ah, [pci_bus]
1618
;   mov     bl, 0x0D                                ;from Lantency Timer Register
1619
;   call    pci_read_reg
1620
   ;******see if its aat least 64 clocks********
1621
;   cmp      ax,64
1622
;   jge      PCNET_adjust_pci_device_Done
1623
   ;******Set latency to 32 clocks*******
1624
;   mov     cx, 64                              ;value to write
1625
;   mov     bh, [pci_dev]
1626
;   mov     al, 1                               ;write a byte
1627
;   mov     ah, [pci_bus]
1628
;   mov     bl, 0x0D                            ;to Lantency Timer Register
1629
;   call    pci_write_reg
1630
   ;******Check latency setting***********
1631
  .Done:
1632
	ret
1633
 
1634
 
1635
 
1636
 
1637
; End of code
1638
 
1639
align 4 				      ; Place all initialised data here
1640
 
1641
PCNET_DEV     dd 0
1642
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
1643
my_service    db 'PCnet',0		      ; max 16 chars include zero
1644
 
1645
device_l2     db "PCnet/PCI 79C970",0
1646
device_l4     db "PCnet/PCI II 79C970A",0
1647
device_l5     db "PCnet/FAST 79C971",0
1648
device_l6     db "PCnet/FAST+ 79C972",0
1649
device_l7     db "PCnet/FAST III 79C973",0
1650
device_l8     db "PCnet/Home 79C978",0
1651
device_l9     db "PCnet/FAST III 79C975",0
1652
 
1653
options_mapping:
1654
dd PCNET_PORT_ASEL					;  0 Auto-select
1655
dd PCNET_PORT_AUI					;  1 BNC/AUI
1656
dd PCNET_PORT_AUI					;  2 AUI/BNC
1657
dd PCNET_PORT_ASEL					;  3 not supported
1658
dd PCNET_PORT_10BT or PCNET_PORT_FD			;  4 10baseT-FD
1659
dd PCNET_PORT_ASEL					;  5 not supported
1660
dd PCNET_PORT_ASEL					;  6 not supported
1661
dd PCNET_PORT_ASEL					;  7 not supported
1662
dd PCNET_PORT_ASEL					;  8 not supported
1663
dd PCNET_PORT_MII					;  9 MII 10baseT
1664
dd PCNET_PORT_MII or PCNET_PORT_FD			; 10 MII 10baseT-FD
1665
dd PCNET_PORT_MII					; 11 MII (autosel)
1666
dd PCNET_PORT_10BT					; 12 10BaseT
1667
dd PCNET_PORT_MII or PCNET_PORT_100			; 13 MII 100BaseTx
1668
dd PCNET_PORT_MII or PCNET_PORT_100 or PCNET_PORT_FD	; 14 MII 100BaseTx-FD
1669
dd PCNET_PORT_ASEL					; 15 not supported
1670
 
1671
include_debug_strings					; All data wich FDO uses will be included here
1672
 
1673
section '.data' data readable writable align 16 	; place all uninitialized data place here
1674
 
1675
PCNET_LIST rd MAX_PCNET 				; This list contains all pointers to device structures the driver is handling