Subversion Repositories Kolibri OS

Rev

Rev 4582 | Rev 5004 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4582 Rev 4629
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                  ;;
2
;;                                                                  ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.     ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.     ;;
4
;; Distributed under terms of the GNU General Public License        ;;
4
;; Distributed under terms of the GNU General Public License        ;;
5
;;                                                                  ;;
5
;;                                                                  ;;
6
;;  AMD PCnet driver for KolibriOS                                  ;;
6
;;  AMD PCnet driver for KolibriOS                                  ;;
7
;;                                                                  ;;
7
;;                                                                  ;;
8
;;  By hidnplayr & clevermouse                                      ;;
8
;;  By hidnplayr & clevermouse                                      ;;
9
;;                                                                  ;;
9
;;                                                                  ;;
10
;;  Based on the PCnet32 driver for MenuetOS, by Jarek Pelczar      ;;
10
;;  Based on the PCnet32 driver for MenuetOS, by Jarek Pelczar      ;;
11
;;                                                                  ;;
11
;;                                                                  ;;
12
;;          GNU GENERAL PUBLIC LICENSE                              ;;
12
;;          GNU GENERAL PUBLIC LICENSE                              ;;
13
;;             Version 2, June 1991                                 ;;
13
;;             Version 2, June 1991                                 ;;
14
;;                                                                  ;;
14
;;                                                                  ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
format PE DLL native
17
format PE DLL native
18
entry START
18
entry START
19
 
19
 
20
        CURRENT_API             = 0x0200
20
        CURRENT_API             = 0x0200
21
        COMPATIBLE_API          = 0x0100
21
        COMPATIBLE_API          = 0x0100
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
23
 
23
 
24
        MAX_DEVICES             = 16
24
        MAX_DEVICES             = 16
25
 
25
 
26
        __DEBUG__               = 1
26
        __DEBUG__               = 1
27
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
27
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
28
 
28
 
29
        TX_RING_SIZE            = 4
29
        TX_RING_SIZE            = 4
30
        RX_RING_SIZE            = 4
30
        RX_RING_SIZE            = 4
31
 
31
 
32
section '.flat' readable writable executable
32
section '.flat' readable writable executable
33
 
33
 
34
include '../struct.inc'
34
include '../struct.inc'
35
include '../macros.inc'
35
include '../macros.inc'
36
include '../proc32.inc'
36
include '../proc32.inc'
37
include '../fdo.inc'
37
include '../fdo.inc'
38
include '../netdrv_pe.inc'
38
include '../netdrv_pe.inc'
39
 
39
 
40
 
40
 
41
        PORT_AUI                = 0x00
41
        PORT_AUI                = 0x00
42
        PORT_10BT               = 0x01
42
        PORT_10BT               = 0x01
43
        PORT_GPSI               = 0x02
43
        PORT_GPSI               = 0x02
44
        PORT_MII                = 0x03
44
        PORT_MII                = 0x03
45
        PORT_PORTSEL            = 0x03
45
        PORT_PORTSEL            = 0x03
46
        PORT_ASEL               = 0x04
46
        PORT_ASEL               = 0x04
47
        PORT_100                = 0x40
47
        PORT_100                = 0x40
48
        PORT_FD                 = 0x80
48
        PORT_FD                 = 0x80
49
 
49
 
50
        DMA_MASK                = 0xffffffff
50
        DMA_MASK                = 0xffffffff
51
 
51
 
52
        LOG_TX_BUFFERS          = 2             ; FIXME
52
        LOG_TX_BUFFERS          = 2             ; FIXME
53
        LOG_RX_BUFFERS          = 2
53
        LOG_RX_BUFFERS          = 2
54
 
54
 
55
        TX_RING_MOD_MASK        = (TX_RING_SIZE-1)
55
        TX_RING_MOD_MASK        = (TX_RING_SIZE-1)
56
        TX_RING_LEN_BITS        = (LOG_TX_BUFFERS shl 12)
56
        TX_RING_LEN_BITS        = (LOG_TX_BUFFERS shl 12)
57
 
57
 
58
        RX_RING_MOD_MASK        = (RX_RING_SIZE-1)
58
        RX_RING_MOD_MASK        = (RX_RING_SIZE-1)
59
        RX_RING_LEN_BITS        = (LOG_RX_BUFFERS shl 4)
59
        RX_RING_LEN_BITS        = (LOG_RX_BUFFERS shl 4)
60
 
60
 
61
        PKT_BUF_SZ              = 1544
61
        PKT_BUF_SZ              = 1544
62
 
62
 
63
        WIO_RDP                 = 0x10
63
        WIO_RDP                 = 0x10
64
        WIO_RAP                 = 0x12
64
        WIO_RAP                 = 0x12
65
        WIO_RESET               = 0x14
65
        WIO_RESET               = 0x14
66
        WIO_BDP                 = 0x16
66
        WIO_BDP                 = 0x16
67
 
67
 
68
        DWIO_RDP                = 0x10
68
        DWIO_RDP                = 0x10
69
        DWIO_RAP                = 0x14
69
        DWIO_RAP                = 0x14
70
        DWIO_RESET              = 0x18
70
        DWIO_RESET              = 0x18
71
        DWIO_BDP                = 0x1C
71
        DWIO_BDP                = 0x1C
72
 
72
 
73
; CSR registers
73
; CSR registers
74
 
74
 
75
        CSR_CSR                 = 0x00
75
        CSR_CSR                 = 0x00
76
        CSR_IAB0                = 0x01
76
        CSR_IAB0                = 0x01
77
        CSR_IAB1                = 0x02
77
        CSR_IAB1                = 0x02
78
        CSR_IMR                 = 0x03
78
        CSR_IMR                 = 0x03
79
        CSR_TFEAT               = 0x04
79
        CSR_TFEAT               = 0x04
80
        CSR_EXTCTL1             = 0x05
80
        CSR_EXTCTL1             = 0x05
81
        CSR_DTBLLEN             = 0x06
81
        CSR_DTBLLEN             = 0x06
82
        CSR_EXTCTL2             = 0x07
82
        CSR_EXTCTL2             = 0x07
83
        CSR_MAR0                = 0x08
83
        CSR_MAR0                = 0x08
84
        CSR_MAR1                = 0x09
84
        CSR_MAR1                = 0x09
85
        CSR_MAR2                = 0x0A
85
        CSR_MAR2                = 0x0A
86
        CSR_MAR3                = 0x0B
86
        CSR_MAR3                = 0x0B
87
        CSR_PAR0                = 0x0C
87
        CSR_PAR0                = 0x0C
88
        CSR_PAR1                = 0x0D
88
        CSR_PAR1                = 0x0D
89
        CSR_PAR2                = 0x0E
89
        CSR_PAR2                = 0x0E
90
        CSR_MODE                = 0x0F
90
        CSR_MODE                = 0x0F
91
        CSR_RXADDR0             = 0x18
91
        CSR_RXADDR0             = 0x18
92
        CSR_RXADDR1             = 0x19
92
        CSR_RXADDR1             = 0x19
93
        CSR_TXADDR0             = 0x1E
93
        CSR_TXADDR0             = 0x1E
94
        CSR_TXADDR1             = 0x1F
94
        CSR_TXADDR1             = 0x1F
95
        CSR_TXPOLL              = 0x2F
95
        CSR_TXPOLL              = 0x2F
96
        CSR_RXPOLL              = 0x31
96
        CSR_RXPOLL              = 0x31
97
        CSR_RXRINGLEN           = 0x4C
97
        CSR_RXRINGLEN           = 0x4C
98
        CSR_TXRINGLEN           = 0x4E
98
        CSR_TXRINGLEN           = 0x4E
99
        CSR_DMACTL              = 0x50
99
        CSR_DMACTL              = 0x50
100
        CSR_BUSTIMER            = 0x52
100
        CSR_BUSTIMER            = 0x52
101
        CSR_MEMERRTIMEO         = 0x64
101
        CSR_MEMERRTIMEO         = 0x64
102
        CSR_ONNOWMISC           = 0x74
102
        CSR_ONNOWMISC           = 0x74
103
        CSR_ADVFEAT             = 0x7A
103
        CSR_ADVFEAT             = 0x7A
104
        CSR_MACCFG              = 0x7D
104
        CSR_MACCFG              = 0x7D
105
        CSR_CHIPID0             = 0x58
105
        CSR_CHIPID0             = 0x58
106
        CSR_CHIPID1             = 0x59
106
        CSR_CHIPID1             = 0x59
107
 
107
 
108
; Control and Status Register (CSR0)
108
; Control and Status Register (CSR0)
109
 
109
 
110
        CSR_INIT                = 1 shl 0
110
        CSR_INIT                = 1 shl 0
111
        CSR_START               = 1 shl 1
111
        CSR_START               = 1 shl 1
112
        CSR_STOP                = 1 shl 2
112
        CSR_STOP                = 1 shl 2
113
        CSR_TX                  = 1 shl 3
113
        CSR_TX                  = 1 shl 3
114
        CSR_TXON                = 1 shl 4
114
        CSR_TXON                = 1 shl 4
115
        CSR_RXON                = 1 shl 5
115
        CSR_RXON                = 1 shl 5
116
        CSR_INTEN               = 1 shl 6
116
        CSR_INTEN               = 1 shl 6
117
        CSR_INTR                = 1 shl 7
117
        CSR_INTR                = 1 shl 7
118
        CSR_IDONE               = 1 shl 8
118
        CSR_IDONE               = 1 shl 8
119
        CSR_TINT                = 1 shl 9
119
        CSR_TINT                = 1 shl 9
120
        CSR_RINT                = 1 shl 10
120
        CSR_RINT                = 1 shl 10
121
        CSR_MERR                = 1 shl 11
121
        CSR_MERR                = 1 shl 11
122
        CSR_MISS                = 1 shl 12
122
        CSR_MISS                = 1 shl 12
123
        CSR_CERR                = 1 shl 13
123
        CSR_CERR                = 1 shl 13
124
 
124
 
125
; Interrupt masks and deferral control (CSR3)
125
; Interrupt masks and deferral control (CSR3)
126
 
126
 
127
        IMR_BSWAP               = 0x0004
127
        IMR_BSWAP               = 0x0004
128
        IMR_ENMBA               = 0x0008  ; enable modified backoff alg
128
        IMR_ENMBA               = 0x0008  ; enable modified backoff alg
129
        IMR_DXMT2PD             = 0x0010
129
        IMR_DXMT2PD             = 0x0010
130
        IMR_LAPPEN              = 0x0020  ; lookahead packet processing enb
130
        IMR_LAPPEN              = 0x0020  ; lookahead packet processing enb
131
        IMR_DXSUFLO             = 0x0040  ; disable TX stop on underflow
131
        IMR_DXSUFLO             = 0x0040  ; disable TX stop on underflow
132
        IMR_IDONE               = 0x0100
132
        IMR_IDONE               = 0x0100
133
        IMR_TINT                = 0x0200
133
        IMR_TINT                = 0x0200
134
        IMR_RINT                = 0x0400
134
        IMR_RINT                = 0x0400
135
        IMR_MERR                = 0x0800
135
        IMR_MERR                = 0x0800
136
        IMR_MISS                = 0x1000
136
        IMR_MISS                = 0x1000
137
 
137
 
138
        IMR                     = IMR_IDONE ; IMR_TINT + IMR_RINT + IMR_MERR + IMR_MISS ;+ IMR_IDONE
138
        IMR                     = IMR_IDONE ; IMR_TINT + IMR_RINT + IMR_MERR + IMR_MISS ;+ IMR_IDONE
139
 
139
 
140
; Test and features control (CSR4)
140
; Test and features control (CSR4)
141
 
141
 
142
        TFEAT_TXSTRTMASK        = 0x0004
142
        TFEAT_TXSTRTMASK        = 0x0004
143
        TFEAT_TXSTRT            = 0x0008
143
        TFEAT_TXSTRT            = 0x0008
144
        TFEAT_RXCCOFLOWM        = 0x0010  ; Rx collision counter oflow
144
        TFEAT_RXCCOFLOWM        = 0x0010  ; Rx collision counter oflow
145
        TFEAT_RXCCOFLOW         = 0x0020
145
        TFEAT_RXCCOFLOW         = 0x0020
146
        TFEAT_UINT              = 0x0040
146
        TFEAT_UINT              = 0x0040
147
        TFEAT_UINTREQ           = 0x0080
147
        TFEAT_UINTREQ           = 0x0080
148
        TFEAT_MISSOFLOWM        = 0x0100
148
        TFEAT_MISSOFLOWM        = 0x0100
149
        TFEAT_MISSOFLOW         = 0x0200
149
        TFEAT_MISSOFLOW         = 0x0200
150
        TFEAT_STRIP_FCS         = 0x0400
150
        TFEAT_STRIP_FCS         = 0x0400
151
        TFEAT_PAD_TX            = 0x0800
151
        TFEAT_PAD_TX            = 0x0800
152
        TFEAT_TXDPOLL           = 0x1000
152
        TFEAT_TXDPOLL           = 0x1000
153
        TFEAT_DMAPLUS           = 0x4000
153
        TFEAT_DMAPLUS           = 0x4000
154
 
154
 
155
; Extended control and interrupt 1 (CSR5)
155
; Extended control and interrupt 1 (CSR5)
156
 
156
 
157
        EXTCTL1_SPND            = 0x0001  ; suspend
157
        EXTCTL1_SPND            = 0x0001  ; suspend
158
        EXTCTL1_MPMODE          = 0x0002  ; magic packet mode
158
        EXTCTL1_MPMODE          = 0x0002  ; magic packet mode
159
        EXTCTL1_MPENB           = 0x0004  ; magic packet enable
159
        EXTCTL1_MPENB           = 0x0004  ; magic packet enable
160
        EXTCTL1_MPINTEN         = 0x0008  ; magic packet interrupt enable
160
        EXTCTL1_MPINTEN         = 0x0008  ; magic packet interrupt enable
161
        EXTCTL1_MPINT           = 0x0010  ; magic packet interrupt
161
        EXTCTL1_MPINT           = 0x0010  ; magic packet interrupt
162
        EXTCTL1_MPPLBA          = 0x0020  ; magic packet phys. logical bcast
162
        EXTCTL1_MPPLBA          = 0x0020  ; magic packet phys. logical bcast
163
        EXTCTL1_EXDEFEN         = 0x0040  ; excessive deferral interrupt enb.
163
        EXTCTL1_EXDEFEN         = 0x0040  ; excessive deferral interrupt enb.
164
        EXTCTL1_EXDEF           = 0x0080  ; excessive deferral interrupt
164
        EXTCTL1_EXDEF           = 0x0080  ; excessive deferral interrupt
165
        EXTCTL1_SINTEN          = 0x0400  ; system interrupt enable
165
        EXTCTL1_SINTEN          = 0x0400  ; system interrupt enable
166
        EXTCTL1_SINT            = 0x0800  ; system interrupt
166
        EXTCTL1_SINT            = 0x0800  ; system interrupt
167
        EXTCTL1_LTINTEN         = 0x4000  ; last TX interrupt enb
167
        EXTCTL1_LTINTEN         = 0x4000  ; last TX interrupt enb
168
        EXTCTL1_TXOKINTD        = 0x8000  ; TX OK interrupt disable
168
        EXTCTL1_TXOKINTD        = 0x8000  ; TX OK interrupt disable
169
 
169
 
170
; RX/TX descriptor len (CSR6)
170
; RX/TX descriptor len (CSR6)
171
 
171
 
172
        DTBLLEN_RLEN            = 0x0F00
172
        DTBLLEN_RLEN            = 0x0F00
173
        DTBLLEN_TLEN            = 0xF000
173
        DTBLLEN_TLEN            = 0xF000
174
 
174
 
175
; Extended control and interrupt 2 (CSR7)
175
; Extended control and interrupt 2 (CSR7)
176
 
176
 
177
        EXTCTL2_MIIPDTINTE      = 0x0001
177
        EXTCTL2_MIIPDTINTE      = 0x0001
178
        EXTCTL2_MIIPDTINT       = 0x0002
178
        EXTCTL2_MIIPDTINT       = 0x0002
179
        EXTCTL2_MCCIINTE        = 0x0004
179
        EXTCTL2_MCCIINTE        = 0x0004
180
        EXTCTL2_MCCIINT         = 0x0008
180
        EXTCTL2_MCCIINT         = 0x0008
181
        EXTCTL2_MCCINTE         = 0x0010
181
        EXTCTL2_MCCINTE         = 0x0010
182
        EXTCTL2_MCCINT          = 0x0020
182
        EXTCTL2_MCCINT          = 0x0020
183
        EXTCTL2_MAPINTE         = 0x0040
183
        EXTCTL2_MAPINTE         = 0x0040
184
        EXTCTL2_MAPINT          = 0x0080
184
        EXTCTL2_MAPINT          = 0x0080
185
        EXTCTL2_MREINTE         = 0x0100
185
        EXTCTL2_MREINTE         = 0x0100
186
        EXTCTL2_MREINT          = 0x0200
186
        EXTCTL2_MREINT          = 0x0200
187
        EXTCTL2_STINTE          = 0x0400
187
        EXTCTL2_STINTE          = 0x0400
188
        EXTCTL2_STINT           = 0x0800
188
        EXTCTL2_STINT           = 0x0800
189
        EXTCTL2_RXDPOLL         = 0x1000
189
        EXTCTL2_RXDPOLL         = 0x1000
190
        EXTCTL2_RDMD            = 0x2000
190
        EXTCTL2_RDMD            = 0x2000
191
        EXTCTL2_RXFRTG          = 0x4000
191
        EXTCTL2_RXFRTG          = 0x4000
192
        EXTCTL2_FASTSPNDE       = 0x8000
192
        EXTCTL2_FASTSPNDE       = 0x8000
193
 
193
 
194
; Mode (CSR15)
194
; Mode (CSR15)
195
 
195
 
196
        MODE_RXD                = 0x0001  ; RX disable
196
        MODE_RXD                = 0x0001  ; RX disable
197
        MODE_TXD                = 0x0002  ; TX disable
197
        MODE_TXD                = 0x0002  ; TX disable
198
        MODE_LOOP               = 0x0004  ; loopback enable
198
        MODE_LOOP               = 0x0004  ; loopback enable
199
        MODE_TXCRCD             = 0x0008
199
        MODE_TXCRCD             = 0x0008
200
        MODE_FORCECOLL          = 0x0010
200
        MODE_FORCECOLL          = 0x0010
201
        MODE_RETRYD             = 0x0020
201
        MODE_RETRYD             = 0x0020
202
        MODE_INTLOOP            = 0x0040
202
        MODE_INTLOOP            = 0x0040
203
        MODE_PORTSEL            = 0x0180
203
        MODE_PORTSEL            = 0x0180
204
        MODE_RXVPAD             = 0x2000
204
        MODE_RXVPAD             = 0x2000
205
        MODE_RXNOBROAD          = 0x4000
205
        MODE_RXNOBROAD          = 0x4000
206
        MODE_PROMISC            = 0x8000
206
        MODE_PROMISC            = 0x8000
207
 
207
 
208
; BCR (Bus Control Registers)
208
; BCR (Bus Control Registers)
209
 
209
 
210
        BCR_MMRA                = 0x00    ; Master Mode Read Active
210
        BCR_MMRA                = 0x00    ; Master Mode Read Active
211
        BCR_MMW                 = 0x01    ; Master Mode Write Active
211
        BCR_MMW                 = 0x01    ; Master Mode Write Active
212
        BCR_MISCCFG             = 0x02
212
        BCR_MISCCFG             = 0x02
213
        BCR_LED0                = 0x04
213
        BCR_LED0                = 0x04
214
        BCR_LED1                = 0x05
214
        BCR_LED1                = 0x05
215
        BCR_LED2                = 0x06
215
        BCR_LED2                = 0x06
216
        BCR_LED3                = 0x07
216
        BCR_LED3                = 0x07
217
        BCR_DUPLEX              = 0x09
217
        BCR_DUPLEX              = 0x09
218
        BCR_BUSCTL              = 0x12
218
        BCR_BUSCTL              = 0x12
219
        BCR_EECTL               = 0x13
219
        BCR_EECTL               = 0x13
220
        BCR_SSTYLE              = 0x14
220
        BCR_SSTYLE              = 0x14
221
        BCR_PCILAT              = 0x16
221
        BCR_PCILAT              = 0x16
222
        BCR_PCISUBVENID         = 0x17
222
        BCR_PCISUBVENID         = 0x17
223
        BCR_PCISUBSYSID         = 0x18
223
        BCR_PCISUBSYSID         = 0x18
224
        BCR_SRAMSIZE            = 0x19
224
        BCR_SRAMSIZE            = 0x19
225
        BCR_SRAMBOUND           = 0x1A
225
        BCR_SRAMBOUND           = 0x1A
226
        BCR_SRAMCTL             = 0x1B
226
        BCR_SRAMCTL             = 0x1B
227
        BCR_MIICTL              = 0x20
227
        BCR_MIICTL              = 0x20
228
        BCR_MIIADDR             = 0x21
228
        BCR_MIIADDR             = 0x21
229
        BCR_MIIDATA             = 0x22
229
        BCR_MIIDATA             = 0x22
230
        BCR_PCIVENID            = 0x23
230
        BCR_PCIVENID            = 0x23
231
        BCR_PCIPCAP             = 0x24
231
        BCR_PCIPCAP             = 0x24
232
        BCR_DATA0               = 0x25
232
        BCR_DATA0               = 0x25
233
        BCR_DATA1               = 0x26
233
        BCR_DATA1               = 0x26
234
        BCR_DATA2               = 0x27
234
        BCR_DATA2               = 0x27
235
        BCR_DATA3               = 0x28
235
        BCR_DATA3               = 0x28
236
        BCR_DATA4               = 0x29
236
        BCR_DATA4               = 0x29
237
        BCR_DATA5               = 0x2A
237
        BCR_DATA5               = 0x2A
238
        BCR_DATA6               = 0x2B
238
        BCR_DATA6               = 0x2B
239
        BCR_DATA7               = 0x2C
239
        BCR_DATA7               = 0x2C
240
        BCR_ONNOWPAT0           = 0x2D
240
        BCR_ONNOWPAT0           = 0x2D
241
        BCR_ONNOWPAT1           = 0x2E
241
        BCR_ONNOWPAT1           = 0x2E
242
        BCR_ONNOWPAT2           = 0x2F
242
        BCR_ONNOWPAT2           = 0x2F
243
        BCR_PHYSEL              = 0x31
243
        BCR_PHYSEL              = 0x31
244
 
244
 
245
; RX status register
245
; RX status register
246
 
246
 
247
        RXSTAT_BPE              = 0x0080        ; bus parity error
247
        RXSTAT_BPE              = 0x0080        ; bus parity error
248
        RXSTAT_ENP              = 0x0100        ; end of packet
248
        RXSTAT_ENP              = 0x0100        ; end of packet
249
        RXSTAT_STP              = 0x0200        ; start of packet
249
        RXSTAT_STP              = 0x0200        ; start of packet
250
        RXSTAT_BUFF             = 0x0400        ; buffer error
250
        RXSTAT_BUFF             = 0x0400        ; buffer error
251
        RXSTAT_CRC              = 0x0800        ; CRC error
251
        RXSTAT_CRC              = 0x0800        ; CRC error
252
        RXSTAT_OFLOW            = 0x1000        ; rx overrun
252
        RXSTAT_OFLOW            = 0x1000        ; rx overrun
253
        RXSTAT_FRAM             = 0x2000        ; framing error
253
        RXSTAT_FRAM             = 0x2000        ; framing error
254
        RXSTAT_ERR              = 0x4000        ; error summary
254
        RXSTAT_ERR              = 0x4000        ; error summary
255
        RXSTAT_OWN              = 0x8000
255
        RXSTAT_OWN              = 0x8000
256
 
256
 
257
; TX status register
257
; TX status register
258
 
258
 
259
        TXSTAT_TRC              = 0x0000000F    ; transmit retries
259
        TXSTAT_TRC              = 0x0000000F    ; transmit retries
260
        TXSTAT_RTRY             = 0x04000000    ; retry
260
        TXSTAT_RTRY             = 0x04000000    ; retry
261
        TXSTAT_LCAR             = 0x08000000    ; lost carrier
261
        TXSTAT_LCAR             = 0x08000000    ; lost carrier
262
        TXSTAT_LCOL             = 0x10000000    ; late collision
262
        TXSTAT_LCOL             = 0x10000000    ; late collision
263
        TXSTAT_EXDEF            = 0x20000000    ; excessive deferrals
263
        TXSTAT_EXDEF            = 0x20000000    ; excessive deferrals
264
        TXSTAT_UFLOW            = 0x40000000    ; transmit underrun
264
        TXSTAT_UFLOW            = 0x40000000    ; transmit underrun
265
        TXSTAT_BUFF             = 0x80000000    ; buffer error
265
        TXSTAT_BUFF             = 0x80000000    ; buffer error
266
 
266
 
267
        TXCTL_OWN               = 0x8000
267
        TXCTL_OWN               = 0x8000
268
        TXCTL_ERR               = 0x4000        ; error summary
268
        TXCTL_ERR               = 0x4000        ; error summary
269
        TXCTL_ADD_FCS           = 0x2000        ; add FCS to pkt
269
        TXCTL_ADD_FCS           = 0x2000        ; add FCS to pkt
270
        TXCTL_MORE_LTINT        = 0x1000
270
        TXCTL_MORE_LTINT        = 0x1000
271
        TXCTL_ONE               = 0x0800
271
        TXCTL_ONE               = 0x0800
272
        TXCTL_DEF               = 0x0400
272
        TXCTL_DEF               = 0x0400
273
        TXCTL_STP               = 0x0200
273
        TXCTL_STP               = 0x0200
274
        TXCTL_ENP               = 0x0100
274
        TXCTL_ENP               = 0x0100
275
        TXCTL_BPE               = 0x0080
275
        TXCTL_BPE               = 0x0080
276
 
276
 
277
        TXCTL_MBO               = 0x0000F000
277
        TXCTL_MBO               = 0x0000F000
278
        TXCTL_BUFSZ             = 0x00000FFF
278
        TXCTL_BUFSZ             = 0x00000FFF
279
 
279
 
280
        MAX_PHYS                = 32
280
        MAX_PHYS                = 32
281
 
281
 
282
 
282
 
283
struct  device          ETH_DEVICE
283
struct  device          ETH_DEVICE
284
 
284
 
285
        rb 0x100-($ and 0xff)   ; align 256
285
        rb 0x100-($ and 0xff)   ; align 256
286
 
286
 
287
; Pcnet configuration structure
287
; Pcnet configuration structure
288
        mode            dw ?
288
        mode            dw ?
289
        tlen_rlen       dw ?
289
        tlen_rlen       dw ?
290
        phys_addr       dp ?
290
        phys_addr       dp ?
291
        reserved        dw ?
291
        reserved        dw ?
292
        filter          dq ?
292
        filter          dq ?
293
        rx_ring_phys    dd ?
293
        rx_ring_phys    dd ?
294
        tx_ring_phys    dd ?
294
        tx_ring_phys    dd ?
295
; end of pcnet config struct
295
; end of pcnet config struct
296
 
296
 
297
        rb 0x100-($ and 0xff)   ; align 256
297
        rb 0x100-($ and 0xff)   ; align 256
298
 
298
 
299
        rx_ring         rb RX_RING_SIZE * sizeof.descriptor
299
        rx_ring         rb RX_RING_SIZE * sizeof.descriptor
300
 
300
 
301
        rb 0x100-($ and 0xff)   ; align 256
301
        rb 0x100-($ and 0xff)   ; align 256
302
 
302
 
303
        tx_ring         rb TX_RING_SIZE * sizeof.descriptor
303
        tx_ring         rb TX_RING_SIZE * sizeof.descriptor
304
 
304
 
305
        cur_rx          db ?
305
        cur_rx          db ?
306
        cur_tx          db ?
306
        cur_tx          db ?
307
        last_tx         db ?
307
        last_tx         db ?
308
        options         dd ?
308
        options         dd ?
309
        full_duplex     db ?
309
        full_duplex     db ?
310
        chip_version    dw ?
310
        chip_version    dw ?
311
        mii             db ?
311
        mii             db ?
312
        ltint           db ?
312
        ltint           db ?
313
        dxsuflo         db ?
313
        dxsuflo         db ?
314
        fset            db ?
314
        fset            db ?
315
        fdx             db ?
315
        fdx             db ?
316
 
316
 
317
        io_addr         dd ?
317
        io_addr         dd ?
318
        irq_line        db ?
318
        irq_line        db ?
319
        pci_bus         dd ?
319
        pci_bus         dd ?
320
        pci_dev         dd ?
320
        pci_dev         dd ?
321
 
321
 
322
        phy             dw ?
322
        phy             dw ?
323
 
323
 
324
        read_csr        dd ?
324
        read_csr        dd ?
325
        write_csr       dd ?
325
        write_csr       dd ?
326
        read_bcr        dd ?
326
        read_bcr        dd ?
327
        write_bcr       dd ?
327
        write_bcr       dd ?
328
        read_rap        dd ?
328
        read_rap        dd ?
329
        write_rap       dd ?
329
        write_rap       dd ?
330
        sw_reset        dd ?
330
        sw_reset        dd ?
331
 
331
 
332
ends
332
ends
333
 
333
 
334
struct  descriptor
334
struct  descriptor
335
 
335
 
336
        base            dd ?
336
        base            dd ?
337
        length          dw ?
337
        length          dw ?
338
        status          dw ?
338
        status          dw ?
339
        msg_length      dw ?
339
        msg_length      dw ?
340
        misc            dw ?
340
        misc            dw ?
341
        virtual         dd ?
341
        virtual         dd ?
342
 
342
 
343
ends
343
ends
344
 
344
 
345
 
345
 
346
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
347
;;                        ;;
347
;;                        ;;
348
;; proc START             ;;
348
;; proc START             ;;
349
;;                        ;;
349
;;                        ;;
350
;; (standard driver proc) ;;
350
;; (standard driver proc) ;;
351
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
351
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352
 
352
 
353
proc START c, reason:dword, cmdline:dword
353
proc START c, reason:dword, cmdline:dword
354
 
354
 
355
        cmp     [reason], DRV_ENTRY
355
        cmp     [reason], DRV_ENTRY
356
        jne     .fail
356
        jne     .fail
357
 
357
 
358
        DEBUGF  2,"Loading driver\n"
358
        DEBUGF  2,"Loading driver\n"
359
        invoke  RegService, my_service, service_proc
359
        invoke  RegService, my_service, service_proc
360
        ret
360
        ret
361
 
361
 
362
  .fail:
362
  .fail:
363
        xor eax, eax
363
        xor eax, eax
364
        ret
364
        ret
365
 
365
 
366
endp
366
endp
367
 
367
 
368
 
368
 
369
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370
;;                        ;;
370
;;                        ;;
371
;; proc SERVICE_PROC      ;;
371
;; proc SERVICE_PROC      ;;
372
;;                        ;;
372
;;                        ;;
373
;; (standard driver proc) ;;
373
;; (standard driver proc) ;;
374
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
374
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
375
 
375
 
376
align 4
376
align 4
377
proc service_proc stdcall, ioctl:dword
377
proc service_proc stdcall, ioctl:dword
378
 
378
 
379
        mov     edx, [ioctl]
379
        mov     edx, [ioctl]
380
        mov     eax, [edx + IOCTL.io_code]
380
        mov     eax, [edx + IOCTL.io_code]
381
 
381
 
382
;------------------------------------------------------
382
;------------------------------------------------------
383
 
383
 
384
        cmp     eax, 0 ;SRV_GETVERSION
384
        cmp     eax, 0 ;SRV_GETVERSION
385
        jne     @F
385
        jne     @F
386
 
386
 
387
        cmp     [edx + IOCTL.out_size], 4
387
        cmp     [edx + IOCTL.out_size], 4
388
        jb      .fail
388
        jb      .fail
389
        mov     eax, [edx + IOCTL.output]
389
        mov     eax, [edx + IOCTL.output]
390
        mov     [eax], dword API_VERSION
390
        mov     [eax], dword API_VERSION
391
 
391
 
392
        xor     eax, eax
392
        xor     eax, eax
393
        ret
393
        ret
394
 
394
 
395
;------------------------------------------------------
395
;------------------------------------------------------
396
  @@:
396
  @@:
397
        cmp     eax, 1 ;SRV_HOOK
397
        cmp     eax, 1 ;SRV_HOOK
398
        jne     .fail
398
        jne     .fail
399
 
399
 
400
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
400
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
401
        jb      .fail
401
        jb      .fail
402
 
402
 
403
        mov     eax, [edx + IOCTL.input]
403
        mov     eax, [edx + IOCTL.input]
404
        cmp     byte[eax], 1                            ; 1 means device number and bus number (pci) are given
404
        cmp     byte[eax], 1                            ; 1 means device number and bus number (pci) are given
405
        jne     .fail                                   ; other types arent supported for this card yet
405
        jne     .fail                                   ; other types arent supported for this card yet
406
 
406
 
407
; check if the device is already listed
407
; check if the device is already listed
408
 
408
 
409
        mov     ecx, [devices]
409
        mov     ecx, [devices]
410
        test    ecx, ecx
410
        test    ecx, ecx
411
        jz      .firstdevice
411
        jz      .firstdevice
412
 
412
 
413
        mov     esi, device_list
413
        mov     esi, device_list
414
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
414
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
415
        mov     ax, [eax+1]                             ;
415
        mov     ax, [eax+1]                             ;
416
  .nextdevice:
416
  .nextdevice:
417
        mov     ebx, [esi]
417
        mov     ebx, [esi]
418
        cmp     al, byte[ebx + device.pci_bus]
418
        cmp     al, byte[ebx + device.pci_bus]
419
        jne     @f
419
        jne     @f
420
        cmp     ah, byte[ebx + device.pci_dev]
420
        cmp     ah, byte[ebx + device.pci_dev]
421
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
421
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
422
       @@:
422
       @@:
423
        add     esi, 4
423
        add     esi, 4
424
        loop    .nextdevice
424
        loop    .nextdevice
425
 
425
 
426
; This device doesnt have its own eth_device structure yet, lets create one
426
; This device doesnt have its own eth_device structure yet, lets create one
427
 
427
 
428
  .firstdevice:
428
  .firstdevice:
429
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
429
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
430
        jae     .fail
430
        jae     .fail
431
 
431
 
432
        allocate_and_clear ebx, sizeof.device, .fail
432
        allocate_and_clear ebx, sizeof.device, .fail
433
 
433
 
434
; Fill in the direct call addresses into the struct
434
; Fill in the direct call addresses into the struct
435
 
435
 
436
        mov     [ebx + device.reset], reset
436
        mov     [ebx + device.reset], reset
437
        mov     [ebx + device.transmit], transmit
437
        mov     [ebx + device.transmit], transmit
438
        mov     [ebx + device.unload], unload
438
        mov     [ebx + device.unload], unload
439
        mov     [ebx + device.name], my_service
439
        mov     [ebx + device.name], my_service
440
 
440
 
441
; save the pci bus and device numbers
441
; save the pci bus and device numbers
442
 
442
 
443
        mov     eax, [edx + IOCTL.input]
443
        mov     eax, [edx + IOCTL.input]
444
        movzx   ecx, byte[eax+1]
444
        movzx   ecx, byte[eax+1]
445
        mov     [ebx + device.pci_bus], ecx
445
        mov     [ebx + device.pci_bus], ecx
446
        movzx   ecx, byte[eax+2]
446
        movzx   ecx, byte[eax+2]
447
        mov     [ebx + device.pci_dev], ecx
447
        mov     [ebx + device.pci_dev], ecx
448
 
448
 
449
; Now, it's time to find the base io addres of the PCI device
449
; Now, it's time to find the base io addres of the PCI device
450
 
450
 
451
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
451
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
452
        mov     [ebx + device.io_addr], eax
452
        mov     [ebx + device.io_addr], eax
453
 
453
 
454
; We've found the io address, find IRQ now
454
; We've found the io address, find IRQ now
455
 
455
 
456
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
456
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
457
        mov     [ebx + device.irq_line], al
457
        mov     [ebx + device.irq_line], al
458
 
458
 
459
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
459
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
460
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
460
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
461
 
461
 
462
; Ok, the eth_device structure is ready, let's probe the device
462
; Ok, the eth_device structure is ready, let's probe the device
463
; Because initialization fires IRQ, IRQ handler must be aware of this device
463
; Because initialization fires IRQ, IRQ handler must be aware of this device
464
        mov     eax, [devices]                                          ; Add the device structure to our device list
464
        mov     eax, [devices]                                          ; Add the device structure to our device list
465
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
465
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
466
        inc     [devices]                                               ;
466
        inc     [devices]                                               ;
467
 
467
 
468
        call    probe                                                   ; this function will output in eax
468
        call    probe                                                   ; this function will output in eax
469
        test    eax, eax
469
        test    eax, eax
470
        jnz     .destroy                                                ; If an error occured, exit
470
        jnz     .destroy                                                ; If an error occured, exit
471
 
471
 
472
        mov     [ebx + device.type], NET_TYPE_ETH
472
        mov     [ebx + device.type], NET_TYPE_ETH
473
        invoke  NetRegDev
473
        invoke  NetRegDev
474
        cmp     eax, -1
474
        cmp     eax, -1
475
        je      .destroy
475
        je      .destroy
476
 
476
 
477
        ret
477
        ret
478
 
478
 
479
; If the device was already loaded, find the device number and return it in eax
479
; If the device was already loaded, find the device number and return it in eax
480
 
480
 
481
  .find_devicenum:
481
  .find_devicenum:
482
        DEBUGF  1,"Trying to find device number of already registered device\n"
482
        DEBUGF  1,"Trying to find device number of already registered device\n"
483
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
483
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
484
                                                                        ; into a device number in edi
484
                                                                        ; into a device number in edi
485
        mov     eax, edi                                                ; Application wants it in eax instead
485
        mov     eax, edi                                                ; Application wants it in eax instead
486
        DEBUGF  1,"Kernel says: %u\n", eax
486
        DEBUGF  1,"Kernel says: %u\n", eax
487
        ret
487
        ret
488
 
488
 
489
; If an error occured, remove all allocated data and exit (returning -1 in eax)
489
; If an error occured, remove all allocated data and exit (returning -1 in eax)
490
 
490
 
491
  .destroy:
491
  .destroy:
492
        ; todo: reset device into virgin state
492
        ; todo: reset device into virgin state
493
 
493
 
494
        dec     [devices]
494
        dec     [devices]
495
  .err:
495
  .err:
496
        DEBUGF  2,"Error, removing all data !\n"
496
        DEBUGF  2,"Error, removing all data !\n"
497
        invoke  KernelFree, ebx
497
        invoke  KernelFree, ebx
498
 
498
 
499
  .fail:
499
  .fail:
500
        or      eax, -1
500
        or      eax, -1
501
        ret
501
        ret
502
 
502
 
503
;------------------------------------------------------
503
;------------------------------------------------------
504
endp
504
endp
505
 
505
 
506
 
506
 
507
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
507
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
508
;;                                                                        ;;
508
;;                                                                        ;;
509
;;        Actual Hardware dependent code starts here                      ;;
509
;;        Actual Hardware dependent code starts here                      ;;
510
;;                                                                        ;;
510
;;                                                                        ;;
511
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
511
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
512
 
512
 
513
align 4
513
align 4
514
unload:
514
unload:
515
        ; TODO: (in this particular order)
515
        ; TODO: (in this particular order)
516
        ;
516
        ;
517
        ; - Stop the device
517
        ; - Stop the device
518
        ; - Detach int handler
518
        ; - Detach int handler
519
        ; - Remove device from local list (device_list)
519
        ; - Remove device from local list (device_list)
520
        ; - call unregister function in kernel
520
        ; - call unregister function in kernel
521
        ; - Remove all allocated structures and buffers the card used
521
        ; - Remove all allocated structures and buffers the card used
522
 
522
 
523
        or      eax,-1
523
        or      eax,-1
524
 
524
 
525
ret
525
ret
526
 
526
 
527
 
527
 
528
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
528
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
529
;;
529
;;
530
;;  probe: enables the device (if it really is a PCnet device)
530
;;  probe: enables the device (if it really is a PCnet device)
531
;;
531
;;
532
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
532
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
533
 
533
 
534
align 4
534
align 4
535
probe:
535
probe:
536
 
536
 
537
        mov     edx, [ebx + device.io_addr]
537
        mov     edx, [ebx + device.io_addr]
538
 
538
 
539
        call    wio_reset
539
        call    wio_reset
540
 
540
 
541
        xor     ecx, ecx
541
        xor     ecx, ecx
542
        call    wio_read_csr
542
        call    wio_read_csr
543
        cmp     eax, 4
543
        cmp     eax, 4
544
        jne     .try_dwio
544
        jne     .try_dwio
545
 
545
 
546
        ; Try Word I/O
546
        ; Try Word I/O
547
        mov     ax, 88
547
        mov     ax, 88
548
        add     edx, WIO_RAP
548
        add     edx, WIO_RAP
549
        out     dx, ax
549
        out     dx, ax
550
        nop
550
        nop
551
        nop
551
        nop
552
        in      ax, dx
552
        in      ax, dx
553
        sub     edx, WIO_RAP
553
        sub     edx, WIO_RAP
554
        cmp     ax, 88
554
        cmp     ax, 88
555
        jne     .try_dwio
555
        jne     .try_dwio
556
 
556
 
557
        call    switch_to_wio
557
        call    switch_to_wio
558
 
558
 
559
        jmp     .L1
559
        jmp     .L1
560
 
560
 
561
  .try_dwio:
561
  .try_dwio:
562
        call    dwio_reset
562
        call    dwio_reset
563
 
563
 
564
        xor     ecx, ecx
564
        xor     ecx, ecx
565
        call    dwio_read_csr
565
        call    dwio_read_csr
566
        cmp     eax, 4
566
        cmp     eax, 4
567
        jne     .no_dev
567
        jne     .no_dev
568
 
568
 
569
        ; Try Dword I/O
569
        ; Try Dword I/O
570
        add     edx, DWIO_RAP
570
        add     edx, DWIO_RAP
571
        mov     eax, 88
571
        mov     eax, 88
572
        out     dx, eax
572
        out     dx, eax
573
        nop
573
        nop
574
        nop
574
        nop
575
        in      eax, dx
575
        in      eax, dx
576
        sub     edx, DWIO_RAP
576
        sub     edx, DWIO_RAP
577
        and     eax, 0xffff
577
        and     eax, 0xffff
578
        cmp     eax, 88
578
        cmp     eax, 88
579
        jne     .no_dev
579
        jne     .no_dev
580
 
580
 
581
        call    switch_to_dwio
581
        call    switch_to_dwio
582
 
582
 
583
        jmp     .L1
583
        jmp     .L1
584
 
584
 
585
  .no_dev:
585
  .no_dev:
586
        DEBUGF  2,"device not found!\n"
586
        DEBUGF  2,"device not found!\n"
587
        mov     eax, 1
587
        mov     eax, 1
588
        ret
588
        ret
589
 
589
 
590
  .L1:
590
  .L1:
591
        mov     ecx, CSR_CHIPID0
591
        mov     ecx, CSR_CHIPID0
592
        call    [ebx + device.read_csr]
592
        call    [ebx + device.read_csr]
593
 
593
 
594
        mov     esi, eax
594
        mov     esi, eax
595
        shr     esi, 12
595
        shr     esi, 12
596
 
596
 
597
        and     ax, 0xfff
597
        and     ax, 0xfff
598
        cmp     ax, 3
598
        cmp     ax, 3
599
        jne     .no_dev
599
        jne     .no_dev
600
 
600
 
601
        mov     ecx, CSR_CHIPID1
601
        mov     ecx, CSR_CHIPID1
602
        call    [ebx + device.read_csr]
602
        call    [ebx + device.read_csr]
603
        shl     eax, 4
603
        shl     eax, 4
604
        or      eax, esi
604
        or      eax, esi
605
        mov     [ebx + device.chip_version], ax
605
        mov     [ebx + device.chip_version], ax
606
 
606
 
607
        mov     [ebx + device.fdx], 0
607
        mov     [ebx + device.fdx], 0
608
        mov     [ebx + device.mii], 0
608
        mov     [ebx + device.mii], 0
609
        mov     [ebx + device.fset], 0
609
        mov     [ebx + device.fset], 0
610
        mov     [ebx + device.dxsuflo], 0
610
        mov     [ebx + device.dxsuflo], 0
611
        mov     [ebx + device.ltint], 0
611
        mov     [ebx + device.ltint], 0
612
 
612
 
613
        cmp     ax, 0x2420
613
        cmp     ax, 0x2420
614
        je      .L2
614
        je      .L2
615
        cmp     ax, 0x2430
615
        cmp     ax, 0x2430
616
        je      .L2
616
        je      .L2
617
 
617
 
618
        mov     [ebx + device.fdx], 1
618
        mov     [ebx + device.fdx], 1
619
 
619
 
620
        cmp     ax, 0x2621
620
        cmp     ax, 0x2621
621
        je      .L4
621
        je      .L4
622
        cmp     ax, 0x2623
622
        cmp     ax, 0x2623
623
        je      .L5
623
        je      .L5
624
        cmp     ax, 0x2624
624
        cmp     ax, 0x2624
625
        je      .L6
625
        je      .L6
626
        cmp     ax, 0x2625
626
        cmp     ax, 0x2625
627
        je      .L7
627
        je      .L7
628
        cmp     ax, 0x2626
628
        cmp     ax, 0x2626
629
        je      .L8
629
        je      .L8
630
        cmp     ax, 0x2627
630
        cmp     ax, 0x2627
631
        je      .L9
631
        je      .L9
632
 
632
 
633
        DEBUGF  1,"Invalid chip rev\n"
633
        DEBUGF  1,"Invalid chip rev\n"
634
        jmp     .no_dev
634
        jmp     .no_dev
635
  .L2:
635
  .L2:
636
        mov     [ebx + device.name], device_l2
636
        mov     [ebx + device.name], device_l2
637
        jmp     .L10
637
        jmp     .L10
638
  .L4:
638
  .L4:
639
        mov     [ebx + device.name], device_l4
639
        mov     [ebx + device.name], device_l4
640
;        mov     [ebx + device.fdx], 1
640
;        mov     [ebx + device.fdx], 1
641
        jmp     .L10
641
        jmp     .L10
642
  .L5:
642
  .L5:
643
        mov     [ebx + device.name], device_l5
643
        mov     [ebx + device.name], device_l5
644
;        mov     [ebx + device.fdx], 1
644
;        mov     [ebx + device.fdx], 1
645
        mov     [ebx + device.mii], 1
645
        mov     [ebx + device.mii], 1
646
        mov     [ebx + device.fset], 1
646
        mov     [ebx + device.fset], 1
647
        mov     [ebx + device.ltint], 1
647
        mov     [ebx + device.ltint], 1
648
        jmp     .L10
648
        jmp     .L10
649
  .L6:
649
  .L6:
650
        mov     [ebx + device.name], device_l6
650
        mov     [ebx + device.name], device_l6
651
;        mov     [ebx + device.fdx], 1
651
;        mov     [ebx + device.fdx], 1
652
        mov     [ebx + device.mii], 1
652
        mov     [ebx + device.mii], 1
653
        mov     [ebx + device.fset], 1
653
        mov     [ebx + device.fset], 1
654
        jmp     .L10
654
        jmp     .L10
655
  .L7:
655
  .L7:
656
        mov     [ebx + device.name], device_l7
656
        mov     [ebx + device.name], device_l7
657
;        mov     [ebx + device.fdx], 1
657
;        mov     [ebx + device.fdx], 1
658
        mov     [ebx + device.mii], 1
658
        mov     [ebx + device.mii], 1
659
        jmp     .L10
659
        jmp     .L10
660
  .L8:
660
  .L8:
661
        mov     [ebx + device.name], device_l8
661
        mov     [ebx + device.name], device_l8
662
;        mov     [ebx + device.fdx], 1
662
;        mov     [ebx + device.fdx], 1
663
        mov     ecx, CSR_RXPOLL
663
        mov     ecx, CSR_RXPOLL
664
        call    dword [ebx + device.read_bcr]
664
        call    dword [ebx + device.read_bcr]
665
        call    dword [ebx + device.write_bcr]
665
        call    dword [ebx + device.write_bcr]
666
        jmp     .L10
666
        jmp     .L10
667
  .L9:
667
  .L9:
668
        mov     [ebx + device.name], device_l9
668
        mov     [ebx + device.name], device_l9
669
;        mov     [ebx + device.fdx], 1
669
;        mov     [ebx + device.fdx], 1
670
        mov     [ebx + device.mii], 1
670
        mov     [ebx + device.mii], 1
671
  .L10:
671
  .L10:
672
        DEBUGF  1,"device name: %s\n", [ebx + device.name]
672
        DEBUGF  1,"device name: %s\n", [ebx + device.name]
673
 
673
 
674
        cmp     [ebx + device.fset], 1
674
        cmp     [ebx + device.fset], 1
675
        jne     .L11
675
        jne     .L11
676
        mov     ecx, BCR_BUSCTL
676
        mov     ecx, BCR_BUSCTL
677
        call    [ebx + device.read_bcr]
677
        call    [ebx + device.read_bcr]
678
        or      eax, 0x800
678
        or      eax, 0x800
679
        call    [ebx + device.write_bcr]
679
        call    [ebx + device.write_bcr]
680
 
680
 
681
        mov     ecx, CSR_DMACTL
681
        mov     ecx, CSR_DMACTL
682
        call    [ebx + device.read_csr]
682
        call    [ebx + device.read_csr]
683
;        and     eax, 0xc00
683
;        and     eax, 0xc00
684
;        or      eax, 0xc00
684
;        or      eax, 0xc00
685
        mov     eax, 0xc00
685
        mov     eax, 0xc00
686
        call    [ebx + device.write_csr]
686
        call    [ebx + device.write_csr]
687
 
687
 
688
        mov     [ebx + device.dxsuflo],1
688
        mov     [ebx + device.dxsuflo],1
689
        mov     [ebx + device.ltint],1
689
        mov     [ebx + device.ltint],1
690
  .L11:
690
  .L11:
691
 
691
 
692
; Make the device a bus master
692
; Make the device a bus master
693
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
693
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
694
        or      al, PCI_CMD_MASTER
694
        or      al, PCI_CMD_MASTER
695
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
695
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
696
 
696
 
697
        mov     [ebx + device.options], PORT_ASEL
697
        mov     [ebx + device.options], PORT_ASEL
698
        mov     [ebx + device.mode], MODE_RXD + MODE_TXD     ; disable receive and transmit
698
        mov     [ebx + device.mode], MODE_RXD + MODE_TXD     ; disable receive and transmit
699
        mov     [ebx + device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
699
        mov     [ebx + device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
700
 
700
 
701
        mov     dword[ebx + device.filter], 0
701
        mov     dword[ebx + device.filter], 0
702
        mov     dword[ebx + device.filter+4], 0
702
        mov     dword[ebx + device.filter+4], 0
703
 
703
 
704
align 4
704
align 4
705
reset:
705
reset:
706
 
706
 
707
; attach int handler
707
; attach int handler
708
 
708
 
709
        movzx   eax, [ebx + device.irq_line]
709
        movzx   eax, [ebx + device.irq_line]
710
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
710
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
711
        invoke  AttachIntHandler, eax, int_handler, ebx
711
        invoke  AttachIntHandler, eax, int_handler, ebx
712
        test    eax, eax
712
        test    eax, eax
713
        jnz     @f
713
        jnz     @f
714
        DEBUGF  2,"Could not attach int handler!\n"
714
        DEBUGF  2,"Could not attach int handler!\n"
715
        or      eax, -1
715
        or      eax, -1
716
        ret
716
        ret
717
  @@:
717
  @@:
718
 
718
 
719
        mov     edx, [ebx + device.io_addr]
719
        mov     edx, [ebx + device.io_addr]
720
        call    [ebx + device.sw_reset]
720
        call    [ebx + device.sw_reset]
721
 
721
 
722
        ; Switch pcnet32 to 32bit mode
722
        ; Switch pcnet32 to 32bit mode
723
        mov     ecx, BCR_SSTYLE
723
        mov     ecx, BCR_SSTYLE
724
        mov     eax, 2
724
        mov     eax, 2
725
        call    [ebx + device.write_bcr]
725
        call    [ebx + device.write_bcr]
726
 
726
 
727
        ; set/reset autoselect bit
727
        ; set/reset autoselect bit
728
        mov     ecx, BCR_MISCCFG
728
        mov     ecx, BCR_MISCCFG
729
        call    [ebx + device.read_bcr]
729
        call    [ebx + device.read_bcr]
730
        and     eax, not 2
730
        and     eax, not 2
731
        test    [ebx + device.options], PORT_ASEL
731
        test    [ebx + device.options], PORT_ASEL
732
        jz      @f
732
        jz      @f
733
        or      eax, 2
733
        or      eax, 2
734
  @@:
734
  @@:
735
        call    [ebx + device.write_bcr]
735
        call    [ebx + device.write_bcr]
736
 
736
 
737
        ; Handle full duplex setting
737
        ; Handle full duplex setting
738
        cmp     byte [ebx + device.full_duplex], 0
738
        cmp     byte [ebx + device.full_duplex], 0
739
        je      .duplex_ok
739
        je      .duplex_ok
740
        mov     ecx, BCR_DUPLEX
740
        mov     ecx, BCR_DUPLEX
741
        call    [ebx + device.read_bcr]
741
        call    [ebx + device.read_bcr]
742
        and     eax, not 3
742
        and     eax, not 3
743
        test    [ebx + device.options], PORT_FD
743
        test    [ebx + device.options], PORT_FD
744
        jz      @f
744
        jz      @f
745
        or      eax, 1
745
        or      eax, 1
746
        cmp     [ebx + device.options], PORT_FD or PORT_AUI
746
        cmp     [ebx + device.options], PORT_FD or PORT_AUI
747
        jne     .set_duplex
747
        jne     .set_duplex
748
        or      eax, 2
748
        or      eax, 2
749
        jmp     .set_duplex
749
        jmp     .set_duplex
750
  @@:
750
  @@:
751
        test    [ebx + device.options], PORT_ASEL
751
        test    [ebx + device.options], PORT_ASEL
752
        jz      .set_duplex
752
        jz      .set_duplex
753
        cmp     [ebx + device.chip_version], 0x2627
753
        cmp     [ebx + device.chip_version], 0x2627
754
        jne     .set_duplex
754
        jne     .set_duplex
755
        or      eax, 3
755
        or      eax, 3
756
  .set_duplex:
756
  .set_duplex:
757
        mov     ecx, BCR_DUPLEX
757
        mov     ecx, BCR_DUPLEX
758
        call    [ebx + device.write_bcr]
758
        call    [ebx + device.write_bcr]
759
  .duplex_ok:
759
  .duplex_ok:
760
 
760
 
761
        ; set/reset GPSI bit in test register
761
        ; set/reset GPSI bit in test register
762
        mov     ecx, 124
762
        mov     ecx, 124
763
        call    [ebx + device.read_csr]
763
        call    [ebx + device.read_csr]
764
        mov     ecx, [ebx + device.options]
764
        mov     ecx, [ebx + device.options]
765
        and     ecx, PORT_PORTSEL
765
        and     ecx, PORT_PORTSEL
766
        cmp     ecx, PORT_GPSI
766
        cmp     ecx, PORT_GPSI
767
        jne     @f
767
        jne     @f
768
        or      eax, 0x10
768
        or      eax, 0x10
769
  @@:
769
  @@:
770
        call    [ebx + device.write_csr]
770
        call    [ebx + device.write_csr]
771
        cmp     [ebx + device.mii], 0
771
        cmp     [ebx + device.mii], 0
772
        je      .L6
772
        je      .L6
773
        test    [ebx + device.options], PORT_ASEL
773
        test    [ebx + device.options], PORT_ASEL
774
        jnz     .L6
774
        jnz     .L6
775
        mov     ecx, BCR_MIICTL
775
        mov     ecx, BCR_MIICTL
776
        call    [ebx + device.read_bcr]
776
        call    [ebx + device.read_bcr]
777
        and     eax, not 0x38
777
        and     eax, not 0x38
778
        test    [ebx + device.options], PORT_FD
778
        test    [ebx + device.options], PORT_FD
779
        jz      @f
779
        jz      @f
780
        or      eax, 0x10
780
        or      eax, 0x10
781
  @@:
781
  @@:
782
        test    [ebx + device.options], PORT_100
782
        test    [ebx + device.options], PORT_100
783
        jz      @f
783
        jz      @f
784
        or      eax, 0x08
784
        or      eax, 0x08
785
  @@:
785
  @@:
786
        call    [ebx + device.write_bcr]
786
        call    [ebx + device.write_bcr]
787
        jmp     .L9
787
        jmp     .L9
788
  .L6:
788
  .L6:
789
        test    [ebx + device.options], PORT_ASEL
789
        test    [ebx + device.options], PORT_ASEL
790
        jz      .L9
790
        jz      .L9
791
        mov     ecx, BCR_MIICTL
791
        mov     ecx, BCR_MIICTL
792
        DEBUGF  1,"ASEL, enable auto-negotiation\n"
792
        DEBUGF  1,"ASEL, enable auto-negotiation\n"
793
        call    [ebx + device.read_bcr]
793
        call    [ebx + device.read_bcr]
794
        and     eax, not 0x98
794
        and     eax, not 0x98
795
        or      eax, 0x20
795
        or      eax, 0x20
796
        call    [ebx + device.write_bcr]
796
        call    [ebx + device.write_bcr]
797
  .L9:
797
  .L9:
798
        cmp     [ebx + device.ltint], 0
798
        cmp     [ebx + device.ltint], 0
799
        je      @f
799
        je      @f
800
        mov     ecx, 5
800
        mov     ecx, 5
801
        call    [ebx + device.read_csr]
801
        call    [ebx + device.read_csr]
802
        or      eax, (1 shl 14)
802
        or      eax, (1 shl 14)
803
        call    [ebx + device.write_csr]
803
        call    [ebx + device.write_csr]
804
  @@:
804
  @@:
805
        mov     eax, [ebx + device.options]
805
        mov     eax, [ebx + device.options]
806
        and     eax, PORT_PORTSEL
806
        and     eax, PORT_PORTSEL
807
        shl     eax, 7
807
        shl     eax, 7
808
        mov     [ebx + device.mode], ax
808
        mov     [ebx + device.mode], ax
809
        mov     dword [ebx + device.filter], -1
809
        mov     dword [ebx + device.filter], -1
810
        mov     dword [ebx + device.filter+4], -1
810
        mov     dword [ebx + device.filter+4], -1
811
 
811
 
812
 
812
 
813
 
813
 
814
;-----------------------------
814
;-----------------------------
815
 
815
 
816
        test    [ebx + device.mii], 1
816
        test    [ebx + device.mii], 1
817
        jz      .no_mii
817
        jz      .no_mii
818
 
818
 
819
        mov     [ebx + device.phy], 0
819
        mov     [ebx + device.phy], 0
820
 
820
 
821
  .mii_loop:
821
  .mii_loop:
822
        mov     ecx, MII_PHYSID1
822
        mov     ecx, MII_PHYSID1
823
        call    mdio_read
823
        call    mdio_read
824
        cmp     ax, 0xffff
824
        cmp     ax, 0xffff
825
        je      .next
825
        je      .next
826
 
826
 
827
        DEBUGF  1, "0x%x\n", ax
827
        DEBUGF  1, "0x%x\n", ax
828
 
828
 
829
        mov     ecx, MII_PHYSID2
829
        mov     ecx, MII_PHYSID2
830
        call    mdio_read
830
        call    mdio_read
831
        cmp     ax, 0xffff
831
        cmp     ax, 0xffff
832
        je      .next
832
        je      .next
833
 
833
 
834
        DEBUGF  1, "0x%x\n", ax
834
        DEBUGF  1, "0x%x\n", ax
835
 
835
 
836
        jmp     .got_phy
836
        jmp     .got_phy
837
 
837
 
838
        cmp     [ebx + device.phy], 31
838
        cmp     [ebx + device.phy], 31
839
        jne     .next
839
        jne     .next
840
        mov     ax, [ebx + device.chip_version]
840
        mov     ax, [ebx + device.chip_version]
841
        inc     ax
841
        inc     ax
842
        and     ax, 0xfffe
842
        and     ax, 0xfffe
843
        cmp     ax, 0x2624              ; 79c971 & 79c972 have phantom phy at id 31
843
        cmp     ax, 0x2624              ; 79c971 & 79c972 have phantom phy at id 31
844
        je      .got_phy
844
        je      .got_phy
845
 
845
 
846
  .next:
846
  .next:
847
        inc     [ebx + device.phy]
847
        inc     [ebx + device.phy]
848
        cmp     [ebx + device.phy], MAX_PHYS
848
        cmp     [ebx + device.phy], MAX_PHYS
849
        jb      .mii_loop
849
        jb      .mii_loop
850
 
850
 
851
        DEBUGF  2, "No PHY found!\n"
851
        DEBUGF  2, "No PHY found!\n"
852
        or      eax, -1
852
        or      eax, -1
853
        ret
853
        ret
854
 
854
 
855
  .got_phy:
855
  .got_phy:
856
        DEBUGF  1, "Found PHY at 0x%x\n", [ebx + device.phy]:4
856
        DEBUGF  1, "Found PHY at 0x%x\n", [ebx + device.phy]:4
857
 
857
 
858
  .no_mii:
858
  .no_mii:
859
 
859
 
860
;-----------------------------------------------
860
;-----------------------------------------------
861
 
861
 
862
        call    read_mac
862
        call    read_mac
863
 
863
 
864
        lea     esi, [ebx + device.mac]
864
        lea     esi, [ebx + device.mac]
865
        lea     edi, [ebx + device.phys_addr]
865
        lea     edi, [ebx + device.phys_addr]
866
        movsd
866
        movsd
867
        movsw
867
        movsw
868
 
868
 
869
        call    init_ring
869
        call    init_ring
870
 
870
 
871
        mov     edx, [ebx + device.io_addr]   ; init ring destroys edx
871
        mov     edx, [ebx + device.io_addr]   ; init ring destroys edx
872
 
872
 
873
        lea     eax, [ebx + device.mode]
873
        lea     eax, [ebx + device.mode]
874
        invoke  GetPhysAddr
874
        invoke  GetPhysAddr
875
        push    eax
875
        push    eax
876
        and     eax, 0xffff
876
        and     eax, 0xffff
877
        mov     ecx, 1
877
        mov     ecx, 1
878
        call    [ebx + device.write_csr]
878
        call    [ebx + device.write_csr]
879
        pop     eax
879
        pop     eax
880
        shr     eax, 16
880
        shr     eax, 16
881
        mov     ecx, 2
881
        mov     ecx, 2
882
        call    [ebx + device.write_csr]
882
        call    [ebx + device.write_csr]
883
 
883
 
884
        mov     ecx, 4
884
        mov     ecx, 4
885
        mov     eax, 0x0915
885
        mov     eax, 0x0915
886
        call    [ebx + device.write_csr]
886
        call    [ebx + device.write_csr]
887
 
887
 
888
; Set the interrupt mask
888
; Set the interrupt mask
889
        mov     ecx, CSR_IMR
889
        mov     ecx, CSR_IMR
890
        mov     eax, IMR
890
        mov     eax, IMR
891
        call    [ebx + device.write_csr]
891
        call    [ebx + device.write_csr]
892
 
892
 
893
; Initialise the device
893
; Initialise the device
894
        xor     ecx, ecx
894
        xor     ecx, ecx
895
        mov     eax, CSR_INIT
895
        mov     eax, CSR_INIT
896
        call    [ebx + device.write_csr]
896
        call    [ebx + device.write_csr]
897
 
897
 
898
        mov     esi, 100
898
        mov     esi, 100
899
;        xor     ecx, ecx
899
;        xor     ecx, ecx
900
  @@:
900
  @@:
901
        call    [ebx + device.read_csr]
901
        call    [ebx + device.read_csr]
902
        test    ax, CSR_IDONE
902
        test    ax, CSR_IDONE
903
        jnz     @f
903
        jnz     @f
904
 
904
 
905
        dec     esi
905
        dec     esi
906
        jnz     @r
906
        jnz     @r
907
        DEBUGF  2,"Initialize timeout!\n"
907
        DEBUGF  2,"Initialize timeout!\n"
908
  @@:
908
  @@:
909
 
909
 
910
; Start the device and enable interrupts
910
; Start the device and enable interrupts
911
        xor     ecx, ecx
911
        xor     ecx, ecx
912
        mov     eax, CSR_START + CSR_INTEN
912
        mov     eax, CSR_START + CSR_INTEN
913
        call    [ebx + device.write_csr]
913
        call    [ebx + device.write_csr]
914
 
914
 
915
; Set the mtu, kernel will be able to send now
915
; Set the mtu, kernel will be able to send now
916
        mov     [ebx + device.mtu], 1514
916
        mov     [ebx + device.mtu], 1514
917
 
917
 
918
; get link status
918
; get link status
919
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
919
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
920
 
920
 
921
        call    check_media
921
        call    check_media
922
 
922
 
923
        DEBUGF  1,"reset complete\n"
923
        DEBUGF  1,"reset complete\n"
924
        xor     eax, eax
924
        xor     eax, eax
925
        ret
925
        ret
926
 
926
 
927
 
927
 
928
align 4
928
align 4
929
init_ring:
929
init_ring:
930
 
930
 
931
        DEBUGF  1,"init ring\n"
931
        DEBUGF  1,"init ring\n"
932
 
932
 
933
        lea     edi, [ebx + device.rx_ring]
933
        lea     edi, [ebx + device.rx_ring]
934
        mov     eax, edi
934
        mov     eax, edi
935
        invoke  GetPhysAddr
935
        invoke  GetPhysAddr
936
        mov     [ebx + device.rx_ring_phys], eax
936
        mov     [ebx + device.rx_ring_phys], eax
937
        mov     ecx, RX_RING_SIZE
937
        mov     ecx, RX_RING_SIZE
938
  .rx_init:
938
  .rx_init:
939
        push    ecx
939
        push    ecx
940
        invoke  KernelAlloc, PKT_BUF_SZ
940
        invoke  KernelAlloc, PKT_BUF_SZ
941
        pop     ecx
941
        pop     ecx
942
        mov     [edi + descriptor.virtual], eax
942
        mov     [edi + descriptor.virtual], eax
943
        invoke  GetPhysAddr
943
        invoke  GetPhysAddr
944
        mov     [edi + descriptor.base], eax
944
        mov     [edi + descriptor.base], eax
945
        mov     [edi + descriptor.length], - PKT_BUF_SZ
945
        mov     [edi + descriptor.length], - PKT_BUF_SZ
946
        mov     [edi + descriptor.status], RXSTAT_OWN
946
        mov     [edi + descriptor.status], RXSTAT_OWN
947
        mov     dword[edi + descriptor.msg_length], 0    ; also clears misc field
947
        mov     dword[edi + descriptor.msg_length], 0    ; also clears misc field
948
        add     edi, sizeof.descriptor
948
        add     edi, sizeof.descriptor
949
        dec     ecx
949
        dec     ecx
950
        jnz     .rx_init
950
        jnz     .rx_init
951
 
951
 
952
        lea     edi, [ebx + device.tx_ring]
952
        lea     edi, [ebx + device.tx_ring]
953
        mov     eax, edi
953
        mov     eax, edi
954
        invoke  GetPhysAddr
954
        invoke  GetPhysAddr
955
        mov     [ebx + device.tx_ring_phys], eax
955
        mov     [ebx + device.tx_ring_phys], eax
956
        mov     ecx, TX_RING_SIZE
956
        mov     ecx, TX_RING_SIZE
957
  .tx_init:
957
  .tx_init:
958
        mov     [edi + descriptor.status], 0
958
        mov     [edi + descriptor.status], 0
959
        add     edi, sizeof.descriptor
959
        add     edi, sizeof.descriptor
960
        dec     ecx
960
        dec     ecx
961
        jnz     .tx_init
961
        jnz     .tx_init
962
 
962
 
963
        mov     [ebx + device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
963
        mov     [ebx + device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
964
 
964
 
965
        mov     [ebx + device.cur_tx], 0
965
        mov     [ebx + device.cur_tx], 0
966
        mov     [ebx + device.last_tx], 0
966
        mov     [ebx + device.last_tx], 0
967
        mov     [ebx + device.cur_rx], 0
967
        mov     [ebx + device.cur_rx], 0
968
 
968
 
969
        ret
969
        ret
970
 
970
 
971
 
971
 
972
 
972
 
973
 
973
 
974
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
974
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
975
;;                                         ;;
975
;;                                         ;;
976
;; Transmit                                ;;
976
;; Transmit                                ;;
977
;;                                         ;;
977
;;                                         ;;
978
;; In: pointer to device structure in ebx  ;;
978
;; In: pointer to device structure in ebx  ;;
979
;;                                         ;;
979
;;                                         ;;
980
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
980
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
981
 
981
 
982
proc transmit stdcall bufferptr, buffersize
982
proc transmit stdcall bufferptr, buffersize
983
 
983
 
984
        pushf
984
        pushf
985
        cli
985
        cli
986
 
986
 
987
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
987
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
988
        mov     eax, [bufferptr]
988
        mov     eax, [bufferptr]
989
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
989
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
990
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
990
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
991
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
991
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
992
        [eax+13]:2,[eax+12]:2
992
        [eax+13]:2,[eax+12]:2
993
 
993
 
994
        cmp     [buffersize], 1514
994
        cmp     [buffersize], 1514
995
        ja      .fail
995
        ja      .fail
996
        cmp     [buffersize], 60
996
        cmp     [buffersize], 60
997
        jb      .fail
997
        jb      .fail
998
 
998
 
999
; check descriptor
999
; check descriptor
1000
        lea     edi, [ebx + device.tx_ring]
1000
        lea     edi, [ebx + device.tx_ring]
1001
        movzx   eax, [ebx + device.cur_tx]
1001
        movzx   eax, [ebx + device.cur_tx]
1002
        shl     eax, 4
1002
        shl     eax, 4
1003
        add     edi, eax
1003
        add     edi, eax
1004
 
1004
 
1005
        test    [edi + descriptor.status], TXCTL_OWN
1005
        test    [edi + descriptor.status], TXCTL_OWN
1006
        jnz     .fail
1006
        jnz     .fail
1007
; descriptor is free, use it
1007
; descriptor is free, use it
1008
        mov     eax, [bufferptr]
1008
        mov     eax, [bufferptr]
1009
        mov     [edi + descriptor.virtual], eax
1009
        mov     [edi + descriptor.virtual], eax
1010
        invoke  GetPhysAddr
1010
        invoke  GetPhysAddr
1011
        mov     [edi + descriptor.base], eax
1011
        mov     [edi + descriptor.base], eax
1012
; set length
1012
; set length
1013
        mov     eax, [buffersize]
1013
        mov     eax, [buffersize]
1014
        neg     eax
1014
        neg     eax
1015
        mov     [edi + descriptor.length], ax
1015
        mov     [edi + descriptor.length], ax
1016
; put to transfer queue
1016
; put to transfer queue
1017
        mov     [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
1017
        mov     [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
1018
 
1018
 
1019
; trigger an immediate send
1019
; trigger an immediate send
1020
        mov     edx, [ebx + device.io_addr]
1020
        mov     edx, [ebx + device.io_addr]
1021
        xor     ecx, ecx                        ; CSR0
1021
        xor     ecx, ecx                        ; CSR0
1022
        call    [ebx + device.read_csr]
1022
        call    [ebx + device.read_csr]
1023
        or      eax, CSR_TX
1023
        or      eax, CSR_TX
1024
        call    [ebx + device.write_csr]
1024
        call    [ebx + device.write_csr]
1025
 
1025
 
1026
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
1026
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
1027
        inc     [ebx + device.cur_tx]
1027
        inc     [ebx + device.cur_tx]
1028
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
1028
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
1029
 
1029
 
1030
; Update stats
1030
; Update stats
1031
        inc     [ebx + device.packets_tx]
1031
        inc     [ebx + device.packets_tx]
1032
        mov     eax, [buffersize]
1032
        mov     eax, [buffersize]
1033
        add     dword[ebx + device.bytes_tx], eax
1033
        add     dword[ebx + device.bytes_tx], eax
1034
        adc     dword[ebx + device.bytes_tx + 4], 0
1034
        adc     dword[ebx + device.bytes_tx + 4], 0
1035
 
1035
 
1036
  .finish:
1036
  .finish:
1037
        popf
1037
        popf
1038
        xor     eax, eax
1038
        xor     eax, eax
1039
        ret
1039
        ret
1040
 
1040
 
1041
  .fail:
1041
  .fail:
1042
        DEBUGF  2, "Send failed\n"
1042
        DEBUGF  2, "Send failed\n"
1043
        invoke  KernelFree, [bufferptr]
1043
        invoke  KernelFree, [bufferptr]
1044
        popf
1044
        popf
1045
        or      eax, -1
1045
        or      eax, -1
1046
        ret
1046
        ret
1047
 
1047
 
1048
endp
1048
endp
1049
 
1049
 
1050
 
1050
 
1051
;;;;;;;;;;;;;;;;;;;;;;;
1051
;;;;;;;;;;;;;;;;;;;;;;;
1052
;;                   ;;
1052
;;                   ;;
1053
;; Interrupt handler ;;
1053
;; Interrupt handler ;;
1054
;;                   ;;
1054
;;                   ;;
1055
;;;;;;;;;;;;;;;;;;;;;;;
1055
;;;;;;;;;;;;;;;;;;;;;;;
1056
 
1056
 
1057
align 4
1057
align 4
1058
int_handler:
1058
int_handler:
1059
 
1059
 
1060
        push    ebx esi edi
1060
        push    ebx esi edi
1061
 
1061
 
1062
        DEBUGF  1,"INT\n"
1062
        DEBUGF  1,"INT\n"
1063
 
1063
 
1064
; find pointer of device wich made IRQ occur
1064
; find pointer of device wich made IRQ occur
1065
 
1065
 
1066
        mov     ecx, [devices]
1066
        mov     ecx, [devices]
1067
        test    ecx, ecx
1067
        test    ecx, ecx
1068
        jz      .nothing
1068
        jz      .nothing
1069
        mov     esi, device_list
1069
        mov     esi, device_list
1070
  .nextdevice:
1070
  .nextdevice:
1071
        mov     ebx, [esi]
1071
        mov     ebx, [esi]
1072
        mov     edx, [ebx + device.io_addr]
1072
        mov     edx, [ebx + device.io_addr]
1073
        push    ecx
1073
        push    ecx
1074
        xor     ecx, ecx                        ; CSR0
1074
        xor     ecx, ecx                        ; CSR0
1075
        call    [ebx + device.read_csr]         ; get IRQ reason
1075
        call    [ebx + device.read_csr]         ; get IRQ reason
1076
        call    [ebx + device.write_csr]        ; write it back to ACK
1076
        call    [ebx + device.write_csr]        ; write it back to ACK
1077
        pop     ecx
1077
        pop     ecx
1078
        and     ax, CSR_RINT or CSR_TINT
1078
        and     ax, CSR_RINT or CSR_TINT
1079
        jnz     .got_it
1079
        jnz     .got_it
1080
  .continue:
1080
  .continue:
1081
        add     esi, 4
1081
        add     esi, 4
1082
        dec     ecx
1082
        dec     ecx
1083
        jnz     .nextdevice
1083
        jnz     .nextdevice
1084
  .nothing:
1084
  .nothing:
1085
        pop     edi esi ebx
1085
        pop     edi esi ebx
1086
        xor     eax, eax
1086
        xor     eax, eax
1087
 
1087
 
1088
        ret
1088
        ret
1089
 
1089
 
1090
  .got_it:
1090
  .got_it:
1091
        DEBUGF  1,"Device: %x status: %x\n", ebx, eax:4
1091
        DEBUGF  1,"Device: %x status: %x\n", ebx, eax:4
1092
 
1092
 
1093
        push    ax
1093
        push    ax
1094
        test    ax, CSR_RINT
1094
        test    ax, CSR_RINT
1095
        jz      .not_receive
1095
        jz      .not_receive
1096
 
1096
 
1097
        push    ebx
1097
        push    ebx
1098
  .rx_loop:
1098
  .rx_loop:
1099
        pop     ebx
1099
        pop     ebx
1100
        movzx   eax, [ebx + device.cur_rx]
1100
        movzx   eax, [ebx + device.cur_rx]
1101
        shl     eax, 4
1101
        shl     eax, 4
1102
        lea     edi, [ebx + device.rx_ring]
1102
        lea     edi, [ebx + device.rx_ring]
1103
        add     edi, eax                        ; edi now points to current rx ring entry
1103
        add     edi, eax                        ; edi now points to current rx ring entry
1104
 
1104
 
1105
        mov     ax, [edi + descriptor.status]
1105
        mov     ax, [edi + descriptor.status]
1106
        DEBUGF  1,"RX packet status: %x\n", eax:4
1106
        DEBUGF  1,"RX packet status: %x\n", eax:4
1107
 
1107
 
1108
        test    ax, RXSTAT_OWN                  ; If this bit is set, the controller OWN's the packet, if not, we do
1108
        test    ax, RXSTAT_OWN                  ; If this bit is set, the controller OWN's the packet, if not, we do
1109
        jnz     .not_receive
1109
        jnz     .not_receive
1110
 
1110
 
1111
        test    ax, RXSTAT_ENP
1111
        test    ax, RXSTAT_ENP
1112
        jz      .not_receive
1112
        jz      .not_receive
1113
 
1113
 
1114
        test    ax, RXSTAT_STP
1114
        test    ax, RXSTAT_STP
1115
        jz      .not_receive
1115
        jz      .not_receive
1116
 
1116
 
1117
        movzx   ecx, [edi + descriptor.msg_length]      ; get packet length in ecx
1117
        movzx   ecx, [edi + descriptor.msg_length]      ; get packet length in ecx
1118
        sub     ecx, 4                                  ; We dont need the CRC
1118
        sub     ecx, 4                                  ; We dont need the CRC
1119
        DEBUGF  1,"Got %u bytes\n", ecx
1119
        DEBUGF  1,"Got %u bytes\n", ecx
1120
 
1120
 
1121
; Set pointers for ETH_input
1121
; Set pointers for ETH_input
1122
        push    ebx
1122
        push    ebx
1123
 
1123
 
1124
        push    .rx_loop                                ; return address
1124
        push    .rx_loop                                ; return address
1125
        push    ecx                                     ; packet size
1125
        push    ecx                                     ; packet size
1126
        push    [edi + descriptor.virtual]              ; packet address
1126
        push    [edi + descriptor.virtual]              ; packet address
1127
 
1127
 
1128
; Update stats
1128
; Update stats
1129
        add     dword[ebx + device.bytes_rx], ecx
1129
        add     dword[ebx + device.bytes_rx], ecx
1130
        adc     dword[ebx + device.bytes_rx + 4], 0
1130
        adc     dword[ebx + device.bytes_rx + 4], 0
1131
        inc     [ebx + device.packets_rx]
1131
        inc     [ebx + device.packets_rx]
1132
 
1132
 
1133
; now allocate a new buffer
1133
; now allocate a new buffer
1134
        invoke  KernelAlloc, PKT_BUF_SZ                 ; Allocate a buffer for the next packet
1134
        invoke  KernelAlloc, PKT_BUF_SZ                 ; Allocate a buffer for the next packet
1135
        mov     [edi + descriptor.virtual], eax         ; set virtual address
1135
        mov     [edi + descriptor.virtual], eax         ; set virtual address
1136
        invoke  GetPhysAddr
1136
        invoke  GetPhysAddr
1137
        mov     [edi + descriptor.base], eax            ; and physical address
1137
        mov     [edi + descriptor.base], eax            ; and physical address
1138
        mov     [edi + descriptor.status], RXSTAT_OWN   ; give it back to PCnet controller
1138
        mov     [edi + descriptor.status], RXSTAT_OWN   ; give it back to PCnet controller
1139
 
1139
 
1140
        inc     [ebx + device.cur_rx]                   ; set next receive descriptor
1140
        inc     [ebx + device.cur_rx]                   ; set next receive descriptor
1141
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
1141
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
1142
 
1142
 
1143
        jmp     [Eth_input]
1143
        jmp     [Eth_input]
1144
 
1144
 
1145
  .not_receive:
1145
  .not_receive:
1146
        pop     ax
1146
        pop     ax
1147
 
1147
 
1148
        test    ax, CSR_TINT
1148
        test    ax, CSR_TINT
1149
        jz      .not_transmit
1149
        jz      .not_transmit
1150
 
1150
 
1151
  .tx_loop:
1151
  .tx_loop:
1152
        lea     edi, [ebx + device.tx_ring]
1152
        lea     edi, [ebx + device.tx_ring]
1153
        movzx   eax, [ebx + device.last_tx]
1153
        movzx   eax, [ebx + device.last_tx]
1154
        shl     eax, 4
1154
        shl     eax, 4
1155
        add     edi, eax
1155
        add     edi, eax
1156
 
1156
 
1157
        test    [edi + descriptor.status], TXCTL_OWN
1157
        test    [edi + descriptor.status], TXCTL_OWN
1158
        jnz     .not_transmit
1158
        jnz     .not_transmit
1159
 
1159
 
1160
        mov     eax, [edi + descriptor.virtual]
1160
        mov     eax, [edi + descriptor.virtual]
1161
        test    eax, eax
1161
        test    eax, eax
1162
        jz      .not_transmit
1162
        jz      .not_transmit
1163
 
1163
 
1164
        mov     [edi + descriptor.virtual], 0
1164
        mov     [edi + descriptor.virtual], 0
1165
 
1165
 
1166
        DEBUGF  1,"Removing packet %x from memory\n", eax
1166
        DEBUGF  1,"Removing packet %x from memory\n", eax
1167
 
1167
 
1168
        invoke  KernelFree, eax
1168
        invoke  KernelFree, eax
1169
 
1169
 
1170
        inc     [ebx + device.last_tx]
1170
        inc     [ebx + device.last_tx]
1171
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
1171
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
1172
        jmp     .tx_loop
1172
        jmp     .tx_loop
1173
 
1173
 
1174
  .not_transmit:
1174
  .not_transmit:
1175
        pop     edi esi ebx
1175
        pop     edi esi ebx
1176
        xor     eax, eax
1176
        xor     eax, eax
1177
        inc     eax
1177
        inc     eax
1178
 
1178
 
1179
        ret
1179
        ret
1180
 
1180
 
1181
 
1181
 
1182
 
1182
 
1183
 
1183
 
1184
;;;;;;;;;;;;;;;;;;;;;;;
1184
;;;;;;;;;;;;;;;;;;;;;;;
1185
;;                   ;;
1185
;;                   ;;
1186
;; Write MAC address ;;
1186
;; Write MAC address ;;
1187
;;                   ;;
1187
;;                   ;;
1188
;;;;;;;;;;;;;;;;;;;;;;;
1188
;;;;;;;;;;;;;;;;;;;;;;;
1189
 
1189
 
1190
align 4
1190
align 4
1191
write_mac:      ; in: mac pushed onto stack (as 3 words)
1191
write_mac:      ; in: mac pushed onto stack (as 3 words)
1192
 
1192
 
1193
        DEBUGF  1,"Writing MAC: %x-%x-%x-%x-%x-%x\n",\
1193
        DEBUGF  1,"Writing MAC: %x-%x-%x-%x-%x-%x\n",\
1194
        [esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
1194
        [esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
1195
 
1195
 
1196
        mov     edx, [ebx + device.io_addr]
1196
        mov     edx, [ebx + device.io_addr]
1197
        add     dx, 2
1197
        add     dx, 2
1198
        xor     eax, eax
1198
        xor     eax, eax
1199
 
1199
 
1200
        mov     ecx, CSR_PAR0
1200
        mov     ecx, CSR_PAR0
1201
       @@:
1201
       @@:
1202
        pop     ax
1202
        pop     ax
1203
        call    [ebx + device.write_csr]
1203
        call    [ebx + device.write_csr]
1204
        inc     ecx
1204
        inc     ecx
1205
        cmp     ecx, CSR_PAR2
1205
        cmp     ecx, CSR_PAR2
1206
        jb      @r
1206
        jb      @r
1207
 
1207
 
1208
; Notice this procedure does not ret, but continues to read_mac instead.
1208
; Notice this procedure does not ret, but continues to read_mac instead.
1209
 
1209
 
1210
;;;;;;;;;;;;;;;;;;;;;;
1210
;;;;;;;;;;;;;;;;;;;;;;
1211
;;                  ;;
1211
;;                  ;;
1212
;; Read MAC address ;;
1212
;; Read MAC address ;;
1213
;;                  ;;
1213
;;                  ;;
1214
;;;;;;;;;;;;;;;;;;;;;;
1214
;;;;;;;;;;;;;;;;;;;;;;
1215
align 4
1215
align 4
1216
read_mac:
1216
read_mac:
1217
        DEBUGF  1,"Reading MAC\n"
1217
        DEBUGF  1,"Reading MAC\n"
1218
 
1218
 
1219
        mov     edx, [ebx + device.io_addr]
1219
        mov     edx, [ebx + device.io_addr]
1220
        lea     edi, [ebx + device.mac]
1220
        lea     edi, [ebx + device.mac]
1221
        in      ax, dx
1221
        in      ax, dx
1222
        stosw
1222
        stosw
1223
 
1223
 
1224
        inc     dx
1224
        inc     dx
1225
        inc     dx
1225
        inc     dx
1226
        in      ax, dx
1226
        in      ax, dx
1227
        stosw
1227
        stosw
1228
 
1228
 
1229
        inc     dx
1229
        inc     dx
1230
        inc     dx
1230
        inc     dx
1231
        in      ax, dx
1231
        in      ax, dx
1232
        stosw
1232
        stosw
1233
 
1233
 
1234
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1234
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1235
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
1235
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
1236
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1236
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1237
 
1237
 
1238
        ret
1238
        ret
1239
 
1239
 
1240
align 4
1240
align 4
1241
switch_to_wio:
1241
switch_to_wio:
1242
 
1242
 
1243
        DEBUGF  1,"Switching to 16-bit mode\n"
1243
        DEBUGF  1,"Switching to 16-bit mode\n"
1244
 
1244
 
1245
        mov     [ebx + device.read_csr], wio_read_csr
1245
        mov     [ebx + device.read_csr], wio_read_csr
1246
        mov     [ebx + device.write_csr], wio_write_csr
1246
        mov     [ebx + device.write_csr], wio_write_csr
1247
        mov     [ebx + device.read_bcr], wio_read_bcr
1247
        mov     [ebx + device.read_bcr], wio_read_bcr
1248
        mov     [ebx + device.write_bcr], wio_write_bcr
1248
        mov     [ebx + device.write_bcr], wio_write_bcr
1249
        mov     [ebx + device.read_rap], wio_read_rap
1249
        mov     [ebx + device.read_rap], wio_read_rap
1250
        mov     [ebx + device.write_rap], wio_write_rap
1250
        mov     [ebx + device.write_rap], wio_write_rap
1251
        mov     [ebx + device.sw_reset], wio_reset
1251
        mov     [ebx + device.sw_reset], wio_reset
1252
 
1252
 
1253
        ret
1253
        ret
1254
 
1254
 
1255
align 4
1255
align 4
1256
switch_to_dwio:
1256
switch_to_dwio:
1257
 
1257
 
1258
        DEBUGF  1,"Switching to 32-bit mode\n"
1258
        DEBUGF  1,"Switching to 32-bit mode\n"
1259
 
1259
 
1260
        mov     [ebx + device.read_csr], dwio_read_csr
1260
        mov     [ebx + device.read_csr], dwio_read_csr
1261
        mov     [ebx + device.write_csr], dwio_write_csr
1261
        mov     [ebx + device.write_csr], dwio_write_csr
1262
        mov     [ebx + device.read_bcr], dwio_read_bcr
1262
        mov     [ebx + device.read_bcr], dwio_read_bcr
1263
        mov     [ebx + device.write_bcr], dwio_write_bcr
1263
        mov     [ebx + device.write_bcr], dwio_write_bcr
1264
        mov     [ebx + device.read_rap], dwio_read_rap
1264
        mov     [ebx + device.read_rap], dwio_read_rap
1265
        mov     [ebx + device.write_rap], dwio_write_rap
1265
        mov     [ebx + device.write_rap], dwio_write_rap
1266
        mov     [ebx + device.sw_reset], dwio_reset
1266
        mov     [ebx + device.sw_reset], dwio_reset
1267
 
1267
 
1268
        ret
1268
        ret
1269
 
1269
 
1270
 
1270
 
1271
; ecx - index
1271
; ecx - index
1272
; return:
1272
; return:
1273
; eax - data
1273
; eax - data
1274
align 4
1274
align 4
1275
wio_read_csr:
1275
wio_read_csr:
1276
 
1276
 
1277
        add     edx, WIO_RAP
1277
        add     edx, WIO_RAP
1278
        mov     ax, cx
1278
        mov     ax, cx
1279
        out     dx, ax
1279
        out     dx, ax
1280
        add     edx, WIO_RDP - WIO_RAP
1280
        add     edx, WIO_RDP - WIO_RAP
1281
        in      ax, dx
1281
        in      ax, dx
1282
        and     eax, 0xffff
1282
        and     eax, 0xffff
1283
        sub     edx, WIO_RDP
1283
        sub     edx, WIO_RDP
1284
 
1284
 
1285
        ret
1285
        ret
1286
 
1286
 
1287
 
1287
 
1288
; eax - data
1288
; eax - data
1289
; ecx - index
1289
; ecx - index
1290
align 4
1290
align 4
1291
wio_write_csr:
1291
wio_write_csr:
1292
 
1292
 
1293
        add     edx, WIO_RAP
1293
        add     edx, WIO_RAP
1294
        xchg    eax, ecx
1294
        xchg    eax, ecx
1295
        out     dx, ax
1295
        out     dx, ax
1296
        xchg    eax, ecx
1296
        xchg    eax, ecx
1297
        add     edx, WIO_RDP - WIO_RAP
1297
        add     edx, WIO_RDP - WIO_RAP
1298
        out     dx, ax
1298
        out     dx, ax
1299
        sub     edx, WIO_RDP
1299
        sub     edx, WIO_RDP
1300
 
1300
 
1301
        ret
1301
        ret
1302
 
1302
 
1303
 
1303
 
1304
; ecx - index
1304
; ecx - index
1305
; return:
1305
; return:
1306
; eax - data
1306
; eax - data
1307
align 4
1307
align 4
1308
wio_read_bcr:
1308
wio_read_bcr:
1309
 
1309
 
1310
        add     edx, WIO_RAP
1310
        add     edx, WIO_RAP
1311
        mov     ax, cx
1311
        mov     ax, cx
1312
        out     dx, ax
1312
        out     dx, ax
1313
        add     edx, WIO_BDP - WIO_RAP
1313
        add     edx, WIO_BDP - WIO_RAP
1314
        in      ax, dx
1314
        in      ax, dx
1315
        and     eax, 0xffff
1315
        and     eax, 0xffff
1316
        sub     edx, WIO_BDP
1316
        sub     edx, WIO_BDP
1317
 
1317
 
1318
        ret
1318
        ret
1319
 
1319
 
1320
 
1320
 
1321
; eax - data
1321
; eax - data
1322
; ecx - index
1322
; ecx - index
1323
align 4
1323
align 4
1324
wio_write_bcr:
1324
wio_write_bcr:
1325
 
1325
 
1326
        add     edx, WIO_RAP
1326
        add     edx, WIO_RAP
1327
        xchg    eax, ecx
1327
        xchg    eax, ecx
1328
        out     dx, ax
1328
        out     dx, ax
1329
        xchg    eax, ecx
1329
        xchg    eax, ecx
1330
        add     edx, WIO_BDP - WIO_RAP
1330
        add     edx, WIO_BDP - WIO_RAP
1331
        out     dx, ax
1331
        out     dx, ax
1332
        sub     edx, WIO_BDP
1332
        sub     edx, WIO_BDP
1333
 
1333
 
1334
        ret
1334
        ret
1335
 
1335
 
1336
align 4
1336
align 4
1337
wio_read_rap:
1337
wio_read_rap:
1338
 
1338
 
1339
        add     edx, WIO_RAP
1339
        add     edx, WIO_RAP
1340
        in      ax, dx
1340
        in      ax, dx
1341
        and     eax, 0xffff
1341
        and     eax, 0xffff
1342
        sub     edx, WIO_RAP
1342
        sub     edx, WIO_RAP
1343
 
1343
 
1344
        ret
1344
        ret
1345
 
1345
 
1346
; eax - val
1346
; eax - val
1347
align 4
1347
align 4
1348
wio_write_rap:
1348
wio_write_rap:
1349
 
1349
 
1350
        add     edx, WIO_RAP
1350
        add     edx, WIO_RAP
1351
        out     dx, ax
1351
        out     dx, ax
1352
        sub     edx, WIO_RAP
1352
        sub     edx, WIO_RAP
1353
 
1353
 
1354
        ret
1354
        ret
1355
 
1355
 
1356
align 4
1356
align 4
1357
wio_reset:
1357
wio_reset:
1358
 
1358
 
1359
        push    eax
1359
        push    eax
1360
        add     edx, WIO_RESET
1360
        add     edx, WIO_RESET
1361
        in      ax, dx
1361
        in      ax, dx
1362
        pop     eax
1362
        pop     eax
1363
        sub     edx, WIO_RESET
1363
        sub     edx, WIO_RESET
1364
 
1364
 
1365
        ret
1365
        ret
1366
 
1366
 
1367
 
1367
 
1368
 
1368
 
1369
; ecx - index
1369
; ecx - index
1370
; return:
1370
; return:
1371
; eax - data
1371
; eax - data
1372
align 4
1372
align 4
1373
dwio_read_csr:
1373
dwio_read_csr:
1374
 
1374
 
1375
        add     edx, DWIO_RAP
1375
        add     edx, DWIO_RAP
1376
        mov     eax, ecx
1376
        mov     eax, ecx
1377
        out     dx, eax
1377
        out     dx, eax
1378
        add     edx, DWIO_RDP - DWIO_RAP
1378
        add     edx, DWIO_RDP - DWIO_RAP
1379
        in      eax, dx
1379
        in      eax, dx
1380
        and     eax, 0xffff
1380
        and     eax, 0xffff
1381
        sub     edx, DWIO_RDP
1381
        sub     edx, DWIO_RDP
1382
 
1382
 
1383
        ret
1383
        ret
1384
 
1384
 
1385
 
1385
 
1386
; ecx - index
1386
; ecx - index
1387
; eax - data
1387
; eax - data
1388
align 4
1388
align 4
1389
dwio_write_csr:
1389
dwio_write_csr:
1390
 
1390
 
1391
        add     edx, DWIO_RAP
1391
        add     edx, DWIO_RAP
1392
        xchg    eax, ecx
1392
        xchg    eax, ecx
1393
        out     dx, eax
1393
        out     dx, eax
1394
        add     edx, DWIO_RDP - DWIO_RAP
1394
        add     edx, DWIO_RDP - DWIO_RAP
1395
        xchg    eax, ecx
1395
        xchg    eax, ecx
1396
        out     dx, eax
1396
        out     dx, eax
1397
        sub     edx, DWIO_RDP
1397
        sub     edx, DWIO_RDP
1398
 
1398
 
1399
        ret
1399
        ret
1400
 
1400
 
1401
; ecx - index
1401
; ecx - index
1402
; return:
1402
; return:
1403
; eax - data
1403
; eax - data
1404
align 4
1404
align 4
1405
dwio_read_bcr:
1405
dwio_read_bcr:
1406
 
1406
 
1407
        add     edx, DWIO_RAP
1407
        add     edx, DWIO_RAP
1408
        mov     eax, ecx
1408
        mov     eax, ecx
1409
        out     dx, eax
1409
        out     dx, eax
1410
        add     edx, DWIO_BDP - DWIO_RAP
1410
        add     edx, DWIO_BDP - DWIO_RAP
1411
        in      eax, dx
1411
        in      eax, dx
1412
        and     eax, 0xffff
1412
        and     eax, 0xffff
1413
        sub     edx, DWIO_BDP
1413
        sub     edx, DWIO_BDP
1414
 
1414
 
1415
        ret
1415
        ret
1416
 
1416
 
1417
 
1417
 
1418
; ecx - index
1418
; ecx - index
1419
; eax - data
1419
; eax - data
1420
align 4
1420
align 4
1421
dwio_write_bcr:
1421
dwio_write_bcr:
1422
 
1422
 
1423
        add     edx, DWIO_RAP
1423
        add     edx, DWIO_RAP
1424
        xchg    eax, ecx
1424
        xchg    eax, ecx
1425
        out     dx, eax
1425
        out     dx, eax
1426
        add     edx, DWIO_BDP - DWIO_RAP
1426
        add     edx, DWIO_BDP - DWIO_RAP
1427
        xchg    eax, ecx
1427
        xchg    eax, ecx
1428
        out     dx, eax
1428
        out     dx, eax
1429
        sub     edx, DWIO_BDP
1429
        sub     edx, DWIO_BDP
1430
 
1430
 
1431
        ret
1431
        ret
1432
 
1432
 
1433
align 4
1433
align 4
1434
dwio_read_rap:
1434
dwio_read_rap:
1435
 
1435
 
1436
        add     edx, DWIO_RAP
1436
        add     edx, DWIO_RAP
1437
        in      eax, dx
1437
        in      eax, dx
1438
        and     eax, 0xffff
1438
        and     eax, 0xffff
1439
        sub     edx, DWIO_RAP
1439
        sub     edx, DWIO_RAP
1440
 
1440
 
1441
        ret
1441
        ret
1442
 
1442
 
1443
 
1443
 
1444
; eax - val
1444
; eax - val
1445
align 4
1445
align 4
1446
dwio_write_rap:
1446
dwio_write_rap:
1447
 
1447
 
1448
        add     edx, DWIO_RAP
1448
        add     edx, DWIO_RAP
1449
        out     dx, eax
1449
        out     dx, eax
1450
        sub     edx, DWIO_RAP
1450
        sub     edx, DWIO_RAP
1451
 
1451
 
1452
        ret
1452
        ret
1453
 
1453
 
1454
align 4
1454
align 4
1455
dwio_reset:
1455
dwio_reset:
1456
 
1456
 
1457
        push    eax
1457
        push    eax
1458
        add     edx, DWIO_RESET
1458
        add     edx, DWIO_RESET
1459
        in      eax, dx
1459
        in      eax, dx
1460
        pop     eax
1460
        pop     eax
1461
        sub     edx, DWIO_RESET
1461
        sub     edx, DWIO_RESET
1462
 
1462
 
1463
        ret
1463
        ret
1464
 
1464
 
1465
 
1465
 
1466
align 4
1466
align 4
1467
mdio_read:
1467
mdio_read:
1468
 
1468
 
1469
        and     ecx, 0x1f
1469
        and     ecx, 0x1f
1470
        mov     ax, [ebx + device.phy]
1470
        mov     ax, [ebx + device.phy]
1471
        and     ax, 0x1f
1471
        and     ax, 0x1f
1472
        shl     ax, 5
1472
        shl     ax, 5
1473
        or      ax, cx
1473
        or      ax, cx
1474
 
1474
 
1475
        mov     ecx, BCR_MIIADDR
1475
        mov     ecx, BCR_MIIADDR
1476
        call    [ebx + device.write_bcr]
1476
        call    [ebx + device.write_bcr]
1477
 
1477
 
1478
        mov     ecx, BCR_MIIDATA
1478
        mov     ecx, BCR_MIIDATA
1479
        call    [ebx + device.read_bcr]
1479
        call    [ebx + device.read_bcr]
1480
 
1480
 
1481
        ret
1481
        ret
1482
 
1482
 
1483
 
1483
 
1484
align 4
1484
align 4
1485
mdio_write:
1485
mdio_write:
1486
 
1486
 
1487
        push    eax
1487
        push    eax
1488
        and     ecx, 0x1f
1488
        and     ecx, 0x1f
1489
        mov     ax, [ebx + device.phy]
1489
        mov     ax, [ebx + device.phy]
1490
        and     ax, 0x1f
1490
        and     ax, 0x1f
1491
        shl     ax, 5
1491
        shl     ax, 5
1492
        or      ax, cx
1492
        or      ax, cx
1493
 
1493
 
1494
        mov     ecx, BCR_MIIADDR
1494
        mov     ecx, BCR_MIIADDR
1495
        call    [ebx + device.write_bcr]
1495
        call    [ebx + device.write_bcr]
1496
 
1496
 
1497
        pop     eax
1497
        pop     eax
1498
        mov     ecx, BCR_MIIDATA
1498
        mov     ecx, BCR_MIIDATA
1499
        call    [ebx + device.write_bcr]
1499
        call    [ebx + device.write_bcr]
1500
 
1500
 
1501
        ret
1501
        ret
1502
 
1502
 
1503
 
1503
 
1504
align 4
1504
align 4
1505
check_media:
1505
check_media:
1506
 
1506
 
1507
        DEBUGF  1, "check_media\n"
1507
        DEBUGF  1, "check_media\n"
1508
 
1508
 
1509
        test    [ebx + device.mii], 1
1509
        test    [ebx + device.mii], 1
1510
        jnz     mii_link_ok
1510
        jnz     mii_link_ok
1511
 
1511
 
1512
        mov     ecx, BCR_LED0
1512
        mov     ecx, BCR_LED0
1513
        call    [ebx + device.read_bcr]
1513
        call    [ebx + device.read_bcr]
1514
        cmp     eax, 0xc0
1514
        cmp     eax, 0xc0
1515
 
1515
 
1516
        DEBUGF  1, "link status=0x%x\n", ax
1516
        DEBUGF  1, "link status=0x%x\n", ax
1517
 
1517
 
1518
        ret
1518
        ret
1519
 
1519
 
1520
 
1520
 
1521
 
1521
 
1522
; End of code
1522
; End of code
1523
 
1523
 
1524
 
1524
 
1525
data fixups
1525
data fixups
1526
end data
1526
end data
1527
 
1527
 
1528
include '../peimport.inc'
1528
include '../peimport.inc'
1529
 
1529
 
1530
my_service    db 'PCnet',0              ; max 16 chars include zero
1530
my_service    db 'PCNET32',0            ; max 16 chars include zero
1531
 
1531
 
1532
device_l2     db "PCnet/PCI 79C970",0
1532
device_l2     db "PCnet/PCI 79C970",0
1533
device_l4     db "PCnet/PCI II 79C970A",0
1533
device_l4     db "PCnet/PCI II 79C970A",0
1534
device_l5     db "PCnet/FAST 79C971",0
1534
device_l5     db "PCnet/FAST 79C971",0
1535
device_l6     db "PCnet/FAST+ 79C972",0
1535
device_l6     db "PCnet/FAST+ 79C972",0
1536
device_l7     db "PCnet/FAST III 79C973",0
1536
device_l7     db "PCnet/FAST III 79C973",0
1537
device_l8     db "PCnet/Home 79C978",0
1537
device_l8     db "PCnet/Home 79C978",0
1538
device_l9     db "PCnet/FAST III 79C975",0
1538
device_l9     db "PCnet/FAST III 79C975",0
1539
 
1539
 
1540
options_mapping:
1540
options_mapping:
1541
dd PORT_ASEL                            ; 0 Auto-select
1541
dd PORT_ASEL                            ; 0 Auto-select
1542
dd PORT_AUI                             ; 1 BNC/AUI
1542
dd PORT_AUI                             ; 1 BNC/AUI
1543
dd PORT_AUI                             ; 2 AUI/BNC
1543
dd PORT_AUI                             ; 2 AUI/BNC
1544
dd PORT_ASEL                            ; 3 not supported
1544
dd PORT_ASEL                            ; 3 not supported
1545
dd PORT_10BT or PORT_FD                 ; 4 10baseT-FD
1545
dd PORT_10BT or PORT_FD                 ; 4 10baseT-FD
1546
dd PORT_ASEL                            ; 5 not supported
1546
dd PORT_ASEL                            ; 5 not supported
1547
dd PORT_ASEL                            ; 6 not supported
1547
dd PORT_ASEL                            ; 6 not supported
1548
dd PORT_ASEL                            ; 7 not supported
1548
dd PORT_ASEL                            ; 7 not supported
1549
dd PORT_ASEL                            ; 8 not supported
1549
dd PORT_ASEL                            ; 8 not supported
1550
dd PORT_MII                             ; 9 MII 10baseT
1550
dd PORT_MII                             ; 9 MII 10baseT
1551
dd PORT_MII or PORT_FD                  ; 10 MII 10baseT-FD
1551
dd PORT_MII or PORT_FD                  ; 10 MII 10baseT-FD
1552
dd PORT_MII                             ; 11 MII (autosel)
1552
dd PORT_MII                             ; 11 MII (autosel)
1553
dd PORT_10BT                            ; 12 10BaseT
1553
dd PORT_10BT                            ; 12 10BaseT
1554
dd PORT_MII or PORT_100                 ; 13 MII 100BaseTx
1554
dd PORT_MII or PORT_100                 ; 13 MII 100BaseTx
1555
dd PORT_MII or PORT_100 or PORT_FD      ; 14 MII 100BaseTx-FD
1555
dd PORT_MII or PORT_100 or PORT_FD      ; 14 MII 100BaseTx-FD
1556
dd PORT_ASEL                            ; 15 not supported
1556
dd PORT_ASEL                            ; 15 not supported
1557
 
1557
 
1558
include_debug_strings                                   ; All data wich FDO uses will be included here
1558
include_debug_strings                                   ; All data wich FDO uses will be included here
1559
 
1559
 
1560
 
1560
 
1561
align 4
1561
align 4
1562
devices     dd 0
1562
devices     dd 0
1563
device_list rd MAX_DEVICES                              ; This list contains all pointers to device structures the driver is handling
1563
device_list rd MAX_DEVICES                              ; This list contains all pointers to device structures the driver is handling