Subversion Repositories Kolibri OS

Rev

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

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