Subversion Repositories Kolibri OS

Rev

Rev 5522 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5522 Rev 9188
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2021. 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
;;  3Com network driver for KolibriOS                           ;;
6
;;  3Com network driver for KolibriOS                           ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;  Ported to KolibriOS net-branch by hidnplayr                 ;;
8
;;  Ported to KolibriOS net-branch by hidnplayr                 ;;
9
;;                                                              ;;
9
;;                                                              ;;
10
;;  Thanks to: scrap metal recyclers, whom provide me with      ;;
10
;;  Thanks to: scrap metal recyclers, whom provide me with      ;;
11
;;                         loads of hardware                    ;;
11
;;                         loads of hardware                    ;;
12
;;             diamond: who makes me understand KolibriOS       ;;
12
;;             diamond: who makes me understand KolibriOS       ;;
13
;;                                                              ;;
13
;;                                                              ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;
15
;;
16
;; Original copyright from menuetos driver:
16
;; Original copyright from menuetos driver:
17
;;
17
;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
;;                                                                         ;;
19
;;                                                                         ;;
20
;;  3C59X.INC                                                              ;;
20
;;  3C59X.INC                                                              ;;
21
;;                                                                         ;;
21
;;                                                                         ;;
22
;;  Ethernet driver for Menuet OS                                          ;;
22
;;  Ethernet driver for Menuet OS                                          ;;
23
;;                                                                         ;;
23
;;                                                                         ;;
24
;;  Driver for 3Com fast etherlink 3c59x and                               ;;
24
;;  Driver for 3Com fast etherlink 3c59x and                               ;;
25
;;         etherlink XL 3c900 and 3c905 cards                              ;;
25
;;         etherlink XL 3c900 and 3c905 cards                              ;;
26
;;  References:                                                            ;;
26
;;  References:                                                            ;;
27
;;    www.3Com.com - data sheets                                           ;;
27
;;    www.3Com.com - data sheets                                           ;;
28
;;    DP83840A.pdf - ethernet physical layer                               ;;
28
;;    DP83840A.pdf - ethernet physical layer                               ;;
29
;;    3c59x.c - linux driver                                               ;;
29
;;    3c59x.c - linux driver                                               ;;
30
;;    ethernet driver template by Mike Hibbett                             ;;
30
;;    ethernet driver template by Mike Hibbett                             ;;
31
;;                                                                         ;;
31
;;                                                                         ;;
32
;;  Credits                                                                ;;
32
;;  Credits                                                                ;;
33
;;   Mike Hibbett,                                                         ;;
33
;;   Mike Hibbett,                                                         ;;
34
;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
34
;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
35
;;                                                                         ;;
35
;;                                                                         ;;
36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
37
;;
37
;;
38
;; Copyright (c) 2004, Endre Kozma 
38
;; Copyright (c) 2004, Endre Kozma 
39
;; All rights reserved.
39
;; All rights reserved.
40
;;
40
;;
41
;; Redistribution  and  use  in  source  and  binary  forms, with or without
41
;; Redistribution  and  use  in  source  and  binary  forms, with or without
42
;; modification, are permitted provided  that  the following  conditions are
42
;; modification, are permitted provided  that  the following  conditions are
43
;; met:
43
;; met:
44
;;
44
;;
45
;; 1. Redistributions of source code must retain the above  copyright notice,
45
;; 1. Redistributions of source code must retain the above  copyright notice,
46
;;    this list of conditions and the following disclaimer.
46
;;    this list of conditions and the following disclaimer.
47
;;
47
;;
48
;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
48
;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
49
;;    notice, this  list of conditions  and the  following disclaimer in the
49
;;    notice, this  list of conditions  and the  following disclaimer in the
50
;;    documentation and/or other  materials  provided with  the distribution.
50
;;    documentation and/or other  materials  provided with  the distribution.
51
;;
51
;;
52
;; 3. The name of the author may not be used to  endorse or promote products
52
;; 3. The name of the author may not be used to  endorse or promote products
53
;;    derived from this software without  specific prior  written permission.
53
;;    derived from this software without  specific prior  written permission.
54
;;
54
;;
55
;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
55
;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
56
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57
;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
57
;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
58
;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
58
;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
59
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
60
;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60
;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
61
;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
61
;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
62
;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
62
;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
63
;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
63
;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
64
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65
;;
65
;;
66
;;  History
66
;;  History
67
;;  =======
67
;;  =======
68
;;  $Log: 3C59X.INC,v $
68
;;  $Log: 3C59X.INC,v $
69
;;  Revision 1.3  2004/07/11 12:21:12  kozma
69
;;  Revision 1.3  2004/07/11 12:21:12  kozma
70
;;  Support of vortex chips (3c59x) added.
70
;;  Support of vortex chips (3c59x) added.
71
;;  Support of 3c920 and 3c982 added.
71
;;  Support of 3c920 and 3c982 added.
72
;;  Corrections.
72
;;  Corrections.
73
;;
73
;;
74
;;  Revision 1.2  2004/06/12 19:40:20  kozma
74
;;  Revision 1.2  2004/06/12 19:40:20  kozma
75
;;  Function e3c59x_set_available_media added in order to set
75
;;  Function e3c59x_set_available_media added in order to set
76
;;  the default media in case auto detection finds no valid link.
76
;;  the default media in case auto detection finds no valid link.
77
;;  Incorrect mii check removed (3c900 Cyclone works now).
77
;;  Incorrect mii check removed (3c900 Cyclone works now).
78
;;  Cleanups.
78
;;  Cleanups.
79
;;
79
;;
80
;;  Revision 1.1  2004/06/12 18:27:15  kozma
80
;;  Revision 1.1  2004/06/12 18:27:15  kozma
81
;;  Initial revision
81
;;  Initial revision
82
;;
82
;;
83
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
83
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
84
 
84
 
85
 
85
 
86
format PE DLL native
86
format PE DLL native
87
entry START
87
entry START
88
 
88
 
89
        CURRENT_API             = 0x0200
89
        CURRENT_API             = 0x0200
90
        COMPATIBLE_API          = 0x0100
90
        COMPATIBLE_API          = 0x0100
91
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
91
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
-
 
92
 
-
 
93
; configureable area
92
 
94
 
-
 
95
        MAX_DEVICES             = 16    ; Maximum number of devices this driver may handle
93
        MAX_DEVICES             = 16
96
 
94
        FORCE_FD                = 0     ; forcing full duplex mode makes sense at some cards and link types
97
        FORCE_FD                = 0     ; forcing full duplex mode makes sense at some cards and link types
95
 
98
 
96
        NUM_RX_DESC             = 4     ; a power of 2 number
99
        NUM_RX_DESC             = 32    ; Number of receive descriptors (must be power of 2)
97
        NUM_TX_DESC             = 4     ; a power of 2 number
100
        NUM_TX_DESC             = 16    ; Number of transmit descriptors (must be power of 2)
-
 
101
 
-
 
102
        __DEBUG__               = 1     ; 1 = on, 0 = off
98
 
103
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
99
        __DEBUG__               = 1
104
 
100
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
105
; end configureable area
101
 
106
 
102
section '.flat' readable writable executable
107
section '.flat' readable writable executable
103
 
108
 
104
include '../proc32.inc'
109
include '../proc32.inc'
105
include '../struct.inc'
110
include '../struct.inc'
106
include '../macros.inc'
111
include '../macros.inc'
107
include '../fdo.inc'
112
include '../fdo.inc'
108
include '../netdrv.inc'
113
include '../netdrv.inc'
-
 
114
 
-
 
115
 
-
 
116
if (bsr NUM_RX_DESC)>(bsf NUM_RX_DESC)
-
 
117
  display 'NUM_RX_DESC must be a power of two'
-
 
118
  err
-
 
119
end if
-
 
120
 
-
 
121
if (bsr NUM_TX_DESC)>(bsf NUM_TX_DESC)
-
 
122
  display 'NUM_TX_DESC must be a power of two'
-
 
123
  err
-
 
124
end if
109
 
125
 
110
; Registers
126
; Registers
111
        REG_POWER_MGMT_CTRL     = 0x7c
127
        REG_POWER_MGMT_CTRL     = 0x7c
112
        REG_UP_LIST_PTR         = 0x38
128
        REG_UP_LIST_PTR         = 0x38
113
        REG_UP_PKT_STATUS       = 0x30
129
        REG_UP_PKT_STATUS       = 0x30
114
        REG_TX_FREE_THRESH      = 0x2f
130
        REG_TX_FREE_THRESH      = 0x2f
115
        REG_DN_LIST_PTR         = 0x24
131
        REG_DN_LIST_PTR         = 0x24
116
        REG_DMA_CTRL            = 0x20
132
        REG_DMA_CTRL            = 0x20
117
        REG_TX_STATUS           = 0x1b
133
        REG_TX_STATUS           = 0x1b
118
        REG_RX_STATUS           = 0x18
134
        REG_RX_STATUS           = 0x18
119
        REG_TX_DATA             = 0x10
135
        REG_TX_DATA             = 0x10
120
 
136
 
121
; Common window registers
137
; Common window registers
122
        REG_INT_STATUS          = 0xe
138
        REG_INT_STATUS          = 0xe
123
        REG_COMMAND             = 0xe
139
        REG_COMMAND             = 0xe
124
 
140
 
125
; Register window 7
141
; Register window 7
126
        REG_MASTER_STATUS       = 0xc
142
        REG_MASTER_STATUS       = 0xc
127
        REG_POWER_MGMT_EVENT    = 0xc
143
        REG_POWER_MGMT_EVENT    = 0xc
128
        REG_MASTER_LEN          = 0x6
144
        REG_MASTER_LEN          = 0x6
129
        REG_VLAN_ETHER_TYPE     = 0x4
145
        REG_VLAN_ETHER_TYPE     = 0x4
130
        REG_VLAN_MASK           = 0x0
146
        REG_VLAN_MASK           = 0x0
131
        REG_MASTER_ADDRESS      = 0x0
147
        REG_MASTER_ADDRESS      = 0x0
132
 
148
 
133
; Register window 6
149
; Register window 6
134
        REG_BYTES_XMITTED_OK    = 0xc
150
        REG_BYTES_XMITTED_OK    = 0xc
135
        REG_BYTES_RCVD_OK       = 0xa
151
        REG_BYTES_RCVD_OK       = 0xa
136
        REG_UPPER_FRAMES_OK     = 0x9
152
        REG_UPPER_FRAMES_OK     = 0x9
137
        REG_FRAMES_DEFERRED     = 0x8
153
        REG_FRAMES_DEFERRED     = 0x8
138
        REG_FRAMES_RCVD_OK      = 0x7
154
        REG_FRAMES_RCVD_OK      = 0x7
139
        REG_FRAMES_XMITTED_OK   = 0x6
155
        REG_FRAMES_XMITTED_OK   = 0x6
140
        REG_RX_OVERRUNS         = 0x5
156
        REG_RX_OVERRUNS         = 0x5
141
        REG_LATE_COLLISIONS     = 0x4
157
        REG_LATE_COLLISIONS     = 0x4
142
        REG_SINGLE_COLLISIONS   = 0x3
158
        REG_SINGLE_COLLISIONS   = 0x3
143
        REG_MULTIPLE_COLLISIONS = 0x2
159
        REG_MULTIPLE_COLLISIONS = 0x2
144
        REG_SQE_ERRORS          = 0x1
160
        REG_SQE_ERRORS          = 0x1
145
        REG_CARRIER_LOST        = 0x0
161
        REG_CARRIER_LOST        = 0x0
146
 
162
 
147
; Register window 5
163
; Register window 5
148
        REG_INDICATION_ENABLE   = 0xc
164
        REG_INDICATION_ENABLE   = 0xc
149
        REG_INTERRUPT_ENABLE    = 0xa
165
        REG_INTERRUPT_ENABLE    = 0xa
150
        REG_TX_RECLAIM_THRESH   = 0x9
166
        REG_TX_RECLAIM_THRESH   = 0x9
151
        REG_RX_FILTER           = 0x8
167
        REG_RX_FILTER           = 0x8
152
        REG_RX_EARLY_THRESH     = 0x6
168
        REG_RX_EARLY_THRESH     = 0x6
153
        REG_TX_START_THRESH     = 0x0
169
        REG_TX_START_THRESH     = 0x0
154
 
170
 
155
; Register window 4
171
; Register window 4
156
        REG_UPPER_BYTES_OK      = 0xe
172
        REG_UPPER_BYTES_OK      = 0xe
157
        REG_BAD_SSD             = 0xc
173
        REG_BAD_SSD             = 0xc
158
        REG_MEDIA_STATUS        = 0xa
174
        REG_MEDIA_STATUS        = 0xa
159
        REG_PHYSICAL_MGMT       = 0x8
175
        REG_PHYSICAL_MGMT       = 0x8
160
        REG_NETWORK_DIAGNOSTIC  = 0x6
176
        REG_NETWORK_DIAGNOSTIC  = 0x6
161
        REG_FIFO_DIAGNOSTIC     = 0x4
177
        REG_FIFO_DIAGNOSTIC     = 0x4
162
        REG_VCO_DIAGNOSTIC      = 0x2   ; may not supported
178
        REG_VCO_DIAGNOSTIC      = 0x2   ; may not supported
163
 
179
 
164
; Bits in register window 4
180
; Bits in register window 4
165
        BIT_AUTOSELECT          = 24
181
        BIT_AUTOSELECT          = 24
166
 
182
 
167
; Register window 3
183
; Register window 3
168
        REG_TX_FREE             = 0xc
184
        REG_TX_FREE             = 0xc
169
        REG_RX_FREE             = 0xa
185
        REG_RX_FREE             = 0xa
170
        REG_MEDIA_OPTIONS       = 0x8
186
        REG_MEDIA_OPTIONS       = 0x8
171
        REG_MAC_CONTROL         = 0x6
187
        REG_MAC_CONTROL         = 0x6
172
        REG_MAX_PKT_SIZE        = 0x4
188
        REG_MAX_PKT_SIZE        = 0x4
173
        REG_INTERNAL_CONFIG     = 0x0
189
        REG_INTERNAL_CONFIG     = 0x0
174
 
190
 
175
; Register window 2
191
; Register window 2
176
        REG_RESET_OPTIONS       = 0xc
192
        REG_RESET_OPTIONS       = 0xc
177
        REG_STATION_MASK_HI     = 0xa
193
        REG_STATION_MASK_HI     = 0xa
178
        REG_STATION_MASK_MID    = 0x8
194
        REG_STATION_MASK_MID    = 0x8
179
        REG_STATION_MASK_LO     = 0x6
195
        REG_STATION_MASK_LO     = 0x6
180
        REG_STATION_ADDRESS_HI  = 0x4
196
        REG_STATION_ADDRESS_HI  = 0x4
181
        REG_STATION_ADDRESS_MID = 0x2
197
        REG_STATION_ADDRESS_MID = 0x2
182
        REG_STATION_ADDRESS_LO  = 0x0
198
        REG_STATION_ADDRESS_LO  = 0x0
183
 
199
 
184
; Register window 1
200
; Register window 1
185
        REG_TRIGGER_BITS        = 0xc
201
        REG_TRIGGER_BITS        = 0xc
186
        REG_SOS_BITS            = 0xa
202
        REG_SOS_BITS            = 0xa
187
        REG_WAKE_ON_TIMER       = 0x8
203
        REG_WAKE_ON_TIMER       = 0x8
188
        REG_SMB_RXBYTES         = 0x7
204
        REG_SMB_RXBYTES         = 0x7
189
        REG_SMB_DIAG            = 0x5
205
        REG_SMB_DIAG            = 0x5
190
        REG_SMB_ARB             = 0x4
206
        REG_SMB_ARB             = 0x4
191
        REG_SMB_STATUS          = 0x2
207
        REG_SMB_STATUS          = 0x2
192
        REG_SMB_ADDRESS         = 0x1
208
        REG_SMB_ADDRESS         = 0x1
193
        REG_SMB_FIFO_DATA       = 0x0
209
        REG_SMB_FIFO_DATA       = 0x0
194
 
210
 
195
; Register window 0
211
; Register window 0
196
        REG_EEPROM_DATA         = 0xc
212
        REG_EEPROM_DATA         = 0xc
197
        REG_EEPROM_COMMAND      = 0xa
213
        REG_EEPROM_COMMAND      = 0xa
198
        REG_BIOS_ROM_DATA       = 0x8
214
        REG_BIOS_ROM_DATA       = 0x8
199
        REG_BIOS_ROM_ADDR       = 0x4
215
        REG_BIOS_ROM_ADDR       = 0x4
200
 
216
 
201
; Physical management bits
217
; Physical management bits
202
        BIT_MGMT_DIR            = 2     ; drive with the data written in mgmtData
218
        BIT_MGMT_DIR            = 2     ; drive with the data written in mgmtData
203
        BIT_MGMT_DATA           = 1     ; MII management data bit
219
        BIT_MGMT_DATA           = 1     ; MII management data bit
204
        BIT_MGMT_CLK            = 0     ; MII management clock
220
        BIT_MGMT_CLK            = 0     ; MII management clock
205
 
221
 
206
; MII commands
222
; MII commands
207
        MII_CMD_MASK            = (1111b shl 10)
223
        MII_CMD_MASK            = (1111b shl 10)
208
        MII_CMD_READ            = (0110b shl 10)
224
        MII_CMD_READ            = (0110b shl 10)
209
        MII_CMD_WRITE           = (0101b shl 10)
225
        MII_CMD_WRITE           = (0101b shl 10)
210
 
226
 
211
; eeprom bits and commands
227
; eeprom bits and commands
212
        EEPROM_CMD_READ         = 0x80
228
        EEPROM_CMD_READ         = 0x80
213
        EEPROM_BIT_BUSY         = 15
229
        EEPROM_BIT_BUSY         = 15
214
 
230
 
215
; eeprom registers
231
; eeprom registers
216
        EEPROM_REG_OEM_NODE_ADDR= 0xa
232
        EEPROM_REG_OEM_NODE_ADDR= 0xa
217
        EEPROM_REG_CAPABILITIES = 0x10
233
        EEPROM_REG_CAPABILITIES = 0x10
218
 
234
 
219
; Commands for command register
235
; Commands for command register
220
        SELECT_REGISTER_WINDOW  = (1 shl 11)
236
        SELECT_REGISTER_WINDOW  = (1 shl 11)
221
 
237
 
222
; Hw capabilities bitflags
238
; Hw capabilities bitflags
223
        IS_VORTEX               = 0x0001
239
        IS_VORTEX               = 0x0001
224
        IS_BOOMERANG            = 0x0002
240
        IS_BOOMERANG            = 0x0002
225
        IS_CYCLONE              = 0x0004
241
        IS_CYCLONE              = 0x0004
226
        IS_TORNADO              = 0x0008
242
        IS_TORNADO              = 0x0008
227
        EEPROM_8BIT             = 0x0010
243
        EEPROM_8BIT             = 0x0010
228
        HAS_PWR_CTRL            = 0x0020
244
        HAS_PWR_CTRL            = 0x0020
229
        HAS_MII                 = 0x0040
245
        HAS_MII                 = 0x0040
230
        HAS_NWAY                = 0x0080
246
        HAS_NWAY                = 0x0080
231
        HAS_CB_FNS              = 0x0100
247
        HAS_CB_FNS              = 0x0100
232
        INVERT_MII_PWR          = 0x0200
248
        INVERT_MII_PWR          = 0x0200
233
        INVERT_LED_PWR          = 0x0400
249
        INVERT_LED_PWR          = 0x0400
234
        MAX_COLLISION_RESET     = 0x0800
250
        MAX_COLLISION_RESET     = 0x0800
235
        EEPROM_OFFSET           = 0x1000
251
        EEPROM_OFFSET           = 0x1000
236
        HAS_HWCKSM              = 0x2000
252
        HAS_HWCKSM              = 0x2000
237
        EXTRA_PREAMBLE          = 0x4000
253
        EXTRA_PREAMBLE          = 0x4000
238
 
254
 
239
; Status
255
; Status
240
        IntLatch                = 0x0001
256
        IntLatch                = 0x0001
241
        HostError               = 0x0002
257
        HostError               = 0x0002
242
        TxComplete              = 0x0004
258
        TxComplete              = 0x0004
243
        TxAvailable             = 0x0008
259
        TxAvailable             = 0x0008
244
        RxComplete              = 0x0010
260
        RxComplete              = 0x0010
245
        RxEarly                 = 0x0020
261
        RxEarly                 = 0x0020
246
        IntReq                  = 0x0040
262
        IntReq                  = 0x0040
247
        StatsFull               = 0x0080
263
        StatsFull               = 0x0080
248
        DMADone                 = 0x0100
264
        DMADone                 = 0x0100
249
        DownComplete            = 0x0200
265
        DownComplete            = 0x0200
250
        UpComplete              = 0x0400
266
        UpComplete              = 0x0400
251
        DMAInProgress           = 0x0800        ; 1 shl 11  (DMA controller is still busy)
267
        DMAInProgress           = 0x0800        ; 1 shl 11  (DMA controller is still busy)
252
        CmdInProgress           = 0x1000        ; 1 shl 12  (EL3_CMD is still busy)
268
        CmdInProgress           = 0x1000        ; 1 shl 12  (EL3_CMD is still busy)
253
 
269
 
254
        S_5_INTS                = HostError + RxEarly + UpComplete + DownComplete + StatsFull ;+ TxComplete + RxComplete  + TxAvailable
270
        S_5_INTS                = HostError + RxEarly + UpComplete + DownComplete + StatsFull ;+ TxComplete + RxComplete  + TxAvailable
255
 
271
 
256
; Commands
272
; Commands
257
        TotalReset              = 0 shl 11
273
        TotalReset              = 0 shl 11
258
        SelectWindow            = 1 shl 11
274
        SelectWindow            = 1 shl 11
259
        StartCoax               = 2 shl 11
275
        StartCoax               = 2 shl 11
260
        RxDisable               = 3 shl 11
276
        RxDisable               = 3 shl 11
261
        RxEnable                = 4 shl 11
277
        RxEnable                = 4 shl 11
262
        RxReset                 = 5 shl 11
278
        RxReset                 = 5 shl 11
263
        UpStall                 = 6 shl 11
279
        UpStall                 = 6 shl 11
264
        UpUnstall               = (6 shl 11)+1
280
        UpUnstall               = (6 shl 11)+1
265
        DownStall               = (6 shl 11)+2
281
        DownStall               = (6 shl 11)+2
266
        DownUnstall             = (6 shl 11)+3
282
        DownUnstall             = (6 shl 11)+3
267
        RxDiscard               = 8 shl 11
283
        RxDiscard               = 8 shl 11
268
        TxEnable                = 9 shl 11
284
        TxEnable                = 9 shl 11
269
        TxDisable               = 10 shl 11
285
        TxDisable               = 10 shl 11
270
        TxReset                 = 11 shl 11
286
        TxReset                 = 11 shl 11
271
        FakeIntr                = 12 shl 11
287
        FakeIntr                = 12 shl 11
272
        AckIntr                 = 13 shl 11
288
        AckIntr                 = 13 shl 11
273
        SetIntrEnb              = 14 shl 11
289
        SetIntrEnb              = 14 shl 11
274
        SetStatusEnb            = 15 shl 11
290
        SetStatusEnb            = 15 shl 11
275
        SetRxFilter             = 16 shl 11
291
        SetRxFilter             = 16 shl 11
276
        SetRxThreshold          = 17 shl 11
292
        SetRxThreshold          = 17 shl 11
277
        SetTxThreshold          = 18 shl 11
293
        SetTxThreshold          = 18 shl 11
278
        SetTxStart              = 19 shl 11
294
        SetTxStart              = 19 shl 11
279
        StartDMAUp              = 20 shl 11
295
        StartDMAUp              = 20 shl 11
280
        StartDMADown            = (20 shl 11)+1
296
        StartDMADown            = (20 shl 11)+1
281
        StatsEnable             = 21 shl 11
297
        StatsEnable             = 21 shl 11
282
        StatsDisable            = 22 shl 11
298
        StatsDisable            = 22 shl 11
283
        StopCoax                = 23 shl 11
299
        StopCoax                = 23 shl 11
284
        SetFilterBit            = 25 shl 11
300
        SetFilterBit            = 25 shl 11
285
 
301
 
286
; Rx mode bits
302
; Rx mode bits
287
        RxStation               = 1
303
        RxStation               = 1
288
        RxMulticast             = 2
304
        RxMulticast             = 2
289
        RxBroadcast             = 4
305
        RxBroadcast             = 4
290
        RxProm                  = 8
306
        RxProm                  = 8
291
 
307
 
292
        MAX_ETH_FRAME_SIZE      = 1514
308
        MAX_ETH_FRAME_SIZE      = 1514
293
 
309
 
294
 
310
 
295
struct  tx_desc
311
struct  tx_desc
296
 
312
 
297
        next_ptr                dd ?
313
        next_ptr                dd ?
298
        frame_start_hdr         dd ?
314
        frame_start_hdr         dd ?
299
        frag_addr               dd ?    ; for packet data
315
        frag_addr               dd ?    ; for packet data
300
        frag_len                dd ?    ; for packet data
316
        frag_len                dd ?    ; for packet data
301
        realaddr                dd ?
317
        realaddr                dd ?
302
                                rd 3    ; align 32
318
                                rd 3    ; align 32
303
ends
319
ends
304
 
320
 
305
 
321
 
306
struct  rx_desc
322
struct  rx_desc
307
 
323
 
308
        next_ptr                dd ?
324
        next_ptr                dd ?
309
        pkt_status              dd ?
325
        pkt_status              dd ?
310
        frag_addr               dd ?
326
        frag_addr               dd ?
311
        frag_len                dd ?    ; for packet data
327
        frag_len                dd ?    ; for packet data
312
        realaddr                dd ?
328
        realaddr                dd ?
313
                                rd 3    ; align 32
329
                                rd 3    ; align 32
314
ends
330
ends
315
 
331
 
316
 
332
 
317
struct  device                  ETH_DEVICE
333
struct  device                  ETH_DEVICE
318
 
334
 
319
        io_addr                 dd ?
335
        io_addr                 dd ?
320
        pci_bus                 dd ?
336
        pci_bus                 dd ?
321
        pci_dev                 dd ?
337
        pci_dev                 dd ?
322
        irq_line                db ?
338
        irq_line                db ?
323
                                rb 3    ; alignment
339
                                rb 3    ; alignment
324
 
340
 
325
        curr_tx                 dd ?
341
        curr_tx                 dd ?
326
        curr_rx                 dd ?
342
        curr_rx                 dd ?
327
        prev_tx_frame           dd ?
343
        prev_tx_frame           dd ?
328
        ver_id                  db ?
344
        ver_id                  db ?
329
        full_bus_master         db ?
345
        full_bus_master         db ?
330
        has_hwcksm              db ?
346
        has_hwcksm              db ?
331
        preamble                db ?
347
        preamble                db ?
332
        dn_list_ptr_cleared     db ?
348
        dn_list_ptr_cleared     db ?
333
        internal_link           dd ?    ; link state (to be used only internally by driver)
349
        internal_link           dd ?    ; link state (to be used only internally by driver)
334
 
350
 
335
        rb 0x100 - ($ and 0xff) ; align 256
351
        rb 0x100 - ($ and 0xff) ; align 256
336
        tx_desc_buffer          rd (sizeof.tx_desc*NUM_TX_DESC)/4
352
        tx_desc_buffer          rd (sizeof.tx_desc*NUM_TX_DESC)/4
337
        rx_desc_buffer          rd (sizeof.rx_desc*NUM_RX_DESC)/4
353
        rx_desc_buffer          rd (sizeof.rx_desc*NUM_RX_DESC)/4
338
 
354
 
339
ends
355
ends
340
 
356
 
341
 
357
 
342
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
358
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
343
;;                        ;;
359
;;                        ;;
344
;; proc START             ;;
360
;; proc START             ;;
345
;;                        ;;
361
;;                        ;;
346
;; (standard driver proc) ;;
362
;; (standard driver proc) ;;
347
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
363
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
348
 
364
 
349
proc START c, reason:dword, cmdline:dword
365
proc START c, reason:dword, cmdline:dword
350
 
366
 
351
        cmp     [reason], DRV_ENTRY
367
        cmp     [reason], DRV_ENTRY
352
        jne     .fail
368
        jne     .fail
353
 
369
 
354
        DEBUGF  2,"Loading driver\n"
370
        DEBUGF  2,"Loading driver\n"
355
        invoke  RegService, my_service, service_proc
371
        invoke  RegService, my_service, service_proc
356
        ret
372
        ret
357
 
373
 
358
  .fail:
374
  .fail:
359
        xor     eax, eax
375
        xor     eax, eax
360
        ret
376
        ret
361
 
377
 
362
endp
378
endp
363
 
379
 
364
 
380
 
365
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
381
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366
;;                        ;;
382
;;                        ;;
367
;; proc SERVICE_PROC      ;;
383
;; proc SERVICE_PROC      ;;
368
;;                        ;;
384
;;                        ;;
369
;; (standard driver proc) ;;
385
;; (standard driver proc) ;;
370
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
386
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371
 
387
 
372
align 4
388
align 4
373
proc service_proc stdcall, ioctl:dword
389
proc service_proc stdcall, ioctl:dword
374
 
390
 
375
        mov     edx, [ioctl]
391
        mov     edx, [ioctl]
376
        mov     eax, [edx + IOCTL.io_code]
392
        mov     eax, [edx + IOCTL.io_code]
377
 
393
 
378
;------------------------------------------------------
394
;------------------------------------------------------
379
 
395
 
380
        cmp     eax, 0 ;SRV_GETVERSION
396
        cmp     eax, 0 ;SRV_GETVERSION
381
        jne     @F
397
        jne     @F
382
 
398
 
383
        cmp     [edx + IOCTL.out_size], 4
399
        cmp     [edx + IOCTL.out_size], 4
384
        jb      .fail
400
        jb      .fail
385
        mov     eax, [edx + IOCTL.output]
401
        mov     eax, [edx + IOCTL.output]
386
        mov     [eax], dword API_VERSION
402
        mov     [eax], dword API_VERSION
387
 
403
 
388
        xor     eax, eax
404
        xor     eax, eax
389
        ret
405
        ret
390
 
406
 
391
;------------------------------------------------------
407
;------------------------------------------------------
392
  @@:
408
  @@:
393
        cmp     eax, 1 ;SRV_HOOK
409
        cmp     eax, 1 ;SRV_HOOK
394
        jne     .fail
410
        jne     .fail
395
 
411
 
396
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
412
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
397
        jb      .fail
413
        jb      .fail
398
 
414
 
399
        mov     eax, [edx + IOCTL.input]
415
        mov     eax, [edx + IOCTL.input]
400
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
416
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
401
        jne     .fail                                   ; other types of this hardware dont exist
417
        jne     .fail                                   ; other types of this hardware dont exist
402
 
418
 
403
; check if the device is already listed
419
; check if the device is already listed
404
 
420
 
405
        mov     ecx, [vortex_devices]
421
        mov     ecx, [devices]
406
        test    ecx, ecx
422
        test    ecx, ecx
407
        jz      .maybeboomerang
423
        jz      .firstdevice
408
 
424
 
409
        mov     esi, vortex_list
425
        mov     esi, device_list
410
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
426
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
411
        mov     ax , [eax+1]                            ;
427
        mov     ax , [eax+1]                            ;
412
  .nextdevice:
428
  .nextdevice:
413
        mov     ebx, [esi]
429
        mov     ebx, [esi]
414
        cmp     al, byte[ebx + device.pci_bus]
430
        cmp     al, byte[ebx + device.pci_bus]
415
        jne     @f
431
        jne     @f
416
        cmp     ah, byte[ebx + device.pci_dev]
432
        cmp     ah, byte[ebx + device.pci_dev]
417
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
433
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
418
       @@:
434
       @@:
419
        add     esi, 4
435
        add     esi, 4
420
        loop    .nextdevice
436
        loop    .nextdevice
421
 
-
 
422
 
-
 
423
  .maybeboomerang:
-
 
424
        mov     ecx, [boomerang_devices]
-
 
425
        test    ecx, ecx
-
 
426
        jz      .firstdevice
-
 
427
 
-
 
428
        mov     esi, boomerang_list
-
 
429
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
-
 
430
        mov     ax, [eax+1]                             ;
-
 
431
  .nextdevice2:
-
 
432
        mov     ebx, [esi]
-
 
433
        cmp     al, byte[ebx + device.pci_bus]
-
 
434
        jne     @f
-
 
435
        cmp     ah, byte[ebx + device.pci_dev]
-
 
436
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
-
 
437
       @@:
-
 
438
        add     esi, 4
-
 
439
        loop    .nextdevice2
-
 
440
 
-
 
441
 
437
 
442
; This device doesnt have its own eth_device structure yet, lets create one
438
; This device doesnt have its own eth_device structure yet, lets create one
443
  .firstdevice:
-
 
444
        mov     ecx, [boomerang_devices]
-
 
445
        add     ecx, [vortex_devices]
439
  .firstdevice:
446
        cmp     ecx, MAX_DEVICES                        ; First check if the driver can handle one more card
440
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
447
        jae     .fail
441
        jae     .fail
448
 
442
 
449
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
443
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
450
 
444
 
451
; Fill in the direct call addresses into the struct
445
; Fill in the direct call addresses into the struct
452
 
446
 
453
        mov     [ebx + device.reset], reset
447
        mov     [ebx + device.reset], reset
454
        mov     [ebx + device.transmit], null_op
448
        mov     [ebx + device.transmit], null_op
455
        mov     [ebx + device.unload], null_op
449
        mov     [ebx + device.unload], null_op
456
        mov     [ebx + device.name], my_service
450
        mov     [ebx + device.name], my_service
457
 
451
 
458
; save the pci bus and device numbers
452
; save the pci bus and device numbers
459
 
453
 
460
        mov     eax, [edx + IOCTL.input]
454
        mov     eax, [edx + IOCTL.input]
461
        movzx   ecx, byte[eax+1]
455
        movzx   ecx, byte[eax+1]
462
        mov     [ebx + device.pci_bus], ecx
456
        mov     [ebx + device.pci_bus], ecx
463
        movzx   ecx, byte[eax+2]
457
        movzx   ecx, byte[eax+2]
464
        mov     [ebx + device.pci_dev], ecx
458
        mov     [ebx + device.pci_dev], ecx
465
 
459
 
466
; Now, it's time to find the base io addres of the PCI device
460
; Now, it's time to find the base io addres of the PCI device
467
 
461
 
468
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
462
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
469
        mov     [ebx + device.io_addr], eax
463
        mov     [ebx + device.io_addr], eax
470
 
464
 
471
; We've found the io address, find IRQ now
465
; We've found the io address, find IRQ now
472
 
466
 
473
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
467
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
474
        mov     [ebx + device.irq_line], al
468
        mov     [ebx + device.irq_line], al
475
 
469
 
476
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
470
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
477
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
471
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
478
 
472
 
479
; Ok, the eth_device structure is ready, let's probe the device
473
; Ok, the eth_device structure is ready, let's probe the device
480
        call    probe                                                   ; this function will output in eax
474
        call    probe                                                   ; this function will output in eax
481
        test    eax, eax
475
        test    eax, eax
482
        jnz     .err                                                    ; If an error occured, exit
476
        jnz     .err                                                    ; If an error occured, exit
483
 
-
 
484
 
-
 
485
        movzx   ecx, [ebx + device.ver_id]
-
 
486
        test    word [hw_versions+2+ecx*4], IS_VORTEX
-
 
487
        jz      .not_vortex
-
 
488
 
477
 
489
        mov     eax, [vortex_devices]                                   ; Add the device structure to our device list
478
        mov     eax, [devices]                                          ; Add the device structure to our device list
490
        mov     [vortex_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
479
        mov     [device_list+4*eax], ebx                                ;
491
        inc     [vortex_devices]                                        ;
480
        inc     [devices]                                               ;
492
 
481
 
493
  .register:
482
  .register:
494
        mov     [ebx + device.type], NET_TYPE_ETH
483
        mov     [ebx + device.type], NET_TYPE_ETH
495
        invoke  NetRegDev
484
        invoke  NetRegDev
496
 
485
 
497
        cmp     eax, -1
486
        cmp     eax, -1
498
        je      .destroy
487
        je      .destroy
499
 
488
 
500
        call    start_device
489
        call    start_device
501
        ret
490
        ret
502
 
-
 
503
  .not_vortex:
-
 
504
        mov     eax, [boomerang_devices]                                ; Add the device structure to our device list
-
 
505
        mov     [boomerang_list+4*eax], ebx                             ; (IRQ handler uses this list to find device)
-
 
506
        inc     [boomerang_devices]
-
 
507
 
-
 
508
        jmp     .register
-
 
509
 
491
 
510
; If the device was already loaded, find the device number and return it in eax
492
; If the device was already loaded, find the device number and return it in eax
511
 
493
 
512
  .find_devicenum:
494
  .find_devicenum:
513
        DEBUGF  2,"Trying to find device number of already registered device\n"
495
        DEBUGF  2,"Trying to find device number of already registered device\n"
514
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
496
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
515
                                                                        ; into a device number in edi
497
                                                                        ; into a device number in edi
516
        mov     eax, edi                                                ; Application wants it in eax instead
498
        mov     eax, edi                                                ; Application wants it in eax instead
517
        DEBUGF  2,"Kernel says: %u\n", eax
499
        DEBUGF  2,"Kernel says: %u\n", eax
518
        ret
500
        ret
519
 
501
 
520
; If an error occured, remove all allocated data and exit (returning -1 in eax)
502
; If an error occured, remove all allocated data and exit (returning -1 in eax)
521
 
503
 
522
  .destroy:
504
  .destroy:
523
        ; todo: reset device into virgin state
505
        ; todo: reset device into virgin state
524
 
506
 
525
  .err:
507
  .err:
526
        invoke  KernelFree, ebx
508
        invoke  KernelFree, ebx
527
  .fail:
509
  .fail:
528
        DEBUGF  2, "Failed to load\n"
510
        DEBUGF  2, "Failed to load\n"
529
        or      eax, -1
511
        or      eax, -1
530
        ret
512
        ret
531
 
513
 
532
;------------------------------------------------------
514
;------------------------------------------------------
533
endp
515
endp
534
 
516
 
535
 
517
 
536
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
518
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
537
;;                                                                        ;;
519
;;                                                                        ;;
538
;;        Actual Hardware dependent code starts here                      ;;
520
;;        Actual Hardware dependent code starts here                      ;;
539
;;                                                                        ;;
521
;;                                                                        ;;
540
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
522
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
541
 
523
 
542
 
524
 
543
align 4
525
align 4
544
null_op:
526
null_op:
545
 
527
 
546
        ret
528
        ret
547
 
529
 
548
 
530
 
549
 
531
 
550
;***************************************************************************
532
;***************************************************************************
551
;   Function
533
;   Function
552
;      probe
534
;      probe
553
;   Description
535
;   Description
554
;      Searches for an ethernet card, enables it and clears the rx buffer
536
;      Searches for an ethernet card, enables it and clears the rx buffer
555
;   Destroyed registers
537
;   Destroyed registers
556
;      eax, ebx, ecx, edx, edi, esi
538
;      eax, ebx, ecx, edx, edi, esi
557
;
539
;
558
;***************************************************************************
540
;***************************************************************************
559
 
541
 
560
align 4
542
align 4
561
probe:
543
probe:
562
 
544
 
563
        DEBUGF  1,"Probing 3com card\n"
545
        DEBUGF  1,"Probing 3com card\n"
564
 
546
 
565
; Make the device a bus master
547
; Make the device a bus master
566
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
548
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
567
        or      al, PCI_CMD_MASTER
549
        or      al, PCI_CMD_MASTER
568
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
550
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
569
 
551
 
570
; wake up the card
552
; wake up the card
571
        DEBUGF 1,"Checking if the device is awake\n"
553
        DEBUGF 1,"Checking if the device is awake\n"
572
 
554
 
573
; wake up - we directly do it by programming PCI
555
; wake up - we directly do it by programming PCI
574
; check if the device is power management capable
556
; check if the device is power management capable
575
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.status
557
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.status
576
        test    al, PCI_STATUS_CAPA     ; is there "new capabilities" linked list?
558
        test    al, PCI_STATUS_CAPA     ; is there "new capabilities" linked list?
577
        jz      .device_awake
559
        jz      .device_awake
578
 
560
 
579
; search for power management register
561
; search for power management register
580
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.cap_ptr
562
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.cap_ptr
581
        and     al, not 3
563
        and     al, not 3
582
        cmp     al, 0x3f
564
        cmp     al, 0x3f
583
        jbe     .device_awake           ; invalid pointer if less then PCI header size
565
        jbe     .device_awake           ; invalid pointer if less then PCI header size
584
 
566
 
585
; traverse the list
567
; traverse the list
586
        movzx   esi, al
568
        movzx   esi, al
587
  .pm_loop:
569
  .pm_loop:
588
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
570
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
589
        cmp     al, 1
571
        cmp     al, 1
590
        je      .set_pm_state
572
        je      .set_pm_state
591
        movzx   esi, ah                 ; load address of next capability
573
        movzx   esi, ah                 ; load address of next capability
592
        test    ah, ah                  ; 0 if none left
574
        test    ah, ah                  ; 0 if none left
593
        jnz     .pm_loop
575
        jnz     .pm_loop
594
        jmp     .device_awake
576
        jmp     .device_awake
595
 
577
 
596
; wake up the device if necessary
578
; wake up the device if necessary
597
  .set_pm_state:
579
  .set_pm_state:
598
        DEBUGF 1,"Waking up the device\n"
580
        DEBUGF 1,"Waking up the device\n"
599
        add     esi, 4                  ; offset for power management
581
        add     esi, 4                  ; offset for power management
600
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
582
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
601
        test    al, 11b
583
        test    al, 11b
602
        jz      .device_awake
584
        jz      .device_awake
603
        and     al, not 11b             ; set state to D0
585
        and     al, not 11b             ; set state to D0
604
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi, eax
586
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi, eax
605
 
587
 
606
  .device_awake:
588
  .device_awake:
607
        DEBUGF 1,"Device is awake\n"
589
        DEBUGF 1,"Device is awake\n"
608
 
590
 
609
; Check device/vendor ID
591
; Check device/vendor ID
610
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
592
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
611
 
593
 
612
        DEBUGF  1,"Vendor id: 0x%x\n", ax
594
        DEBUGF  1,"Vendor id: 0x%x\n", ax
613
 
595
 
614
        cmp     ax, 0x10B7
596
        cmp     ax, 0x10B7
615
        jne     .notfound
597
        jne     .notfound
616
        shr     eax, 16
598
        shr     eax, 16
617
 
599
 
618
        DEBUGF  1,"Vendor ok!, device id: 0x%x\n", ax
600
        DEBUGF  1,"Vendor ok!, device id: 0x%x\n", ax
619
 
601
 
620
; get chip version
602
; get chip version
621
        mov     ecx, HW_VERSIONS_SIZE/4-1
603
        mov     ecx, HW_VERSIONS_SIZE/4-1
622
  .loop:
604
  .loop:
623
        cmp     ax, [hw_versions+ecx*4]
605
        cmp     ax, [hw_versions+ecx*4]
624
        jz      .found
606
        jz      .found
625
        loop    .loop
607
        loop    .loop
626
  .notfound:
608
  .notfound:
627
        DEBUGF  2,"Device id not found in list!\n"
609
        DEBUGF  2,"Device id not found in list!\n"
628
        or      eax, -1
610
        or      eax, -1
629
        ret
611
        ret
630
  .found:
612
  .found:
631
        mov     esi, [hw_str+ecx*4]
613
        mov     esi, [hw_str+ecx*4]
632
        DEBUGF  1,"Hardware type: %s\n", esi
614
        DEBUGF  1,"Hardware type: %s\n", esi
633
        mov     [ebx + device.name], esi
615
        mov     [ebx + device.name], esi
634
 
616
 
635
        mov     [ebx + device.ver_id], cl
617
        mov     [ebx + device.ver_id], cl
636
        test    word [hw_versions+2+ecx*4], HAS_HWCKSM
618
        test    word [hw_versions+2+ecx*4], HAS_HWCKSM
637
        setnz   [ebx + device.has_hwcksm]
619
        setnz   [ebx + device.has_hwcksm]
638
; set pci latency for vortex cards
620
; set pci latency for vortex cards
639
        test    word [hw_versions+2+ecx*4], IS_VORTEX
621
        test    word [hw_versions+2+ecx*4], IS_VORTEX
640
        jz      .not_vortex
622
        jz      .not_vortex
641
 
623
 
642
        mov     al, 11111000b ; 248 = max latency
624
        mov     al, 11111000b ; 248 = max latency
643
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
625
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
644
 
626
 
645
  .not_vortex:
627
  .not_vortex:
646
; set RX/TX functions
628
; set RX/TX functions
647
        mov     ax, EEPROM_REG_CAPABILITIES
629
        mov     ax, EEPROM_REG_CAPABILITIES
648
        call    read_eeprom
630
        call    read_eeprom
649
        test    al, 100000b ; full bus master?
631
        test    al, 100000b ; full bus master?
650
        setnz   [ebx + device.full_bus_master]
632
        setnz   [ebx + device.full_bus_master]
651
        jnz     .boomerang_func
633
        jnz     .boomerang_func
652
        mov     [ebx + device.transmit], vortex_transmit
634
        mov     [ebx + device.transmit], vortex_transmit
653
        DEBUGF  2,"Device is a vortex type\n"
635
        DEBUGF  2,"Device is a vortex type\n"
654
        DEBUGF  2,"I'm sorry but vortex code hasnt been tested yet\n"
636
        DEBUGF  2,"I'm sorry but vortex code hasnt been tested yet\n"
655
        DEBUGF  2,"Please contact me on hidnplayr@kolibrios.org\n"
637
        DEBUGF  2,"Please contact me on hidnplayr@kolibrios.org\n"
656
        DEBUGF  2,"If you can help me finish it!\n"
638
        DEBUGF  2,"If you can help me finish it!\n"
657
        or      eax, -1
639
        or      eax, -1
658
        ret
640
        ret
659
        jmp     @f
641
        jmp     @f
660
  .boomerang_func: ; full bus master, so use boomerang functions
642
  .boomerang_func: ; full bus master, so use boomerang functions
661
        mov     [ebx + device.transmit], boomerang_transmit
643
        mov     [ebx + device.transmit], boomerang_transmit
662
        DEBUGF  1,"Device is a boomerang type\n"
644
        DEBUGF  1,"Device is a boomerang type\n"
663
       @@:
645
       @@:
664
        call    read_mac_eeprom
646
        call    read_mac_eeprom
665
 
647
 
666
        test    byte [ebx + device.full_bus_master], 0xff
648
        test    byte [ebx + device.full_bus_master], 0xff
667
        jz      .set_preamble
649
        jz      .set_preamble
668
; switch to register window 2
650
; switch to register window 2
669
        set_io  [ebx + device.io_addr], 0
651
        set_io  [ebx + device.io_addr], 0
670
        set_io  [ebx + device.io_addr], REG_COMMAND
652
        set_io  [ebx + device.io_addr], REG_COMMAND
671
        mov     ax, SELECT_REGISTER_WINDOW+2
653
        mov     ax, SELECT_REGISTER_WINDOW+2
672
        out     dx, ax
654
        out     dx, ax
673
; activate xcvr by setting some magic bits
655
; activate xcvr by setting some magic bits
674
        set_io  [ebx + device.io_addr], REG_RESET_OPTIONS
656
        set_io  [ebx + device.io_addr], REG_RESET_OPTIONS
675
        in      ax, dx
657
        in      ax, dx
676
        and     ax, not 0x4010
658
        and     ax, not 0x4010
677
        movzx   ecx, [ebx + device.ver_id]
659
        movzx   ecx, [ebx + device.ver_id]
678
        test    word [ecx*4+hw_versions+2], INVERT_LED_PWR
660
        test    word [ecx*4+hw_versions+2], INVERT_LED_PWR
679
        jz      @f
661
        jz      @f
680
        or      al, 0x10
662
        or      al, 0x10
681
       @@:
663
       @@:
682
        test    word [ecx*4+hw_versions+2], INVERT_MII_PWR
664
        test    word [ecx*4+hw_versions+2], INVERT_MII_PWR
683
        jz      @f
665
        jz      @f
684
        or      ah, 0x40
666
        or      ah, 0x40
685
       @@:
667
       @@:
686
        out     dx, ax
668
        out     dx, ax
687
  .set_preamble:
669
  .set_preamble:
688
; use preamble as default
670
; use preamble as default
689
        mov     byte [ebx + device.preamble], 1 ; enable preamble
671
        mov     byte [ebx + device.preamble], 1 ; enable preamble
690
 
672
 
691
        DEBUGF 1,"Global reset..\n"
673
        DEBUGF 1,"Global reset..\n"
692
 
674
 
693
; GlobalReset
675
; GlobalReset
694
        set_io  [ebx + device.io_addr], 0
676
        set_io  [ebx + device.io_addr], 0
695
        set_io  [ebx + device.io_addr], REG_COMMAND
677
        set_io  [ebx + device.io_addr], REG_COMMAND
696
        xor     eax, eax
678
        xor     eax, eax
697
;       or      al, 0x14
679
;       or      al, 0x14
698
        out     dx, ax
680
        out     dx, ax
699
; wait for GlobalReset to complete
681
; wait for GlobalReset to complete
700
        mov     ecx, 64000
682
        mov     ecx, 2000
701
  .rsloop:
683
  .rsloop:
702
        in      ax , dx
684
        in      ax, dx
703
        test    ah , 10000b             ; CmdInProgress
685
        test    ah, 10000b             ; CmdInProgress
-
 
686
 
-
 
687
        pusha
-
 
688
        mov     esi, 1
-
 
689
        invoke  Sleep
-
 
690
        popa
-
 
691
 
704
        loopz   .rsloop
692
        loopz   .rsloop
705
 
693
 
706
        DEBUGF 1,"Waiting for nic to boot..\n"
694
        DEBUGF 1,"Waiting for NIC to boot..\n"
707
; wait for 2 seconds for NIC to boot
695
; wait for 2 seconds for NIC to boot
708
        mov     esi, 2000               ; WTF? FIXME
696
        mov     esi, 2000               ; WTF? FIXME
709
        invoke  Sleep ; 2 seconds
697
        invoke  Sleep ; 2 seconds
710
 
698
 
711
        DEBUGF 1,"Ok!\n"
699
        DEBUGF 1,"Ok!\n"
712
 
700
 
713
 
701
 
714
;--------------------------
702
;--------------------------
715
;
703
;
716
; RESET
704
; RESET
717
;
705
;
718
;--------------------------
706
;--------------------------
719
 
707
 
720
reset:
708
reset:
721
 
709
 
722
        movzx   eax, [ebx + device.irq_line]
710
        movzx   eax, [ebx + device.irq_line]
723
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
711
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
724
 
712
 
725
        movzx   ecx, [ebx + device.ver_id]
713
        movzx   ecx, [ebx + device.ver_id]
726
        test    word [hw_versions+2+ecx*4], IS_VORTEX
714
        test    word [hw_versions+2+ecx*4], IS_VORTEX
727
        jz      .not_vortex
715
        jz      .not_vortex
728
        mov     esi, int_vortex
716
        mov     esi, int_vortex
729
        jmp     .reg_int
717
        jmp     .reg_int
730
  .not_vortex:
718
  .not_vortex:
731
        mov     esi, int_boomerang
719
        mov     esi, int_boomerang
732
  .reg_int:
720
  .reg_int:
733
        invoke  AttachIntHandler, eax, esi, ebx
721
        invoke  AttachIntHandler, eax, esi, ebx
734
        test    eax, eax
722
        test    eax, eax
735
        jnz     @f
723
        jnz     @f
736
        DEBUGF  2,"Could not attach int handler!\n"
724
        DEBUGF  2,"Could not attach int handler!\n"
737
        or      eax, -1
725
        or      eax, -1
738
        ret
726
        ret
739
  @@:
727
  @@:
740
 
728
 
741
        set_io  [ebx + device.io_addr], 0
729
        set_io  [ebx + device.io_addr], 0
742
        set_io  [ebx + device.io_addr], REG_COMMAND
730
        set_io  [ebx + device.io_addr], REG_COMMAND
743
        mov     ax, SELECT_REGISTER_WINDOW + 0
731
        mov     ax, SELECT_REGISTER_WINDOW + 0
744
        out     dx, ax
732
        out     dx, ax
745
 
733
 
746
        mov     ax, StopCoax
734
        mov     ax, StopCoax
747
        out     dx, ax                        ; stop transceiver
735
        out     dx, ax                        ; stop transceiver
748
 
736
 
749
        mov     ax, SELECT_REGISTER_WINDOW + 4
737
        mov     ax, SELECT_REGISTER_WINDOW + 4
750
        out     dx, ax                        ; disable UTP
738
        out     dx, ax                        ; disable UTP
751
 
739
 
752
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
740
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
753
        mov     ax, 0x0
741
        mov     ax, 0x0
754
 
742
 
755
        set_io  [ebx + device.io_addr], REG_COMMAND
743
        set_io  [ebx + device.io_addr], REG_COMMAND
756
        mov     ax, SELECT_REGISTER_WINDOW + 0
744
        mov     ax, SELECT_REGISTER_WINDOW + 0
757
        out     dx, ax
745
        out     dx, ax
758
 
746
 
759
        set_io  [ebx + device.io_addr], REG_FIFO_DIAGNOSTIC
747
        set_io  [ebx + device.io_addr], REG_FIFO_DIAGNOSTIC
760
        mov     ax, 0
748
        mov     ax, 0
761
        out     dx, ax                        ; disable card
749
        out     dx, ax                        ; disable card
762
 
750
 
763
        mov     ax, 1
751
        mov     ax, 1
764
        out     dx, ax                        ; enable card
752
        out     dx, ax                        ; enable card
765
 
753
 
766
        call    write_mac
754
        call    write_mac
767
 
755
 
768
        set_io  [ebx + device.io_addr], 0
756
        set_io  [ebx + device.io_addr], 0
769
        set_io  [ebx + device.io_addr], REG_COMMAND
757
        set_io  [ebx + device.io_addr], REG_COMMAND
770
        mov     ax, SELECT_REGISTER_WINDOW + 1
758
        mov     ax, SELECT_REGISTER_WINDOW + 1
771
        out     dx, ax
759
        out     dx, ax
772
 
760
 
773
        mov     ecx, 32
761
        mov     ecx, 32
774
        set_io  [ebx + device.io_addr], 0x0b
762
        set_io  [ebx + device.io_addr], 0x0b
775
  .loop:
763
  .loop:
776
        in      al, dx
764
        in      al, dx
777
        loop    .loop
765
        loop    .loop
778
 
766
 
779
; Get rid of stray ints
767
; Get rid of stray ints
780
        set_io  [ebx + device.io_addr], REG_COMMAND
768
        set_io  [ebx + device.io_addr], REG_COMMAND
781
        mov     ax, AckIntr + 0xff
769
        mov     ax, AckIntr + 0xff
782
        out     dx, ax
770
        out     dx, ax
783
 
771
 
784
        mov     ax, SetStatusEnb + S_5_INTS
772
        mov     ax, SetStatusEnb + S_5_INTS
785
        out     dx, ax
773
        out     dx, ax
786
 
774
 
787
        mov     ax, SetIntrEnb + S_5_INTS
775
        mov     ax, SetIntrEnb + S_5_INTS
788
        out     dx, ax
776
        out     dx, ax
789
 
777
 
790
        DEBUGF  1,"Setting RX mode\n"
778
        DEBUGF  1,"Setting RX mode\n"
791
 
779
 
792
        set_io  [ebx + device.io_addr], 0
780
        set_io  [ebx + device.io_addr], 0
793
        set_io  [ebx + device.io_addr], REG_COMMAND
781
        set_io  [ebx + device.io_addr], REG_COMMAND
794
 
782
 
795
if      defined PROMISCIOUS
783
if      defined PROMISCIOUS
796
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast + RxProm
784
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast + RxProm
797
else if  defined ALLMULTI
785
else if  defined ALLMULTI
798
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast
786
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast
799
else
787
else
800
        mov     ax, SetRxFilter + RxStation + RxBroadcast
788
        mov     ax, SetRxFilter + RxStation + RxBroadcast
801
end if
789
end if
802
        out     dx, ax
790
        out     dx, ax
803
 
791
 
804
        call    set_active_port
792
        call    set_active_port
805
 
793
 
806
        call    create_rx_ring
794
        call    create_rx_ring
807
        test    eax, eax
795
        test    eax, eax
808
        jnz     .err
796
        jnz     .err
809
 
797
 
810
        call    rx_reset
798
        call    rx_reset
811
        call    tx_reset
799
        call    tx_reset
812
 
800
 
813
        xor     eax, eax
801
        xor     eax, eax
814
; clear packet/byte counters
802
; clear packet/byte counters
815
 
803
 
816
        lea     edi, [ebx + device.bytes_tx]
804
        lea     edi, [ebx + device.bytes_tx]
817
        mov     ecx, 6
805
        mov     ecx, 6
818
        rep     stosd
806
        rep     stosd
819
 
807
 
820
        xor     eax, eax
808
        xor     eax, eax
821
        ret
809
        ret
822
 
810
 
823
  .err:
811
  .err:
824
        DEBUGF  2,"reset failed\n"
812
        DEBUGF  2,"reset failed\n"
825
        or      eax, -1
813
        or      eax, -1
826
        ret
814
        ret
827
 
815
 
828
 
816
 
829
align 4
817
align 4
830
start_device:
818
start_device:
831
        DEBUGF  1,"Starting the device\n"
819
        DEBUGF  1,"Starting the device\n"
832
 
820
 
833
        set_io  [ebx + device.io_addr], 0
821
        set_io  [ebx + device.io_addr], 0
834
        set_io  [ebx + device.io_addr], REG_COMMAND
822
        set_io  [ebx + device.io_addr], REG_COMMAND
835
        mov     ax, SetTxThreshold + 60 ;2047 ; recommended by the manual :)
823
        mov     ax, SetTxThreshold + 60 ;2047 ; recommended by the manual :)
836
        out     dx, ax
824
        out     dx, ax
837
 
825
 
838
        call    check_tx_status
826
        call    check_tx_status
839
 
827
 
840
        set_io  [ebx + device.io_addr], 0
828
        set_io  [ebx + device.io_addr], 0
841
        set_io  [ebx + device.io_addr], REG_COMMAND
829
        set_io  [ebx + device.io_addr], REG_COMMAND
842
; switch to register window 4
830
; switch to register window 4
843
        mov     ax, SELECT_REGISTER_WINDOW+4
831
        mov     ax, SELECT_REGISTER_WINDOW+4
844
        out     dx, ax
832
        out     dx, ax
845
 
833
 
846
; wait for linkDetect
834
; wait for linkDetect
847
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
835
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
848
        mov     ecx, 20         ; wait for max 2s
836
        mov     ecx, 20         ; wait for max 2s
849
  .link_detect_loop:
837
  .link_detect_loop:
850
        mov     esi, 100
838
        mov     esi, 100
851
        invoke  Sleep           ; 100 ms
839
        invoke  Sleep           ; 100 ms
852
        in      ax, dx
840
        in      ax, dx
853
        test    ah, 1000b       ; linkDetect
841
        test    ah, 1000b       ; linkDetect
854
        jnz     @f
842
        jnz     @f
855
        loop    .link_detect_loop
843
        loop    .link_detect_loop
856
        DEBUGF  2,"Link detect timed-out!\n"
844
        DEBUGF  2,"Link detect timed-out!\n"
857
       @@:
845
       @@:
858
 
846
 
859
; print link type
847
; print link type
860
        xor     eax, eax
848
        xor     eax, eax
861
        bsr     ax, word[ebx + device.internal_link]
849
        bsr     ax, word[ebx + device.internal_link]
862
        jz      @f
850
        jz      @f
863
        sub     ax, 5
851
        sub     ax, 5
864
       @@:
852
       @@:
865
 
853
 
866
        mov     esi, [link_str+eax*4]
854
        mov     esi, [link_str+eax*4]
867
        DEBUGF  1,"Established Link type: %s\n", esi
855
        DEBUGF  1,"Established Link type: %s\n", esi
868
 
856
 
869
; enable interrupts
857
; enable interrupts
870
        set_io  [ebx + device.io_addr], REG_COMMAND
858
        set_io  [ebx + device.io_addr], REG_COMMAND
871
        mov     ax, SELECT_REGISTER_WINDOW + 1
859
        mov     ax, SELECT_REGISTER_WINDOW + 1
872
        out     dx, ax
860
        out     dx, ax
873
 
861
 
874
        mov     ax, AckIntr + 0xff
862
        mov     ax, AckIntr + 0xff
875
        out     dx, ax
863
        out     dx, ax
876
 
864
 
877
        mov     ax, SetStatusEnb + S_5_INTS
865
        mov     ax, SetStatusEnb + S_5_INTS
878
        out     dx, ax
866
        out     dx, ax
879
 
867
 
880
        mov     ax, SetIntrEnb + S_5_INTS
868
        mov     ax, SetIntrEnb + S_5_INTS
881
        out     dx, ax
869
        out     dx, ax
882
 
870
 
883
; Start RX/TX
871
; Start RX/TX
884
 
872
 
885
        set_io  [ebx + device.io_addr], 0
873
        set_io  [ebx + device.io_addr], 0
886
        set_io  [ebx + device.io_addr], REG_COMMAND
874
        set_io  [ebx + device.io_addr], REG_COMMAND
887
        mov     ax, RxEnable
875
        mov     ax, RxEnable
888
        out     dx, ax
876
        out     dx, ax
889
 
877
 
890
        mov     ax, TxEnable
878
        mov     ax, TxEnable
891
        out     dx, ax
879
        out     dx, ax
892
 
880
 
893
        set_io  [ebx + device.io_addr], REG_COMMAND
881
        set_io  [ebx + device.io_addr], REG_COMMAND
894
        mov     ax, SetRxThreshold + 208
882
        mov     ax, SetRxThreshold + 208
895
        out     dx, ax
883
        out     dx, ax
896
 
884
 
897
        mov     ax, SetTxThreshold + 60 ;16 ; recommended by the manual :)
885
        mov     ax, SetTxThreshold + 60 ;16 ; recommended by the manual :)
898
        out     dx, ax
886
        out     dx, ax
899
 
887
 
900
        mov     ax, SELECT_REGISTER_WINDOW + 1
888
        mov     ax, SELECT_REGISTER_WINDOW + 1
901
        out     dx, ax
889
        out     dx, ax
902
 
890
 
903
; Set the mtu, kernel will be able to send now
891
; Set the mtu, kernel will be able to send now
904
        mov     [ebx + device.mtu], 1514
892
        mov     [ebx + device.mtu], 1514
905
 
893
 
906
; Set link state to unknown
894
; Set link state to unknown
907
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
895
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
908
        xor     eax, eax
896
        xor     eax, eax
909
 
897
 
910
        ret
898
        ret
911
 
899
 
912
 
900
 
913
 
901
 
914
;***************************************************************************
902
;***************************************************************************
915
;   Function
903
;   Function
916
;      tx_reset
904
;      tx_reset
917
;   Description
905
;   Description
918
;      resets and enables transmitter engine
906
;      resets and enables transmitter engine
919
;
907
;
920
;***************************************************************************
908
;***************************************************************************
921
 
909
 
922
align 4
910
align 4
923
tx_reset:
911
tx_reset:
924
        DEBUGF 1,"tx reset\n"
912
        DEBUGF 1,"tx reset\n"
925
 
913
 
926
; TxReset
914
; TxReset
927
        set_io  [ebx + device.io_addr], 0
915
        set_io  [ebx + device.io_addr], 0
928
        set_io  [ebx + device.io_addr], REG_COMMAND
916
        set_io  [ebx + device.io_addr], REG_COMMAND
929
        mov     ax, TxReset
917
        mov     ax, TxReset
930
        out     dx, ax
918
        out     dx, ax
931
; Wait for TxReset to complete
919
; Wait for TxReset to complete
932
        mov     ecx, 200000
920
        mov     ecx, 200000
933
  .tx_reset_loop:
921
  .tx_reset_loop:
934
        in      ax, dx
922
        in      ax, dx
935
        test    ah, 10000b ; check CmdInProgress
923
        test    ah, 10000b ; check CmdInProgress
936
        jz      .tx_set_prev
924
        jz      .tx_set_prev
937
        dec     ecx
925
        dec     ecx
938
        jnz     .tx_reset_loop
926
        jnz     .tx_reset_loop
939
  .tx_set_prev:
927
  .tx_set_prev:
940
; init last TX descriptor
928
; init last TX descriptor
941
        lea     eax, [ebx + device.tx_desc_buffer + (NUM_TX_DESC-1)*sizeof.tx_desc]
929
        lea     eax, [ebx + device.tx_desc_buffer + (NUM_TX_DESC-1)*sizeof.tx_desc]
942
        mov     [ebx + device.curr_tx], eax
930
        mov     [ebx + device.curr_tx], eax
943
 
931
 
944
  .tx_enable:
932
  .tx_enable:
945
        ret
933
        ret
946
 
934
 
947
 
935
 
948
 
936
 
949
;***************************************************************************
937
;***************************************************************************
950
;   Function
938
;   Function
951
;      rx_reset
939
;      rx_reset
952
;   Description
940
;   Description
953
;      resets and enables receiver engine
941
;      resets and enables receiver engine
954
;
942
;
955
;***************************************************************************
943
;***************************************************************************
956
 
944
 
957
align 4
945
align 4
958
rx_reset:
946
rx_reset:
959
 
947
 
960
        DEBUGF 1,"rx reset\n"
948
        DEBUGF 1,"rx reset\n"
961
 
949
 
962
        set_io  [ebx + device.io_addr], 0
950
        set_io  [ebx + device.io_addr], 0
963
        set_io  [ebx + device.io_addr], REG_COMMAND
951
        set_io  [ebx + device.io_addr], REG_COMMAND
964
        mov     ax, RxReset or 0x4
952
        mov     ax, RxReset or 0x4
965
        out     dx, ax
953
        out     dx, ax
966
 
954
 
967
; wait for RxReset to complete
955
; wait for RxReset to complete
968
        mov     ecx, 200000
956
        mov     ecx, 200000
969
  .loop:
957
  .loop:
970
        in      ax, dx
958
        in      ax, dx
971
        test    ah, 10000b ; check CmdInProgress
959
        test    ah, 10000b ; check CmdInProgress
972
        jz      .done
960
        jz      .done
973
        dec     ecx
961
        dec     ecx
974
        jnz     .loop
962
        jnz     .loop
975
  .done:
963
  .done:
976
 
964
 
977
        lea     eax, [ebx + device.rx_desc_buffer]
965
        lea     eax, [ebx + device.rx_desc_buffer]
978
        mov     [ebx + device.curr_rx], eax
966
        mov     [ebx + device.curr_rx], eax
979
        invoke  GetPhysAddr
967
        invoke  GetPhysAddr
980
        set_io  [ebx + device.io_addr], 0
968
        set_io  [ebx + device.io_addr], 0
981
        set_io  [ebx + device.io_addr], REG_UP_LIST_PTR
969
        set_io  [ebx + device.io_addr], REG_UP_LIST_PTR
982
        out     dx, eax
970
        out     dx, eax
983
 
971
 
984
  .rx_enable:
972
  .rx_enable:
985
        ret
973
        ret
986
 
974
 
987
 
975
 
988
 
976
 
989
align 4
977
align 4
990
create_rx_ring:
978
create_rx_ring:
991
; create rx descriptor ring
979
; create rx descriptor ring
992
        lea     eax, [ebx + device.rx_desc_buffer]
980
        lea     eax, [ebx + device.rx_desc_buffer]
993
        invoke  GetPhysAddr
981
        invoke  GetPhysAddr
994
        mov     edi, eax                                                ; real addr of first descr
982
        mov     edi, eax                                                ; real addr of first descr
995
 
983
 
996
        lea     esi, [ebx + device.rx_desc_buffer]                          ; ptr to first descr
984
        lea     esi, [ebx + device.rx_desc_buffer]                          ; ptr to first descr
997
        lea     edx, [ebx + device.rx_desc_buffer + (NUM_RX_DESC-1)*sizeof.rx_desc]     ; ptr to last descr
985
        lea     edx, [ebx + device.rx_desc_buffer + (NUM_RX_DESC-1)*sizeof.rx_desc]     ; ptr to last descr
998
 
986
 
999
        mov     ecx, NUM_RX_DESC
987
        mov     ecx, NUM_RX_DESC
1000
  .loop:
988
  .loop:
1001
        mov     [edx + rx_desc.next_ptr], edi
989
        mov     [edx + rx_desc.next_ptr], edi
1002
 
990
 
1003
        push    ecx edx
991
        push    ecx edx
1004
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE+NET_BUFF.data
992
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE+NET_BUFF.data
1005
        pop     edx ecx
993
        pop     edx ecx
1006
        test    eax, eax
994
        test    eax, eax
1007
        jz      .out_of_mem
995
        jz      .out_of_mem
1008
        mov     [esi + rx_desc.realaddr], eax
996
        mov     [esi + rx_desc.realaddr], eax
1009
        invoke  GetPhysAddr
997
        invoke  GetPhysAddr
1010
        add     eax, NET_BUFF.data
998
        add     eax, NET_BUFF.data
1011
        mov     [esi + rx_desc.frag_addr], eax
999
        mov     [esi + rx_desc.frag_addr], eax
1012
        and     [esi + rx_desc.pkt_status], 0
1000
        and     [esi + rx_desc.pkt_status], 0
1013
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
1001
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
1014
 
1002
 
1015
        DEBUGF  1,"rx_desc: lin=%x phys=%x len=%x next ptr=%x\n", [esi+rx_desc.realaddr]:8, [esi+rx_desc.frag_addr]:8, [esi+rx_desc.frag_len]:8, edi
1003
        DEBUGF  1,"rx_desc: lin=%x phys=%x len=%x next ptr=%x\n", [esi+rx_desc.realaddr]:8, [esi+rx_desc.frag_addr]:8, [esi+rx_desc.frag_len]:8, edi
1016
        DEBUGF  1,"rx_desc: cur=%x prev=%x\n", esi, edx
1004
        DEBUGF  1,"rx_desc: cur=%x prev=%x\n", esi, edx
1017
 
1005
 
1018
        mov     edx, esi
1006
        mov     edx, esi
1019
        add     esi, sizeof.rx_desc
1007
        add     esi, sizeof.rx_desc
1020
        add     edi, sizeof.rx_desc
1008
        add     edi, sizeof.rx_desc
1021
        dec     ecx
1009
        dec     ecx
1022
        jnz     .loop
1010
        jnz     .loop
1023
 
1011
 
1024
        xor     eax, eax
1012
        xor     eax, eax
1025
        ret
1013
        ret
1026
 
1014
 
1027
  .out_of_mem:
1015
  .out_of_mem:
1028
        or      eax, -1
1016
        or      eax, -1
1029
        ret
1017
        ret
1030
 
1018
 
1031
 
1019
 
1032
 
1020
 
1033
;---------------------------------------------------------------------------
1021
;---------------------------------------------------------------------------
1034
;   Function
1022
;   Function
1035
;      try_link_detect
1023
;      try_link_detect
1036
;   Description
1024
;   Description
1037
;      try_link_detect checks if link exists
1025
;      try_link_detect checks if link exists
1038
;   Parameters
1026
;   Parameters
1039
;      ebx = device structure
1027
;      ebx = device structure
1040
;   Return value
1028
;   Return value
1041
;      al - 0 ; no link detected
1029
;      al - 0 ; no link detected
1042
;      al - 1 ; link detected
1030
;      al - 1 ; link detected
1043
;   Destroyed registers
1031
;   Destroyed registers
1044
;      eax, ebx, ecx, edx, edi, esi
1032
;      eax, ebx, ecx, edx, edi, esi
1045
;
1033
;
1046
;---------------------------------------------------------------------------
1034
;---------------------------------------------------------------------------
1047
 
1035
 
1048
align 4
1036
align 4
1049
try_link_detect:
1037
try_link_detect:
1050
 
1038
 
1051
        DEBUGF  1,"Trying to detect link\n"
1039
        DEBUGF  1,"Trying to detect link\n"
1052
 
1040
 
1053
; create self-directed packet
1041
; create self-directed packet
1054
        invoke  NetAlloc, 20+NET_BUFF.data     ; create a buffer for the self-directed packet
1042
        invoke  NetAlloc, 20+NET_BUFF.data     ; create a buffer for the self-directed packet
1055
        test    eax, eax
1043
        test    eax, eax
1056
        jz      .fail
1044
        jz      .fail
1057
 
1045
 
1058
        push    eax
1046
        push    eax
1059
        mov     [eax + NET_BUFF.length], 20
1047
        mov     [eax + NET_BUFF.length], 20
1060
 
1048
 
1061
        lea     edi, [eax + NET_BUFF.data]
1049
        lea     edi, [eax + NET_BUFF.data]
1062
        lea     esi, [ebx + device.mac]
1050
        lea     esi, [ebx + device.mac]
1063
        movsw
1051
        movsw
1064
        movsd
1052
        movsd
1065
        sub     esi, 6
1053
        sub     esi, 6
1066
        movsw
1054
        movsw
1067
        movsd
1055
        movsd
1068
        mov     ax , 0x0608
1056
        mov     ax , 0x0608
1069
        stosw
1057
        stosw
1070
 
1058
 
1071
; download self-directed packet
1059
; download self-directed packet
1072
        call    [ebx + device.transmit]
1060
        call    [ebx + device.transmit]
1073
 
1061
 
1074
; switch to register window 4
1062
; switch to register window 4
1075
        set_io  [ebx + device.io_addr], 0
1063
        set_io  [ebx + device.io_addr], 0
1076
        set_io  [ebx + device.io_addr], REG_COMMAND
1064
        set_io  [ebx + device.io_addr], REG_COMMAND
1077
        mov     ax, SELECT_REGISTER_WINDOW+4
1065
        mov     ax, SELECT_REGISTER_WINDOW+4
1078
        out     dx, ax
1066
        out     dx, ax
1079
 
1067
 
1080
; See if we have received the packet by now..
1068
; See if we have received the packet by now..
1081
        cmp     [ebx + device.packets_rx], 0
1069
        cmp     [ebx + device.packets_rx], 0
1082
        jnz     .link_detected
1070
        jnz     .link_detected
1083
 
1071
 
1084
; switch to register window 4
1072
; switch to register window 4
1085
        set_io  [ebx + device.io_addr], REG_COMMAND
1073
        set_io  [ebx + device.io_addr], REG_COMMAND
1086
        mov     ax, SELECT_REGISTER_WINDOW+4
1074
        mov     ax, SELECT_REGISTER_WINDOW+4
1087
        out     dx, ax
1075
        out     dx, ax
1088
 
1076
 
1089
; read linkbeatdetect
1077
; read linkbeatdetect
1090
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
1078
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
1091
        in      ax, dx
1079
        in      ax, dx
1092
        test    ah, 1000b ; test linkBeatDetect
1080
        test    ah, 1000b ; test linkBeatDetect
1093
        jnz     .link_detected
1081
        jnz     .link_detected
1094
        xor     al, al
1082
        xor     al, al
1095
        jmp     .finish
1083
        jmp     .finish
1096
 
1084
 
1097
  .link_detected:
1085
  .link_detected:
1098
        DEBUGF  1,"Link detected!\n"
1086
        DEBUGF  1,"Link detected!\n"
1099
        setb    al
1087
        setb    al
1100
 
1088
 
1101
  .finish:
1089
  .finish:
1102
        test    al, al
1090
        test    al, al
1103
        jz      @f
1091
        jz      @f
1104
        or      byte [ebx + device.internal_link+1], 100b
1092
        or      byte [ebx + device.internal_link+1], 100b
1105
       @@:
1093
       @@:
1106
        xor     eax, eax
1094
        xor     eax, eax
1107
        ret
1095
        ret
1108
 
1096
 
1109
  .fail:
1097
  .fail:
1110
        DEBUGF  1,"No link detected!\n"
1098
        DEBUGF  1,"No link detected!\n"
1111
        or      eax, -1
1099
        or      eax, -1
1112
        ret
1100
        ret
1113
 
1101
 
1114
 
1102
 
1115
 
1103
 
1116
;***************************************************************************
1104
;***************************************************************************
1117
;   Function
1105
;   Function
1118
;      try_phy
1106
;      try_phy
1119
;   Description
1107
;   Description
1120
;      try_phy checks the auto-negotiation function
1108
;      try_phy checks the auto-negotiation function
1121
;      in the PHY at PHY index. It can also be extended to
1109
;      in the PHY at PHY index. It can also be extended to
1122
;      include link detection for non-IEEE 802.3u
1110
;      include link detection for non-IEEE 802.3u
1123
;      auto-negotiation devices, for instance the BCM5000.              ; TODO: BCM5000
1111
;      auto-negotiation devices, for instance the BCM5000.              ; TODO: BCM5000
1124
;   Parameters
1112
;   Parameters
1125
;       ah - PHY index
1113
;       ah - PHY index
1126
;       ebx - device stucture
1114
;       ebx - device stucture
1127
;   Return value
1115
;   Return value
1128
;      al - 0 link is auto-negotiated
1116
;      al - 0 link is auto-negotiated
1129
;      al - 1 no link is auto-negotiated
1117
;      al - 1 no link is auto-negotiated
1130
;   Destroyed registers
1118
;   Destroyed registers
1131
;       eax, ebx, ecx, edx, esi
1119
;       eax, ebx, ecx, edx, esi
1132
;
1120
;
1133
;***************************************************************************
1121
;***************************************************************************
1134
 
1122
 
1135
align 4
1123
align 4
1136
try_phy:
1124
try_phy:
1137
 
1125
 
1138
        DEBUGF 1,"PHY=%u\n", ah
1126
        DEBUGF 1,"PHY=%u\n", ah
1139
        DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
1127
        DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
1140
 
1128
 
1141
        mov     al, MII_BMCR
1129
        mov     al, MII_BMCR
1142
        push    eax
1130
        push    eax
1143
        call    mdio_read       ; returns with window #4
1131
        call    mdio_read
1144
        or      ah, 0x80        ; software reset
1132
        or      ax, BMCR_RESET
1145
        mov     esi, eax
1133
        mov     esi, eax
1146
        mov     eax, [esp]
1134
        mov     eax, [esp]
1147
        call    mdio_write      ; returns with window #4
1135
        call    mdio_write
1148
 
1136
 
1149
; wait for reset to complete
1137
; wait for reset to complete
1150
        mov     esi, 2000
1138
        mov     esi, 2000
1151
        invoke  Sleep           ; 2s FIXME
1139
        invoke  Sleep           ; 2s FIXME
-
 
1140
 
1152
        mov     eax, [esp]
1141
        mov     eax, [esp]
-
 
1142
        mov     al, MII_BMCR
1153
        call    mdio_read       ; returns with window #4
1143
        call    mdio_read
1154
        test    ah, 0x80
1144
        test    ax, BMCR_RESET
1155
        jnz     .fail1
1145
        jnz     .fail1
1156
        mov     eax, [esp]
-
 
1157
 
1146
 
1158
; wait for a while after reset
1147
; wait for a while after reset
1159
        mov     esi, 20
1148
        mov     esi, 20
1160
        invoke  Sleep           ; 20ms
1149
        invoke  Sleep           ; 20ms
-
 
1150
 
1161
        mov     eax, [esp]
1151
        mov     eax, [esp]
1162
        mov     al , MII_BMSR
1152
        mov     al, MII_BMSR
1163
        call    mdio_read        ; returns with window #4
1153
        call    mdio_read
1164
        test    al, 1            ; extended capability supported?
1154
        test    al, BMSR_ERCAP
1165
        jz      .fail2
1155
        jz      .fail2
1166
        DEBUGF  1,"Extended capability supported\n"
1156
        DEBUGF  1,"Extended capability supported\n"
1167
 
-
 
1168
; auto-neg capable?
-
 
1169
        test    al , 1000b
1157
        test    al, BMSR_ANEGCAPABLE
1170
        jz      .fail2           ; not auto-negotiation capable
1158
        jz      .fail2
1171
        DEBUGF  1,"Auto-negotiation capable\n"
1159
        DEBUGF  1,"Auto-negotiation capable\n"
1172
 
-
 
1173
; auto-neg complete?
-
 
1174
        test    al , 100000b
1160
        test    al, BMSR_ANEGCOMPLETE
1175
        jnz     .auto_neg_ok
1161
        jnz     .auto_neg_ok
1176
        DEBUGF  1,"Restarting auto-negotiation\n"
1162
        DEBUGF  1,"Restarting auto-negotiation\n"
1177
 
1163
 
1178
; restart auto-negotiation
1164
; restart auto-negotiation
1179
        mov     eax, [esp]
1165
        mov     eax, [esp]
1180
        mov     al, MII_ADVERTISE
1166
        mov     al, MII_ADVERTISE
1181
        push    eax
1167
        push    eax
1182
        call    mdio_read       ; returns with window #4
1168
        call    mdio_read       ; returns with window #4
1183
        or      ax , 1111b shl 5; advertise only 10base-T and 100base-TX
1169
        or      ax, ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL
1184
        mov     esi, eax
1170
        mov     esi, eax
1185
        pop     eax
1171
        pop     eax
1186
        call    mdio_write      ; returns with window #4
1172
        call    mdio_write      ; returns with window #4
1187
        mov     eax, [esp]
1173
        mov     eax, [esp]
1188
        call    mdio_read       ; returns with window #4
1174
        call    mdio_read       ; returns with window #4
1189
        mov     esi, eax
1175
        mov     esi, eax
1190
        or      bh , 10010b     ; restart auto-negotiation
1176
        or      bx, BMCR_ANENABLE or BMCR_ANRESTART
1191
        mov     eax, [esp]
1177
        mov     eax, [esp]
1192
        call    mdio_write      ; returns with window #4
1178
        call    mdio_write      ; returns with window #4
1193
        mov     esi, 4000
1179
        mov     esi, 4000
1194
        invoke  Sleep  ; 4 seconds
1180
        invoke  Sleep  ; 4 seconds
1195
        mov     eax, [esp]
1181
        mov     eax, [esp]
-
 
1182
 
1196
        mov     al , MII_BMSR
1183
        mov     al, MII_BMSR
1197
        call    mdio_read ; returns with window #4
1184
        call    mdio_read ; returns with window #4
1198
        test    al , 100000b ; auto-neg complete?
1185
        test    al, BMSR_ANEGCOMPLETE
1199
        jnz     .auto_neg_ok
1186
        jnz     .auto_neg_ok
-
 
1187
 
1200
        jmp     .fail3
1188
        jmp     .fail3
1201
  .auto_neg_ok:
1189
  .auto_neg_ok:
1202
        DEBUGF  1,"Auto-negotiation complete\n"
1190
        DEBUGF  1,"Auto-negotiation complete\n"
1203
 
1191
 
1204
; compare advertisement and link partner ability registers
1192
; compare advertisement and link partner ability registers
1205
        mov     eax, [esp]
1193
        mov     eax, [esp]
1206
        mov     al, MII_ADVERTISE
1194
        mov     al, MII_ADVERTISE
1207
        call    mdio_read               ; returns with window #4
1195
        call    mdio_read               ; returns with window #4
1208
        xchg    eax, [esp]
1196
        xchg    eax, [esp]
1209
        mov     al, MII_LPA
1197
        mov     al, MII_LPA
1210
        call    mdio_read               ; returns with window #4
1198
        call    mdio_read               ; returns with window #4
1211
        pop     esi
1199
        pop     esi
1212
        and     eax, esi
1200
        and     eax, esi
1213
        and     eax, 11111100000b       ; Mask off
1201
        and     eax, 11111100000b       ; Mask off
1214
        push    eax
1202
        push    eax
1215
        mov     word[ebx + device.internal_link+2], ax
1203
        mov     word[ebx + device.internal_link+2], ax
1216
 
1204
 
1217
; switch to register window 3
1205
; switch to register window 3
1218
        set_io  [ebx + device.io_addr], 0
1206
        set_io  [ebx + device.io_addr], 0
1219
        set_io  [ebx + device.io_addr], REG_COMMAND
1207
        set_io  [ebx + device.io_addr], REG_COMMAND
1220
        mov     ax, SELECT_REGISTER_WINDOW+3
1208
        mov     ax, SELECT_REGISTER_WINDOW+3
1221
        out     dx, ax
1209
        out     dx, ax
1222
 
1210
 
1223
; set full-duplex mode
1211
; set full-duplex mode
1224
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1212
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1225
        in      ax, dx
1213
        in      ax, dx
1226
        and     ax, not 0x120           ; clear full duplex and flow control
1214
        and     ax, not 0x120           ; clear full duplex and flow control
1227
        pop     esi
1215
        pop     esi
1228
        test    esi, 1010b shl 5        ; check for full-duplex
1216
        test    esi, 1010b shl 5        ; check for full-duplex
1229
        jz      .half_duplex
1217
        jz      .half_duplex
1230
        or      ax, 0x120               ; set full duplex and flow control
1218
        or      ax, 0x120               ; set full duplex and flow control
1231
  .half_duplex:
1219
  .half_duplex:
1232
        DEBUGF 1,"Using half-duplex\n"
1220
        DEBUGF 1,"Using half-duplex\n"
1233
        out     dx, ax
1221
        out     dx, ax
1234
        mov     al, 1
1222
        mov     al, 1
1235
        ret
1223
        ret
1236
 
1224
 
1237
  .fail1:
1225
  .fail1:
1238
        DEBUGF  2,"reset failed!\n"
1226
        DEBUGF  2,"reset failed!\n"
1239
        pop     eax
1227
        pop     eax
1240
        xor     al, al
1228
        xor     al, al
1241
        ret
1229
        ret
1242
 
1230
 
1243
  .fail2:
1231
  .fail2:
1244
        DEBUGF  2,"This device is not auto-negotiation capable!\n"
1232
        DEBUGF  2,"This device is not auto-negotiation capable!\n"
1245
        pop     eax
1233
        pop     eax
1246
        xor     al, al
1234
        xor     al, al
1247
        ret
1235
        ret
1248
 
1236
 
1249
  .fail3:
1237
  .fail3:
1250
        DEBUGF  2,"Auto-negotiation reset failed!\n"
1238
        DEBUGF  2,"Auto-negotiation reset failed!\n"
1251
        pop     eax
1239
        pop     eax
1252
        xor     al, al
1240
        xor     al, al
1253
        ret
1241
        ret
1254
 
1242
 
1255
 
1243
 
1256
 
1244
 
1257
;***************************************************************************
1245
;***************************************************************************
1258
;   Function
1246
;   Function
1259
;      try_mii
1247
;      try_mii
1260
;   Description
1248
;   Description
1261
;      try_MII checks the on-chip auto-negotiation logic
1249
;      try_MII checks the on-chip auto-negotiation logic
1262
;      or an off-chip MII PHY, depending upon what is set in
1250
;      or an off-chip MII PHY, depending upon what is set in
1263
;      xcvrSelect by the caller.
1251
;      xcvrSelect by the caller.
1264
;      It exits when it finds the first device with a good link.
1252
;      It exits when it finds the first device with a good link.
1265
;   Parameters
1253
;   Parameters
1266
;
1254
;
1267
;   Return value
1255
;   Return value
1268
;      al - 0
1256
;      al - 0
1269
;      al - 1
1257
;      al - 1
1270
;   Destroyed registers
1258
;   Destroyed registers
1271
;      eax, ebx, ecx, edx, esi
1259
;      eax, ebx, ecx, edx, esi
1272
;
1260
;
1273
;***************************************************************************
1261
;***************************************************************************
1274
 
1262
 
1275
align 4
1263
align 4
1276
try_mii:
1264
try_mii:
1277
 
1265
 
1278
        DEBUGF  1,"Trying to find MII PHY\n"
1266
        DEBUGF  1,"Trying to find MII PHY\n"
1279
 
1267
 
1280
; switch to register window 3
1268
; switch to register window 3
1281
        set_io  [ebx + device.io_addr], 0
1269
        set_io  [ebx + device.io_addr], 0
1282
        set_io  [ebx + device.io_addr], REG_COMMAND
1270
        set_io  [ebx + device.io_addr], REG_COMMAND
1283
        mov     ax, SELECT_REGISTER_WINDOW+3
1271
        mov     ax, SELECT_REGISTER_WINDOW+3
1284
        out     dx, ax
1272
        out     dx, ax
1285
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1273
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1286
        in      eax, dx
1274
        in      eax, dx
1287
        and     eax, (1111b shl 20)
1275
        and     eax, (1111b shl 20)
1288
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
1276
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
1289
        jne     .mii_device
1277
        jne     .mii_device
1290
 
1278
 
1291
        DEBUGF  1,"Auto-negotiation is set\n"
1279
        DEBUGF  1,"Auto-negotiation is set\n"
1292
; switch to register window 4
1280
; switch to register window 4
1293
        set_io  [ebx + device.io_addr], REG_COMMAND
1281
        set_io  [ebx + device.io_addr], REG_COMMAND
1294
        mov     ax, SELECT_REGISTER_WINDOW+4
1282
        mov     ax, SELECT_REGISTER_WINDOW+4
1295
        out     dx, ax
1283
        out     dx, ax
1296
 
1284
 
1297
; PHY==24 is the on-chip auto-negotiation logic
1285
; PHY==24 is the on-chip auto-negotiation logic
1298
; it supports only 10base-T and 100base-TX
1286
; it supports only 10base-T and 100base-TX
1299
        mov     ah, 24
1287
        mov     ah, 24
1300
        call    try_phy
1288
        call    try_phy
1301
        test    al, al
1289
        test    al, al
1302
        jz      .fail
1290
        jz      .fail
1303
 
1291
 
1304
        mov     cl, 24
1292
        mov     cl, 24
1305
        jmp     .check_preamble
1293
        jmp     .check_preamble
1306
 
1294
 
1307
  .mii_device:
1295
  .mii_device:
1308
        cmp     eax, (0110b shl 20)
1296
        cmp     eax, (0110b shl 20)
1309
        jne     .fail
1297
        jne     .fail
1310
 
1298
 
1311
        set_io  [ebx + device.io_addr], 0
1299
        set_io  [ebx + device.io_addr], 0
1312
        set_io  [ebx + device.io_addr], REG_COMMAND
1300
        set_io  [ebx + device.io_addr], REG_COMMAND
1313
        mov     ax , SELECT_REGISTER_WINDOW+4
1301
        mov     ax , SELECT_REGISTER_WINDOW+4
1314
        out     dx , ax
1302
        out     dx , ax
1315
 
1303
 
1316
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1304
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1317
        in      ax , dx
1305
        in      ax , dx
1318
        and     al , (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_DATA)
1306
        and     al , (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_DATA)
1319
        cmp     al , (1 shl BIT_MGMT_DATA)
1307
        cmp     al , (1 shl BIT_MGMT_DATA)
1320
        je      .search_for_phy
1308
        je      .search_for_phy
1321
 
1309
 
1322
        xor     al, al
1310
        xor     al, al
1323
        ret
1311
        ret
1324
 
1312
 
1325
  .search_for_phy:
1313
  .search_for_phy:
1326
; search for PHY
1314
; search for PHY
1327
        mov     cx, 31
1315
        mov     cx, 31
1328
  .search_phy_loop:
1316
  .search_phy_loop:
1329
        DEBUGF  1,"Searching for the PHY\n"
1317
        DEBUGF  1,"Searching for the PHY\n"
1330
        cmp     cx, 24
1318
        cmp     cx, 24
1331
        je      .next_phy
1319
        je      .next_phy
1332
        mov     ah, cl                  ; ah = phy
1320
        mov     ah, cl                  ; ah = phy
1333
        mov     al, MII_BMSR            ; al = Basic Mode Status Register       ; BUGFIX HERE! :):)
1321
        mov     al, MII_BMSR            ; al = Basic Mode Status Register       ; BUGFIX HERE! :):)
1334
        push    cx
1322
        push    cx
1335
        call    mdio_read
1323
        call    mdio_read
1336
        pop     cx
1324
        pop     cx
1337
        test    ax, ax
1325
        test    ax, ax
1338
        jz      .next_phy
1326
        jz      .next_phy
1339
        cmp     ax, 0xffff
1327
        cmp     ax, 0xffff
1340
        je      .next_phy
1328
        je      .next_phy
1341
        mov     ah, cl                  ; ah = phy
1329
        mov     ah, cl                  ; ah = phy
1342
        push    cx
1330
        push    cx
1343
        call    try_phy
1331
        call    try_phy
1344
        pop     cx
1332
        pop     cx
1345
        test    al, al
1333
        test    al, al
1346
        jnz     .check_preamble
1334
        jnz     .check_preamble
1347
  .next_phy:
1335
  .next_phy:
1348
        loopw   .search_phy_loop
1336
        loopw   .search_phy_loop
1349
 
1337
 
1350
  .fail:
1338
  .fail:
1351
        DEBUGF  1,"PHY not found\n"
1339
        DEBUGF  1,"PHY not found\n"
1352
        xor     al, al
1340
        xor     al, al
1353
        ret
1341
        ret
1354
 
1342
 
1355
; epilog
1343
; epilog
1356
  .check_preamble:
1344
  .check_preamble:
1357
        DEBUGF  1,"Using PHY: %u\nChecking PreAmble\n", cl
1345
        DEBUGF  1,"Using PHY: %u\nChecking PreAmble\n", cl
1358
        push    eax ; eax contains the return value of try_phy
1346
        push    eax ; eax contains the return value of try_phy
1359
; check hard coded preamble forcing
1347
; check hard coded preamble forcing
1360
        movzx   eax, [ebx + device.ver_id]
1348
        movzx   eax, [ebx + device.ver_id]
1361
        test    word [eax*4+hw_versions+2], EXTRA_PREAMBLE
1349
        test    word [eax*4+hw_versions+2], EXTRA_PREAMBLE
1362
        setnz   [ebx + device.preamble] ; force preamble
1350
        setnz   [ebx + device.preamble] ; force preamble
1363
        jnz     .finish
1351
        jnz     .finish
1364
 
1352
 
1365
; check mii for preamble suppression
1353
; check mii for preamble suppression
1366
        mov     ah, cl
1354
        mov     ah, cl
1367
        mov     al, MII_BMSR
1355
        mov     al, MII_BMSR
1368
        call    mdio_read
1356
        call    mdio_read
1369
        test    al, 1000000b ; preamble suppression?
1357
        test    al, 1000000b ; preamble suppression?
1370
        setz    [ebx + device.preamble] ; no
1358
        setz    [ebx + device.preamble] ; no
1371
 
1359
 
1372
  .finish:
1360
  .finish:
1373
        pop     eax
1361
        pop     eax
1374
        ret
1362
        ret
1375
 
1363
 
1376
 
1364
 
1377
 
1365
 
1378
;***************************************************************************
1366
;***************************************************************************
1379
;   Function
1367
;   Function
1380
;      test_packet
1368
;      test_packet
1381
;   Description
1369
;   Description
1382
;      try_loopback try a loopback packet for 10BASE2 or AUI port
1370
;      try_loopback try a loopback packet for 10BASE2 or AUI port
1383
;   Parameters
1371
;   Parameters
1384
;      ebx = device structure
1372
;      ebx = device structure
1385
;
1373
;
1386
;***************************************************************************
1374
;***************************************************************************
1387
 
1375
 
1388
align 4
1376
align 4
1389
test_packet:
1377
test_packet:
1390
 
1378
 
1391
        DEBUGF 1,"Sending test packet\n"
1379
        DEBUGF 1,"Sending test packet\n"
1392
 
1380
 
1393
; switch to register window 3
1381
; switch to register window 3
1394
        set_io  [ebx + device.io_addr], 0
1382
        set_io  [ebx + device.io_addr], 0
1395
        set_io  [ebx + device.io_addr], REG_COMMAND
1383
        set_io  [ebx + device.io_addr], REG_COMMAND
1396
        mov     ax, SELECT_REGISTER_WINDOW+3
1384
        mov     ax, SELECT_REGISTER_WINDOW+3
1397
        out     dx, ax
1385
        out     dx, ax
1398
 
1386
 
1399
; set fullDuplexEnable in MacControl register
1387
; set fullDuplexEnable in MacControl register
1400
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1388
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1401
        in      ax, dx
1389
        in      ax, dx
1402
        or      ax, 0x120
1390
        or      ax, 0x120
1403
        out     dx, ax
1391
        out     dx, ax
1404
 
1392
 
1405
; switch to register window 5
1393
; switch to register window 5
1406
        set_io  [ebx + device.io_addr], REG_COMMAND
1394
        set_io  [ebx + device.io_addr], REG_COMMAND
1407
        mov     ax, SELECT_REGISTER_WINDOW+5
1395
        mov     ax, SELECT_REGISTER_WINDOW+5
1408
        out     dx, ax
1396
        out     dx, ax
1409
 
1397
 
1410
; set RxFilter to enable individual address matches
1398
; set RxFilter to enable individual address matches
1411
        mov     ax, (10000b shl 11)
1399
        mov     ax, (10000b shl 11)
1412
        set_io  [ebx + device.io_addr], REG_RX_FILTER
1400
        set_io  [ebx + device.io_addr], REG_RX_FILTER
1413
        in      al, dx
1401
        in      al, dx
1414
        or      al, 1
1402
        or      al, 1
1415
        set_io  [ebx + device.io_addr], REG_COMMAND
1403
        set_io  [ebx + device.io_addr], REG_COMMAND
1416
        out     dx, ax
1404
        out     dx, ax
1417
 
1405
 
1418
; issue RxEnable and TxEnable
1406
; issue RxEnable and TxEnable
1419
        call    rx_reset
1407
        call    rx_reset
1420
        call    tx_reset
1408
        call    tx_reset
1421
 
1409
 
1422
; create self-directed packet
1410
; create self-directed packet
1423
        invoke  NetAlloc, 20 + NET_BUFF.data   ; create a buffer for the self-directed packet
1411
        invoke  NetAlloc, 20 + NET_BUFF.data   ; create a buffer for the self-directed packet
1424
        test    eax, eax
1412
        test    eax, eax
1425
        jz      .fail
1413
        jz      .fail
1426
 
1414
 
1427
        push    eax
1415
        push    eax
1428
        mov     [eax + NET_BUFF.length], 20
1416
        mov     [eax + NET_BUFF.length], 20
1429
;        mov     [eax + NET_BUFF.device], ebx
1417
;        mov     [eax + NET_BUFF.device], ebx
1430
 
1418
 
1431
        lea     edi, [eax + NET_BUFF.data]
1419
        lea     edi, [eax + NET_BUFF.data]
1432
        lea     esi, [ebx + device.mac]
1420
        lea     esi, [ebx + device.mac]
1433
        movsw
1421
        movsw
1434
        movsd
1422
        movsd
1435
        sub     esi, 6
1423
        sub     esi, 6
1436
        movsw
1424
        movsw
1437
        movsd
1425
        movsd
1438
        mov     ax, 0x0608
1426
        mov     ax, 0x0608
1439
        stosw
1427
        stosw
1440
 
1428
 
1441
; download self-directed packet
1429
; download self-directed packet
1442
        call    [ebx + device.transmit]
1430
        call    [ebx + device.transmit]
1443
 
1431
 
1444
; wait for 2s
1432
; wait for 2s
1445
        mov     esi, 2000       ; FIXME
1433
        mov     esi, 2000       ; FIXME
1446
        invoke  Sleep
1434
        invoke  Sleep
1447
 
1435
 
1448
; check if self-directed packet is received
1436
; check if self-directed packet is received
1449
        mov     eax, [ebx + device.packets_rx]
1437
        mov     eax, [ebx + device.packets_rx]
1450
        test    eax, eax
1438
        test    eax, eax
1451
        jnz     .finish
1439
        jnz     .finish
1452
 
1440
 
1453
; switch to register window 3
1441
; switch to register window 3
1454
        set_io  [ebx + device.io_addr], 0
1442
        set_io  [ebx + device.io_addr], 0
1455
        set_io  [ebx + device.io_addr], REG_COMMAND
1443
        set_io  [ebx + device.io_addr], REG_COMMAND
1456
        mov     ax, SELECT_REGISTER_WINDOW+3
1444
        mov     ax, SELECT_REGISTER_WINDOW+3
1457
        out     dx, ax
1445
        out     dx, ax
1458
 
1446
 
1459
; clear fullDuplexEnable in MacControl register
1447
; clear fullDuplexEnable in MacControl register
1460
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1448
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1461
        in      ax, dx
1449
        in      ax, dx
1462
        and     ax, not 0x120
1450
        and     ax, not 0x120
1463
        out     dx, ax
1451
        out     dx, ax
1464
  .fail:
1452
  .fail:
1465
        xor     eax, eax
1453
        xor     eax, eax
1466
 
1454
 
1467
  .finish:
1455
  .finish:
1468
        ret
1456
        ret
1469
 
1457
 
1470
 
1458
 
1471
 
1459
 
1472
;***************************************************************************
1460
;***************************************************************************
1473
;   Function
1461
;   Function
1474
;      try_loopback
1462
;      try_loopback
1475
;   Description
1463
;   Description
1476
;      tries a loopback packet for 10BASE2 or AUI port
1464
;      tries a loopback packet for 10BASE2 or AUI port
1477
;   Parameters
1465
;   Parameters
1478
;      al -  0: 10Mbps AUI connector
1466
;      al -  0: 10Mbps AUI connector
1479
;            1: 10BASE-2
1467
;            1: 10BASE-2
1480
;
1468
;
1481
;   Return value
1469
;   Return value
1482
;      al - 0
1470
;      al - 0
1483
;      al - 1
1471
;      al - 1
1484
;   Destroyed registers
1472
;   Destroyed registers
1485
;      eax, ebx, ecx, edx, edi, esi
1473
;      eax, ebx, ecx, edx, edi, esi
1486
;
1474
;
1487
;***************************************************************************
1475
;***************************************************************************
1488
 
1476
 
1489
align 4
1477
align 4
1490
try_loopback:
1478
try_loopback:
1491
 
1479
 
1492
        DEBUGF 1,"trying loopback\n"
1480
        DEBUGF 1,"trying loopback\n"
1493
 
1481
 
1494
        push    eax
1482
        push    eax
1495
; switch to register window 3
1483
; switch to register window 3
1496
        set_io  [ebx + device.io_addr], 0
1484
        set_io  [ebx + device.io_addr], 0
1497
        set_io  [ebx + device.io_addr], REG_COMMAND
1485
        set_io  [ebx + device.io_addr], REG_COMMAND
1498
        mov     ax, SELECT_REGISTER_WINDOW+3
1486
        mov     ax, SELECT_REGISTER_WINDOW+3
1499
        out     dx, ax
1487
        out     dx, ax
1500
        mov     eax, [esp]
1488
        mov     eax, [esp]
1501
 
1489
 
1502
        mov     cl, al
1490
        mov     cl, al
1503
        inc     cl
1491
        inc     cl
1504
        shl     cl, 3
1492
        shl     cl, 3
1505
        or      byte [ebx + device.internal_link+1], cl
1493
        or      byte [ebx + device.internal_link+1], cl
1506
 
1494
 
1507
        test    al, al ; aui or coax?
1495
        test    al, al ; aui or coax?
1508
        jz      .complete_loopback
1496
        jz      .complete_loopback
1509
; enable 100BASE-2 DC-DC converter
1497
; enable 100BASE-2 DC-DC converter
1510
        mov     ax, (10b shl 11) ; EnableDcConverter
1498
        mov     ax, (10b shl 11) ; EnableDcConverter
1511
        out     dx, ax
1499
        out     dx, ax
1512
  .complete_loopback:
1500
  .complete_loopback:
1513
 
1501
 
1514
        mov     cx, 2 ; give a port 3 chances to complete a loopback
1502
        mov     cx, 2 ; give a port 3 chances to complete a loopback
1515
  .next_try:
1503
  .next_try:
1516
        push    ecx
1504
        push    ecx
1517
        call    test_packet
1505
        call    test_packet
1518
        pop     ecx
1506
        pop     ecx
1519
        test    eax, eax
1507
        test    eax, eax
1520
        loopzw  .next_try
1508
        loopzw  .next_try
1521
 
1509
 
1522
  .finish:
1510
  .finish:
1523
        xchg    eax, [esp]
1511
        xchg    eax, [esp]
1524
        test    al, al
1512
        test    al, al
1525
        jz      .aui_finish
1513
        jz      .aui_finish
1526
 
1514
 
1527
; issue DisableDcConverter command
1515
; issue DisableDcConverter command
1528
        set_io  [ebx + device.io_addr], 0
1516
        set_io  [ebx + device.io_addr], 0
1529
        set_io  [ebx + device.io_addr], REG_COMMAND
1517
        set_io  [ebx + device.io_addr], REG_COMMAND
1530
        mov     ax, (10111b shl 11)
1518
        mov     ax, (10111b shl 11)
1531
        out     dx, ax
1519
        out     dx, ax
1532
  .aui_finish:
1520
  .aui_finish:
1533
        pop     eax ; al contains the result of operation
1521
        pop     eax ; al contains the result of operation
1534
 
1522
 
1535
        test    al, al
1523
        test    al, al
1536
        jnz     @f
1524
        jnz     @f
1537
        and     byte [ebx + device.internal_link+1], not 11000b
1525
        and     byte [ebx + device.internal_link+1], not 11000b
1538
       @@:
1526
       @@:
1539
 
1527
 
1540
        ret
1528
        ret
1541
 
1529
 
1542
 
1530
 
1543
;***************************************************************************
1531
;***************************************************************************
1544
;   Function
1532
;   Function
1545
;      set_active_port
1533
;      set_active_port
1546
;   Description
1534
;   Description
1547
;      It selects the media port (transceiver) to be used
1535
;      It selects the media port (transceiver) to be used
1548
;   Return value:
1536
;   Return value:
1549
;   Destroyed registers
1537
;   Destroyed registers
1550
;      eax, ebx, ecx, edx, edi, esi
1538
;      eax, ebx, ecx, edx, edi, esi
1551
;
1539
;
1552
;***************************************************************************
1540
;***************************************************************************
1553
 
1541
 
1554
align 4
1542
align 4
1555
set_active_port:
1543
set_active_port:
1556
 
1544
 
1557
        DEBUGF 1,"Trying to find the active port\n"
1545
        DEBUGF 1,"Trying to find the active port\n"
1558
 
1546
 
1559
; switch to register window 3
1547
; switch to register window 3
1560
        set_io  [ebx + device.io_addr], 0
1548
        set_io  [ebx + device.io_addr], 0
1561
        set_io  [ebx + device.io_addr], REG_COMMAND
1549
        set_io  [ebx + device.io_addr], REG_COMMAND
1562
        mov     ax, SELECT_REGISTER_WINDOW + 3
1550
        mov     ax, SELECT_REGISTER_WINDOW + 3
1563
        out     dx, ax
1551
        out     dx, ax
1564
 
1552
 
1565
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1553
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1566
        in      eax, dx
1554
        in      eax, dx
1567
        test    eax, (1 shl 24) ; check if autoselect enable
1555
        test    eax, (1 shl 24) ; check if autoselect enable
1568
        jz      .set_first_available_media
1556
        jz      .set_first_available_media
1569
 
1557
 
1570
; check 100BASE-TX and 10BASE-T
1558
; check 100BASE-TX and 10BASE-T
1571
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1559
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1572
        in      ax, dx
1560
        in      ax, dx
1573
        test    al, 1010b       ; check whether 100BASE-TX or 10BASE-T available
1561
        test    al, 1010b       ; check whether 100BASE-TX or 10BASE-T available
1574
        jz      .mii_device     ; they are not available
1562
        jz      .mii_device     ; they are not available
1575
 
1563
 
1576
; set auto-negotiation
1564
; set auto-negotiation
1577
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1565
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1578
        in      eax, dx
1566
        in      eax, dx
1579
        and     eax, not (1111b shl 20)
1567
        and     eax, not (1111b shl 20)
1580
        or      eax, (1000b shl 20)
1568
        or      eax, (1000b shl 20)
1581
        out     dx, eax
1569
        out     dx, eax
1582
        call    try_mii
1570
        call    try_mii
1583
        test    al, al
1571
        test    al, al
1584
        jz      .mii_device
1572
        jz      .mii_device
1585
        DEBUGF 1,"Using auto negotiation\n"
1573
        DEBUGF 1,"Using auto negotiation\n"
1586
        ret
1574
        ret
1587
 
1575
 
1588
  .mii_device:
1576
  .mii_device:
1589
; switch to register window 3
1577
; switch to register window 3
1590
        set_io  [ebx + device.io_addr], 0
1578
        set_io  [ebx + device.io_addr], 0
1591
; check for off-chip mii device
1579
; check for off-chip mii device
1592
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1580
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1593
        in      ax, dx
1581
        in      ax, dx
1594
        test    al, 1000000b ; check miiDevice
1582
        test    al, 1000000b ; check miiDevice
1595
        jz      .base_fx
1583
        jz      .base_fx
1596
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1584
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1597
        in      eax, dx
1585
        in      eax, dx
1598
        and     eax, not (1111b shl 20)
1586
        and     eax, not (1111b shl 20)
1599
        or      eax, (0110b shl 20) ; set MIIDevice
1587
        or      eax, (0110b shl 20) ; set MIIDevice
1600
        out     dx, eax
1588
        out     dx, eax
1601
        call    try_mii
1589
        call    try_mii
1602
        test    al, al
1590
        test    al, al
1603
        jz      .base_fx
1591
        jz      .base_fx
1604
        DEBUGF 1,"Using off-chip mii device\n"
1592
        DEBUGF 1,"Using off-chip mii device\n"
1605
        ret
1593
        ret
1606
 
1594
 
1607
  .base_fx:
1595
  .base_fx:
1608
; switch to register window 3
1596
; switch to register window 3
1609
        set_io  [ebx + device.io_addr], 0
1597
        set_io  [ebx + device.io_addr], 0
1610
; check for 100BASE-FX
1598
; check for 100BASE-FX
1611
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1599
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1612
        in      ax, dx ; read media option register
1600
        in      ax, dx ; read media option register
1613
        test    al, 100b ; check 100BASE-FX
1601
        test    al, 100b ; check 100BASE-FX
1614
        jz      .aui_enable
1602
        jz      .aui_enable
1615
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1603
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1616
        in      eax, dx
1604
        in      eax, dx
1617
        and     eax, not (1111b shl 20)
1605
        and     eax, not (1111b shl 20)
1618
        or      eax, (0101b shl 20) ; set 100base-FX
1606
        or      eax, (0101b shl 20) ; set 100base-FX
1619
        out     dx, eax
1607
        out     dx, eax
1620
        call    try_link_detect
1608
        call    try_link_detect
1621
        test    al, al
1609
        test    al, al
1622
        jz      .aui_enable
1610
        jz      .aui_enable
1623
        DEBUGF 1,"Using 100Base-FX\n"
1611
        DEBUGF 1,"Using 100Base-FX\n"
1624
        ret
1612
        ret
1625
 
1613
 
1626
  .aui_enable:
1614
  .aui_enable:
1627
; switch to register window 3
1615
; switch to register window 3
1628
        set_io  [ebx + device.io_addr], 0
1616
        set_io  [ebx + device.io_addr], 0
1629
; check for 10Mbps AUI connector
1617
; check for 10Mbps AUI connector
1630
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1618
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1631
        in      ax, dx ; read media option register
1619
        in      ax, dx ; read media option register
1632
        test    al, 100000b ; check 10Mbps AUI connector
1620
        test    al, 100000b ; check 10Mbps AUI connector
1633
        jz      .coax_available
1621
        jz      .coax_available
1634
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1622
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1635
        in      eax, dx
1623
        in      eax, dx
1636
        and     eax, not (1111b shl 20)
1624
        and     eax, not (1111b shl 20)
1637
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1625
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1638
        out     dx, eax
1626
        out     dx, eax
1639
        xor     al, al ; try 10Mbps AUI connector
1627
        xor     al, al ; try 10Mbps AUI connector
1640
        call    try_loopback
1628
        call    try_loopback
1641
        test    al, al
1629
        test    al, al
1642
        jz      .coax_available
1630
        jz      .coax_available
1643
        DEBUGF 1,"Using 10Mbps aui\n"
1631
        DEBUGF 1,"Using 10Mbps aui\n"
1644
        ret
1632
        ret
1645
 
1633
 
1646
  .coax_available:
1634
  .coax_available:
1647
; switch to register window 3
1635
; switch to register window 3
1648
        set_io  [ebx + device.io_addr], 0
1636
        set_io  [ebx + device.io_addr], 0
1649
; check for coaxial 10BASE-2 port
1637
; check for coaxial 10BASE-2 port
1650
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1638
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1651
        in      ax, dx ; read media option register
1639
        in      ax, dx ; read media option register
1652
        test    al, 10000b ; check 10BASE-2
1640
        test    al, 10000b ; check 10BASE-2
1653
        jz      .set_first_available_media
1641
        jz      .set_first_available_media
1654
 
1642
 
1655
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1643
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1656
        in      eax, dx
1644
        in      eax, dx
1657
        and     eax, not (1111b shl 20)
1645
        and     eax, not (1111b shl 20)
1658
        or      eax, (0011b shl 20) ; set 10BASE-2
1646
        or      eax, (0011b shl 20) ; set 10BASE-2
1659
        out     dx, eax
1647
        out     dx, eax
1660
        mov     al, 1
1648
        mov     al, 1
1661
        call    try_loopback
1649
        call    try_loopback
1662
        test    al, al
1650
        test    al, al
1663
        jz      .set_first_available_media
1651
        jz      .set_first_available_media
1664
        DEBUGF 1,"Using 10BASE-2 port\n"
1652
        DEBUGF 1,"Using 10BASE-2 port\n"
1665
        ret
1653
        ret
1666
 
1654
 
1667
  .set_first_available_media:
1655
  .set_first_available_media:
1668
        DEBUGF  1,"Using the first available media\n"
1656
        DEBUGF  1,"Using the first available media\n"
1669
 
1657
 
1670
;***************************************************************************
1658
;***************************************************************************
1671
;   Function
1659
;   Function
1672
;      set_available_media
1660
;      set_available_media
1673
;   Description
1661
;   Description
1674
;      sets the first available media
1662
;      sets the first available media
1675
;   Parameters
1663
;   Parameters
1676
;      ebx - ptr to device struct
1664
;      ebx - ptr to device struct
1677
;   Return value
1665
;   Return value
1678
;      al - 0
1666
;      al - 0
1679
;      al - 1
1667
;      al - 1
1680
;   Destroyed registers
1668
;   Destroyed registers
1681
;      eax, edx
1669
;      eax, edx
1682
;
1670
;
1683
;***************************************************************************
1671
;***************************************************************************
1684
 
1672
 
1685
align 4
1673
align 4
1686
set_available_media:
1674
set_available_media:
1687
 
1675
 
1688
        DEBUGF  1,"Setting the available media\n"
1676
        DEBUGF  1,"Setting the available media\n"
1689
; switch to register window 3
1677
; switch to register window 3
1690
        set_io  [ebx + device.io_addr], 0
1678
        set_io  [ebx + device.io_addr], 0
1691
        set_io  [ebx + device.io_addr], REG_COMMAND
1679
        set_io  [ebx + device.io_addr], REG_COMMAND
1692
        mov     ax, SELECT_REGISTER_WINDOW+3
1680
        mov     ax, SELECT_REGISTER_WINDOW+3
1693
        out     dx, ax
1681
        out     dx, ax
1694
 
1682
 
1695
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1683
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1696
        in      ax, dx
1684
        in      ax, dx
1697
        DEBUGF  1,"available media:%x\n", al
1685
        DEBUGF  1,"available media:%x\n", al
1698
        mov     cl, al
1686
        mov     cl, al
1699
 
1687
 
1700
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1688
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1701
        in      eax, dx
1689
        in      eax, dx
1702
        and     eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
1690
        and     eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
1703
 
1691
 
1704
        test    cl, 10b         ; baseTXAvailable
1692
        test    cl, 10b         ; baseTXAvailable
1705
        jz      @f
1693
        jz      @f
1706
 
1694
 
1707
        DEBUGF  1,"base TX is available\n"
1695
        DEBUGF  1,"base TX is available\n"
1708
        or      eax, (100b shl 20)
1696
        or      eax, (100b shl 20)
1709
if FORCE_FD
1697
if FORCE_FD
1710
        mov     word [ebx + device.internal_link], (1 shl 8)
1698
        mov     word [ebx + device.internal_link], (1 shl 8)
1711
else
1699
else
1712
        mov     word [ebx + device.internal_link], (1 shl 7)
1700
        mov     word [ebx + device.internal_link], (1 shl 7)
1713
end if
1701
end if
1714
        jmp     .set_media
1702
        jmp     .set_media
1715
       @@:
1703
       @@:
1716
 
1704
 
1717
        test    cl, 100b        ; baseFXAvailable
1705
        test    cl, 100b        ; baseFXAvailable
1718
        jz      @f
1706
        jz      @f
1719
 
1707
 
1720
        DEBUGF  1,"base FX is available\n"
1708
        DEBUGF  1,"base FX is available\n"
1721
        or      eax, (101b shl 20)
1709
        or      eax, (101b shl 20)
1722
        mov     word [ebx + device.internal_link], (1 shl 10)
1710
        mov     word [ebx + device.internal_link], (1 shl 10)
1723
        jmp     .set_media
1711
        jmp     .set_media
1724
       @@:
1712
       @@:
1725
 
1713
 
1726
        test    cl, 1000000b    ; miiDevice
1714
        test    cl, 1000000b    ; miiDevice
1727
        jz      @f
1715
        jz      @f
1728
 
1716
 
1729
        DEBUGF  1,"mii-device is available\n"
1717
        DEBUGF  1,"mii-device is available\n"
1730
        or      eax, (0110b shl 20)
1718
        or      eax, (0110b shl 20)
1731
        mov     word [ebx + device.internal_link], (1 shl 13)
1719
        mov     word [ebx + device.internal_link], (1 shl 13)
1732
        jmp     .set_media
1720
        jmp     .set_media
1733
       @@:
1721
       @@:
1734
 
1722
 
1735
        test    cl, 1000b       ; 10bTAvailable
1723
        test    cl, 1000b       ; 10bTAvailable
1736
        jz      @f
1724
        jz      @f
1737
 
1725
 
1738
        DEBUGF  1,"10base-T is available\n"
1726
        DEBUGF  1,"10base-T is available\n"
1739
  .set_default:
1727
  .set_default:
1740
if FORCE_FD
1728
if FORCE_FD
1741
        mov     word [ebx + device.internal_link], (1 shl 6)
1729
        mov     word [ebx + device.internal_link], (1 shl 6)
1742
else
1730
else
1743
        mov     word [ebx + device.internal_link], (1 shl 5)
1731
        mov     word [ebx + device.internal_link], (1 shl 5)
1744
end if
1732
end if
1745
        jmp     .set_media
1733
        jmp     .set_media
1746
       @@:
1734
       @@:
1747
 
1735
 
1748
        test    cl, 10000b      ; coaxAvailable
1736
        test    cl, 10000b      ; coaxAvailable
1749
        jz      @f
1737
        jz      @f
1750
 
1738
 
1751
        DEBUGF  1,"coax is available\n"
1739
        DEBUGF  1,"coax is available\n"
1752
        push    eax
1740
        push    eax
1753
        set_io  [ebx + device.io_addr], REG_COMMAND
1741
        set_io  [ebx + device.io_addr], REG_COMMAND
1754
        mov     ax, (10b shl 11) ; EnableDcConverter
1742
        mov     ax, (10b shl 11) ; EnableDcConverter
1755
        out     dx, ax
1743
        out     dx, ax
1756
        pop     eax
1744
        pop     eax
1757
 
1745
 
1758
        or      eax, (11b shl 20)
1746
        or      eax, (11b shl 20)
1759
        mov     word [ebx + device.internal_link], (1 shl 12)
1747
        mov     word [ebx + device.internal_link], (1 shl 12)
1760
        jmp     .set_media
1748
        jmp     .set_media
1761
       @@:
1749
       @@:
1762
 
1750
 
1763
        test    cl, 10000b      ; auiAvailable
1751
        test    cl, 10000b      ; auiAvailable
1764
        jz      .set_default
1752
        jz      .set_default
1765
 
1753
 
1766
        DEBUGF  1,"AUI is available\n"
1754
        DEBUGF  1,"AUI is available\n"
1767
        or      eax, (1 shl 20)
1755
        or      eax, (1 shl 20)
1768
        mov     word [ebx + device.internal_link], (1 shl 11)
1756
        mov     word [ebx + device.internal_link], (1 shl 11)
1769
 
1757
 
1770
  .set_media:
1758
  .set_media:
1771
        set_io  [ebx + device.io_addr], 0
1759
        set_io  [ebx + device.io_addr], 0
1772
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1760
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1773
        out     dx, eax
1761
        out     dx, eax
1774
 
1762
 
1775
if FORCE_FD
1763
if FORCE_FD
1776
        DEBUGF  1,"Forcing full duplex\n"
1764
        DEBUGF  1,"Forcing full duplex\n"
1777
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1765
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1778
        in      ax, dx
1766
        in      ax, dx
1779
        or      ax, 0x120
1767
        or      ax, 0x120
1780
        out     dx, ax
1768
        out     dx, ax
1781
end if
1769
end if
1782
 
1770
 
1783
        mov     al, 1
1771
        mov     al, 1
1784
        ret
1772
        ret
1785
 
1773
 
1786
;***************************************************************************
1774
;***************************************************************************
1787
;   Function
1775
;   Function
1788
;      write_eeprom
1776
;      write_eeprom
1789
;   Description
1777
;   Description
1790
;      reads eeprom
1778
;      reads eeprom
1791
;      Note : the caller must switch to the register window 0
1779
;      Note : the caller must switch to the register window 0
1792
;             before calling this function
1780
;             before calling this function
1793
;   Parameters:
1781
;   Parameters:
1794
;      ax - register to be read (only the first 63 words can be read)
1782
;      ax - register to be read (only the first 63 words can be read)
1795
;      cx - value to be read into the register
1783
;      cx - value to be read into the register
1796
;   Return value:
1784
;   Return value:
1797
;      ax - word read
1785
;      ax - word read
1798
;   Destroyed registers
1786
;   Destroyed registers
1799
;      ax, ebx, edx
1787
;      ax, ebx, edx
1800
;
1788
;
1801
;***************************************************************************
1789
;***************************************************************************
1802
;       align 4
1790
;       align 4
1803
;write_eeprom:
1791
;write_eeprom:
1804
;       mov     edx, [io_addr]
1792
;       mov     edx, [io_addr]
1805
;       add     edx, REG_EEPROM_COMMAND
1793
;       add     edx, REG_EEPROM_COMMAND
1806
;       cmp     ah, 11b
1794
;       cmp     ah, 11b
1807
;       ja      .finish ; address may have a value of maximal 1023
1795
;       ja      .finish ; address may have a value of maximal 1023
1808
;       shl     ax, 2
1796
;       shl     ax, 2
1809
;       shr     al, 2
1797
;       shr     al, 2
1810
;       push    eax
1798
;       push    eax
1811
;; wait for busy
1799
;; wait for busy
1812
;       mov     ebx, 0xffff
1800
;       mov     ebx, 0xffff
1813
;@@:
1801
;@@:
1814
;       in      ax, dx
1802
;       in      ax, dx
1815
;       test    ah, 0x80
1803
;       test    ah, 0x80
1816
;       jz      .write_enable
1804
;       jz      .write_enable
1817
;       dec     ebx
1805
;       dec     ebx
1818
;       jns     @r
1806
;       jns     @r
1819
;; write enable
1807
;; write enable
1820
;.write_enable:
1808
;.write_enable:
1821
;       xor     eax, eax
1809
;       xor     eax, eax
1822
;       mov     eax, (11b shl 4)
1810
;       mov     eax, (11b shl 4)
1823
;       out     dx, ax
1811
;       out     dx, ax
1824
;; wait for busy
1812
;; wait for busy
1825
;       mov     ebx, 0xffff
1813
;       mov     ebx, 0xffff
1826
;@@:
1814
;@@:
1827
;       in      ax, dx
1815
;       in      ax, dx
1828
;       test    ah, 0x80
1816
;       test    ah, 0x80
1829
;       jz      .erase_loop
1817
;       jz      .erase_loop
1830
;       dec     ebx
1818
;       dec     ebx
1831
;       jns     @r
1819
;       jns     @r
1832
;.erase_loop:
1820
;.erase_loop:
1833
;       pop     eax
1821
;       pop     eax
1834
;       push    eax
1822
;       push    eax
1835
;       or      ax, (11b shl 6) ; erase register
1823
;       or      ax, (11b shl 6) ; erase register
1836
;       out     dx, ax
1824
;       out     dx, ax
1837
;       mov     ebx, 0xffff
1825
;       mov     ebx, 0xffff
1838
;@@:
1826
;@@:
1839
;       in      ax, dx
1827
;       in      ax, dx
1840
;       test    ah, 0x80
1828
;       test    ah, 0x80
1841
;       jz      .write_reg
1829
;       jz      .write_reg
1842
;       dec     ebx
1830
;       dec     ebx
1843
;       jns     @r
1831
;       jns     @r
1844
;.write_reg:
1832
;.write_reg:
1845
;       add     edx, REG_EEPROM_DATA-REG_EEPROM_COMMAND
1833
;       add     edx, REG_EEPROM_DATA-REG_EEPROM_COMMAND
1846
;       mov     eax, ecx
1834
;       mov     eax, ecx
1847
;       out     dx, ax
1835
;       out     dx, ax
1848
;; write enable
1836
;; write enable
1849
;       add     edx, REG_EEPROM_COMMAND-REG_EEPROM_DATA
1837
;       add     edx, REG_EEPROM_COMMAND-REG_EEPROM_DATA
1850
;       xor     eax, eax
1838
;       xor     eax, eax
1851
;       mov     eax, (11b shl 4)
1839
;       mov     eax, (11b shl 4)
1852
;       out     dx, ax
1840
;       out     dx, ax
1853
; wait for busy
1841
; wait for busy
1854
;       mov     ebx, 0xffff
1842
;       mov     ebx, 0xffff
1855
;@@:
1843
;@@:
1856
;       in      ax, dx
1844
;       in      ax, dx
1857
;       test    ah, 0x80
1845
;       test    ah, 0x80
1858
;       jz      .issue_write_reg
1846
;       jz      .issue_write_reg
1859
;       dec     ebx
1847
;       dec     ebx
1860
;       jns     @r
1848
;       jns     @r
1861
;.issue_write_reg:
1849
;.issue_write_reg:
1862
;       pop     eax
1850
;       pop     eax
1863
;       or      ax, 01b shl 6
1851
;       or      ax, 01b shl 6
1864
;       out     dx, ax
1852
;       out     dx, ax
1865
;.finish:
1853
;.finish:
1866
;       ret
1854
;       ret
1867
 
1855
 
1868
 
1856
 
1869
;***************************************************************************
1857
;***************************************************************************
1870
;   Function
1858
;   Function
1871
;      read_eeprom
1859
;      read_eeprom
1872
;   Description
1860
;   Description
1873
;      reads eeprom
1861
;      reads eeprom
1874
;   Parameters:
1862
;   Parameters:
1875
;       ax - register to be read (only the first 63 words can be read)
1863
;       ax - register to be read (only the first 63 words can be read)
1876
;      ebx = driver structure
1864
;      ebx = driver structure
1877
;   Return value:
1865
;   Return value:
1878
;      ax - word read
1866
;      ax - word read
1879
;   Destroyed registers
1867
;   Destroyed registers
1880
;      ax, ebx, edx
1868
;      ax, ebx, edx
1881
;
1869
;
1882
;***************************************************************************
1870
;***************************************************************************
1883
 
1871
 
1884
align 4
1872
align 4
1885
read_eeprom:
1873
read_eeprom:
1886
 
1874
 
1887
        DEBUGF 1,"Reading from eeprom.. "
1875
        DEBUGF 1,"Reading from eeprom.. "
1888
 
1876
 
1889
        push    eax
1877
        push    eax
1890
; switch to register window 0
1878
; switch to register window 0
1891
        set_io  [ebx + device.io_addr], 0
1879
        set_io  [ebx + device.io_addr], 0
1892
        set_io  [ebx + device.io_addr], REG_COMMAND
1880
        set_io  [ebx + device.io_addr], REG_COMMAND
1893
        mov     ax, SELECT_REGISTER_WINDOW+0
1881
        mov     ax, SELECT_REGISTER_WINDOW+0
1894
        out     dx, ax
1882
        out     dx, ax
1895
        pop     eax
1883
        pop     eax
1896
        and     ax, 111111b ; take only the first 6 bits into account
1884
        and     ax, 111111b ; take only the first 6 bits into account
1897
        movzx   esi, [ebx + device.ver_id]
1885
        movzx   esi, [ebx + device.ver_id]
1898
 
1886
 
1899
        test    word [esi*4+hw_versions+2], EEPROM_8BIT
1887
        test    word [esi*4+hw_versions+2], EEPROM_8BIT
1900
        jz      @f
1888
        jz      @f
1901
        add     ax, 0x230 ; hardware constant
1889
        add     ax, 0x230 ; hardware constant
1902
        jmp     .read
1890
        jmp     .read
1903
@@:
1891
@@:
1904
 
1892
 
1905
        add     ax, EEPROM_CMD_READ
1893
        add     ax, EEPROM_CMD_READ
1906
        test    word [esi*4+hw_versions+2], EEPROM_OFFSET
1894
        test    word [esi*4+hw_versions+2], EEPROM_OFFSET
1907
        jz      .read
1895
        jz      .read
1908
        add     ax, 0x30
1896
        add     ax, 0x30
1909
.read:
1897
.read:
1910
 
1898
 
1911
        set_io  [ebx + device.io_addr], REG_EEPROM_COMMAND
1899
        set_io  [ebx + device.io_addr], REG_EEPROM_COMMAND
1912
        out     dx, ax
1900
        out     dx, ax
1913
        mov     ecx, 0xffff ; duration of about 162 us ;-)
1901
        mov     ecx, 0xffff ; duration of about 162 us ;-)
1914
.wait_for_reading:
1902
.wait_for_reading:
1915
        in      ax, dx
1903
        in      ax, dx
1916
        test    ah, 0x80 ; check bit eepromBusy
1904
        test    ah, 0x80 ; check bit eepromBusy
1917
        jz      .read_data
1905
        jz      .read_data
1918
        loop    .wait_for_reading
1906
        loop    .wait_for_reading
1919
.read_data:
1907
.read_data:
1920
        set_io  [ebx + device.io_addr], REG_EEPROM_DATA
1908
        set_io  [ebx + device.io_addr], REG_EEPROM_DATA
1921
        in      ax, dx
1909
        in      ax, dx
1922
 
1910
 
1923
        DEBUGF 1,"ok!\n"
1911
        DEBUGF 1,"ok!\n"
1924
 
1912
 
1925
        ret
1913
        ret
1926
 
1914
 
1927
;***************************************************************************
1915
;***************************************************************************
1928
;   Function
1916
;   Function
1929
;      mdio_sync
1917
;      mdio_sync
1930
;   Description
1918
;   Description
1931
;      initial synchronization
1919
;      initial synchronization
1932
;   Parameters
1920
;   Parameters
1933
;
1921
;
1934
;   Return value
1922
;   Return value
1935
;   Destroyed registers
1923
;   Destroyed registers
1936
;      ax, edx, cl
1924
;      ax, edx, cl
1937
;
1925
;
1938
;***************************************************************************
1926
;***************************************************************************
1939
 
1927
 
1940
align 4
1928
align 4
1941
mdio_sync:
1929
mdio_sync:
1942
 
1930
 
1943
        DEBUGF 1,"syncing mdio\n"
1931
        DEBUGF 1,"syncing mdio\n"
1944
 
1932
 
1945
; switch to register window 4
1933
; switch to register window 4
1946
        set_io  [ebx + device.io_addr], 0
1934
        set_io  [ebx + device.io_addr], 0
1947
        set_io  [ebx + device.io_addr], REG_COMMAND
1935
        set_io  [ebx + device.io_addr], REG_COMMAND
1948
        mov     ax, SELECT_REGISTER_WINDOW+4
1936
        mov     ax, SELECT_REGISTER_WINDOW+4
1949
        out     dx, ax
1937
        out     dx, ax
1950
        cmp     [ebx + device.preamble], 0
1938
        cmp     [ebx + device.preamble], 0
1951
        je      .no_preamble
1939
        je      .no_preamble
1952
; send 32 logic ones
1940
; send 32 logic ones
1953
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1941
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1954
        mov     ecx, 31
1942
        mov     ecx, 31
1955
  .loop:
1943
  .loop:
1956
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR)
1944
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR)
1957
        out     dx, ax
1945
        out     dx, ax
1958
        in      ax, dx ; delay
1946
        in      ax, dx ; delay
1959
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_CLK)
1947
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_CLK)
1960
        out     dx, ax
1948
        out     dx, ax
1961
        in      ax, dx ; delay
1949
        in      ax, dx ; delay
1962
        loop    .loop
1950
        loop    .loop
1963
  .no_preamble:
1951
  .no_preamble:
1964
 
1952
 
1965
        ret
1953
        ret
1966
 
1954
 
1967
;***************************************************************************
1955
;***************************************************************************
1968
;   Function
1956
;   Function
1969
;      mdio_read
1957
;      mdio_read
1970
;   Description
1958
;   Description
1971
;      read MII register
1959
;      read MII register
1972
;      see page 16 in D83840A.pdf
1960
;      see page 16 in D83840A.pdf
1973
;   Parameters
1961
;   Parameters
1974
;       ah - PHY addr
1962
;       ah - PHY addr
1975
;       al - register addr
1963
;       al - register addr
1976
;      ebx = device structure
1964
;      ebx = device structure
1977
;   Return value
1965
;   Return value
1978
;      ax - register read
1966
;      ax - register read
1979
;
1967
;
1980
;***************************************************************************
1968
;***************************************************************************
1981
 
1969
 
1982
align 4
1970
align 4
1983
mdio_read:
1971
mdio_read:
1984
 
1972
 
1985
        DEBUGF 1,"Reading MII registers\n"
1973
        DEBUGF 1,"Reading MII registers\n"
1986
 
1974
 
1987
        push    eax
1975
        push    eax
1988
        call    mdio_sync ; returns with window #4
1976
        call    mdio_sync ; returns with window #4
1989
        pop     eax
1977
        pop     eax
1990
        set_io  [ebx + device.io_addr], 0
1978
        set_io  [ebx + device.io_addr], 0
1991
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1979
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
1992
        shl     al, 3
1980
        shl     al, 3
1993
        shr     ax, 3
1981
        shr     ax, 3
1994
        and     ax, not MII_CMD_MASK
1982
        and     ax, not MII_CMD_MASK
1995
        or      ax, MII_CMD_READ
1983
        or      ax, MII_CMD_READ
1996
 
1984
 
1997
        mov     esi, eax
1985
        mov     esi, eax
1998
        mov     ecx, 13
1986
        mov     ecx, 13
1999
  .cmd_loop:
1987
  .cmd_loop:
2000
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
1988
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
2001
        bt      esi, ecx
1989
        bt      esi, ecx
2002
        jnc     .zero_bit
1990
        jnc     .zero_bit
2003
        or      al, (1 shl BIT_MGMT_DATA)
1991
        or      al, (1 shl BIT_MGMT_DATA)
2004
 
1992
 
2005
  .zero_bit:
1993
  .zero_bit:
2006
        out     dx, ax
1994
        out     dx, ax
2007
        push    ax
1995
        push    ax
2008
        in      ax, dx ; delay
1996
        in      ax, dx ; delay
2009
        pop     ax
1997
        pop     ax
2010
        or      al, (1 shl BIT_MGMT_CLK) ; write
1998
        or      al, (1 shl BIT_MGMT_CLK) ; write
2011
        out     dx, ax
1999
        out     dx, ax
2012
        in      ax, dx ; delay
2000
        in      ax, dx ; delay
2013
        loop    .cmd_loop
2001
        loop    .cmd_loop
2014
 
2002
 
2015
; read data (18 bits with the two transition bits)
2003
; read data (18 bits with the two transition bits)
2016
        mov     ecx, 17
2004
        mov     ecx, 17
2017
        xor     esi, esi
2005
        xor     esi, esi
2018
  .read_loop:
2006
  .read_loop:
2019
        shl     esi, 1
2007
        shl     esi, 1
2020
        xor     eax, eax ; read comand
2008
        xor     eax, eax ; read comand
2021
        out     dx, ax
2009
        out     dx, ax
2022
        in      ax, dx ; delay
2010
        in      ax, dx ; delay
2023
        in      ax, dx
2011
        in      ax, dx
2024
        test    al, (1 shl BIT_MGMT_DATA)
2012
        test    al, (1 shl BIT_MGMT_DATA)
2025
        jz      .dont_set
2013
        jz      .dont_set
2026
        inc     esi
2014
        inc     esi
2027
  .dont_set:
2015
  .dont_set:
2028
        mov     ax, (1 shl BIT_MGMT_CLK)
2016
        mov     ax, (1 shl BIT_MGMT_CLK)
2029
        out     dx, ax
2017
        out     dx, ax
2030
        in      ax, dx ; delay
2018
        in      ax, dx ; delay
2031
        loop    .read_loop
2019
        loop    .read_loop
2032
        mov     eax, esi
2020
        mov     eax, esi
2033
 
2021
 
2034
        ret
2022
        ret
2035
 
2023
 
2036
 
2024
 
2037
 
2025
 
2038
;***************************************************************************
2026
;***************************************************************************
2039
;   Function
2027
;   Function
2040
;      mdio_write
2028
;      mdio_write
2041
;   Description
2029
;   Description
2042
;      write MII register
2030
;      write MII register
2043
;      see page 16 in D83840A.pdf
2031
;      see page 16 in D83840A.pdf
2044
;   Parameters
2032
;   Parameters
2045
;       ah - PHY addr
2033
;       ah - PHY addr
2046
;       al - register addr
2034
;       al - register addr
2047
;       si - word to be written
2035
;       si - word to be written
2048
;   Return value
2036
;   Return value
2049
;      ax - register read
2037
;      ax - register read
2050
;
2038
;
2051
;***************************************************************************
2039
;***************************************************************************
2052
 
2040
 
2053
align 4
2041
align 4
2054
mdio_write:
2042
mdio_write:
2055
 
2043
 
2056
        DEBUGF 1,"Writing MII registers\n"
2044
        DEBUGF 1,"Writing MII registers\n"
2057
 
2045
 
2058
        push    eax
2046
        push    eax
2059
        call    mdio_sync
2047
        call    mdio_sync
2060
        pop     eax
2048
        pop     eax
2061
        set_io  [ebx + device.io_addr], 0
2049
        set_io  [ebx + device.io_addr], 0
2062
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
2050
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
2063
        shl     al, 3
2051
        shl     al, 3
2064
        shr     ax, 3
2052
        shr     ax, 3
2065
        and     ax, not MII_CMD_MASK
2053
        and     ax, not MII_CMD_MASK
2066
        or      ax, MII_CMD_WRITE
2054
        or      ax, MII_CMD_WRITE
2067
        shl     eax, 2
2055
        shl     eax, 2
2068
        or      eax, 10b ; transition bits
2056
        or      eax, 10b ; transition bits
2069
        shl     eax, 16
2057
        shl     eax, 16
2070
        mov     ax, si
2058
        mov     ax, si
2071
        mov     esi, eax
2059
        mov     esi, eax
2072
        mov     ecx, 31
2060
        mov     ecx, 31
2073
 
2061
 
2074
  .cmd_loop:
2062
  .cmd_loop:
2075
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
2063
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
2076
        bt      esi, ecx
2064
        bt      esi, ecx
2077
        jnc     @f
2065
        jnc     @f
2078
        or      al, (1 shl BIT_MGMT_DATA)
2066
        or      al, (1 shl BIT_MGMT_DATA)
2079
       @@:
2067
       @@:
2080
        out     dx, ax
2068
        out     dx, ax
2081
        push    eax
2069
        push    eax
2082
        in      ax, dx ; delay
2070
        in      ax, dx ; delay
2083
        pop     eax
2071
        pop     eax
2084
        or      al, (1 shl BIT_MGMT_CLK) ; write
2072
        or      al, (1 shl BIT_MGMT_CLK) ; write
2085
        out     dx, ax
2073
        out     dx, ax
2086
        in      ax, dx ; delay
2074
        in      ax, dx ; delay
2087
        loop    .cmd_loop
2075
        loop    .cmd_loop
2088
 
2076
 
2089
        ret
2077
        ret
2090
 
2078
 
2091
 
2079
 
2092
;***************************************************************************
2080
;***************************************************************************
2093
;   Function
2081
;   Function
2094
;      check_tx_status
2082
;      check_tx_status
2095
;   Description
2083
;   Description
2096
;      Checks TxStatus queue.
2084
;      Checks TxStatus queue.
2097
;   Return value
2085
;   Return value
2098
;      al - 0 no error was found
2086
;      al - 0 no error was found
2099
;      al - 1 error was found TxReset was needed
2087
;      al - 1 error was found TxReset was needed
2100
;   Destroyed registers
2088
;   Destroyed registers
2101
;      eax, ecx, edx
2089
;      eax, ecx, edx
2102
;
2090
;
2103
;***************************************************************************
2091
;***************************************************************************
2104
 
2092
 
2105
align 4
2093
align 4
2106
check_tx_status:
2094
check_tx_status:
2107
 
2095
 
2108
        DEBUGF 1,"Checking TX status\n"
2096
        DEBUGF 1,"Checking TX status\n"
2109
 
2097
 
2110
; clear TxStatus queue
2098
; clear TxStatus queue
2111
        set_io  [ebx + device.io_addr], 0
2099
        set_io  [ebx + device.io_addr], 0
2112
        set_io  [ebx + device.io_addr], REG_TX_STATUS
2100
        set_io  [ebx + device.io_addr], REG_TX_STATUS
2113
        mov     ecx, 31 ; max number of queue entries
2101
        mov     ecx, 31 ; max number of queue entries
2114
 
2102
 
2115
  .tx_status_loop:
2103
  .tx_status_loop:
2116
        in      al, dx
2104
        in      al, dx
2117
        test    al, al
2105
        test    al, al
2118
        jz      .finish ; no error
2106
        jz      .finish ; no error
2119
        test    al, 0x3f
2107
        test    al, 0x3f
2120
        jnz     .error
2108
        jnz     .error
2121
  .no_error_found:
2109
  .no_error_found:
2122
; clear current TxStatus entry which advances the next one
2110
; clear current TxStatus entry which advances the next one
2123
        xor     al, al
2111
        xor     al, al
2124
        out     dx, al
2112
        out     dx, al
2125
        loop    .tx_status_loop
2113
        loop    .tx_status_loop
2126
 
2114
 
2127
  .finish:
2115
  .finish:
2128
        ret
2116
        ret
2129
 
2117
 
2130
  .error:
2118
  .error:
2131
        call    tx_reset
2119
        call    tx_reset
2132
        ret
2120
        ret
2133
 
2121
 
2134
 
2122
 
2135
 
2123
 
2136
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2124
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2137
;;                                         ;;
2125
;;                                         ;;
2138
;; Transmit (vortex)                       ;;
2126
;; Transmit (vortex)                       ;;
2139
;;                                         ;;
2127
;;                                         ;;
2140
;; In: buffer pointer in [esp+4]           ;;
2128
;; In: pointer to device structure in ebx  ;;
2141
;;     pointer to device structure in ebx  ;;
2129
;; Out: eax = 0 on success                 ;;
2142
;;                                         ;;
2130
;;                                         ;;
2143
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2131
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2144
 
2132
align 16
2145
proc vortex_transmit stdcall bufferptr
2133
proc vortex_transmit stdcall bufferptr
2146
 
2134
 
2147
        pushf
-
 
2148
        cli
2135
        spin_lock_irqsave
2149
 
2136
 
2150
        mov     esi, [bufferptr]
2137
        mov     esi, [bufferptr]
2151
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
2138
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
2152
        lea     eax, [esi + NET_BUFF.data]
2139
        lea     eax, [esi + NET_BUFF.data]
2153
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2140
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2154
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2141
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2155
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2142
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2156
        [eax+13]:2,[eax+12]:2
2143
        [eax+13]:2,[eax+12]:2
2157
 
2144
 
2158
        cmp     [esi + NET_BUFF.length], 1514
2145
        cmp     [esi + NET_BUFF.length], 1514
2159
        ja      .fail
2146
        ja      .error
2160
        cmp     [esi + NET_BUFF.length], 60
2147
        cmp     [esi + NET_BUFF.length], 60
2161
        jb      .fail
2148
        jb      .error
2162
 
2149
 
2163
        call    check_tx_status
2150
        call    check_tx_status
2164
 
2151
 
2165
; switch to register window 7
2152
; switch to register window 7
2166
        set_io  [ebx + device.io_addr], 0
2153
        set_io  [ebx + device.io_addr], 0
2167
        set_io  [ebx + device.io_addr], REG_COMMAND
2154
        set_io  [ebx + device.io_addr], REG_COMMAND
2168
        mov     ax, SELECT_REGISTER_WINDOW+7
2155
        mov     ax, SELECT_REGISTER_WINDOW + 7
2169
        out     dx, ax
2156
        out     dx, ax
2170
 
2157
 
2171
; check for master operation in progress
2158
; check for master operation in progress
2172
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
2159
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
2173
        in      ax, dx
2160
        in      ax, dx
2174
        test    ah, 0x80
2161
        test    ah, 0x80
2175
        jnz     .fail ; no DMA for sending
2162
        jnz     .overrun ; no DMA for sending
2176
 
2163
 
2177
; program frame address to be sent
2164
; program frame address to be sent
2178
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2165
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2179
        mov     eax, esi
2166
        mov     eax, esi
2180
        add     eax, [eax + NET_BUFF.offset]
2167
        add     eax, [eax + NET_BUFF.offset]
2181
        invoke  GetPhysAddr
2168
        invoke  GetPhysAddr
2182
        out     dx, eax
2169
        out     dx, eax
2183
 
2170
 
2184
; program frame length
2171
; program frame length
2185
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2172
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2186
        mov     eax, [esi + NET_BUFF.length]
2173
        mov     eax, [esi + NET_BUFF.length]
2187
        out     dx, ax
2174
        out     dx, ax
2188
 
2175
 
2189
; start DMA Down
2176
; start DMA Down
2190
        set_io  [ebx + device.io_addr], REG_COMMAND
2177
        set_io  [ebx + device.io_addr], REG_COMMAND
2191
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2178
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2192
        out     dx, ax
2179
        out     dx, ax
-
 
2180
 
2193
  .finish:
2181
; Update stats
-
 
2182
        inc     [ebx + device.packets_tx]
-
 
2183
        mov     eax, [esi + NET_BUFF.length]
-
 
2184
        add     dword[ebx + device.bytes_tx], eax
-
 
2185
        adc     dword[ebx + device.bytes_tx + 4], 0
-
 
2186
 
2194
        popf
2187
        spin_unlock_irqrestore
2195
        xor     eax, eax
2188
        xor     eax, eax
2196
        ret
2189
        ret
2197
 
2190
 
-
 
2191
  .error:
-
 
2192
        DEBUGF  2, "TX packet error\n"
-
 
2193
        inc     [ebx + device.packets_tx_err]
-
 
2194
        invoke  NetFree, [bufferptr]
-
 
2195
 
-
 
2196
        spin_unlock_irqrestore
-
 
2197
        or      eax, -1
-
 
2198
        ret
-
 
2199
 
2198
  .fail:
2200
  .overrun:
-
 
2201
        DEBUGF  2, "TX overrun\n"
2199
        DEBUGF  2,"Send failed\n"
2202
        inc     [ebx + device.packets_tx_ovr]
-
 
2203
        invoke  NetFree, [bufferptr]
2200
        invoke  NetFree, [bufferptr]
2204
 
2201
        popf
2205
        spin_unlock_irqrestore
2202
        or      eax, -1
2206
        or      eax, -1
2203
        ret
2207
        ret
2204
 
2208
 
2205
endp
2209
endp
2206
 
2210
 
2207
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2211
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2208
;;                                         ;;
2212
;;                                         ;;
2209
;; Transmit (boomerang)                    ;;
2213
;; Transmit (boomerang)                    ;;
2210
;;                                         ;;
2214
;;                                         ;;
2211
;; In: buffer pointer in [esp+4]           ;;
2215
;; In: pointer to device structure in ebx  ;;
2212
;;     pointer to device structure in ebx  ;;
2216
;; Out: eax = 0 on success                 ;;
2213
;;                                         ;;
2217
;;                                         ;;
2214
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2218
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2215
 
2219
align 16
2216
proc boomerang_transmit stdcall bufferptr
2220
proc boomerang_transmit stdcall bufferptr
2217
 
2221
 
2218
        pushf
-
 
2219
        cli
2222
        spin_lock_irqsave
2220
 
2223
 
2221
        mov     esi, [bufferptr]
2224
        mov     esi, [bufferptr]
2222
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
2225
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
2223
        lea     eax, [esi + NET_BUFF.data]
2226
        lea     eax, [esi + NET_BUFF.data]
2224
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2227
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2225
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2228
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2226
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2229
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2227
        [eax+13]:2,[eax+12]:2
2230
        [eax+13]:2,[eax+12]:2
2228
 
2231
 
2229
        cmp     [esi + NET_BUFF.length], 1514
2232
        cmp     [esi + NET_BUFF.length], 1514
2230
        ja      .fail
2233
        ja      .error
2231
        cmp     [esi + NET_BUFF.length], 60
2234
        cmp     [esi + NET_BUFF.length], 60
2232
        jb      .fail
2235
        jb      .error
2233
 
2236
 
2234
        call    check_tx_status                         ; Reset TX engine if needed
2237
        call    check_tx_status                         ; Reset TX engine if needed
2235
 
2238
 
2236
; calculate descriptor address
2239
; calculate descriptor address
2237
        mov     edi, [ebx + device.curr_tx]
2240
        mov     edi, [ebx + device.curr_tx]
2238
        DEBUGF  1,"Previous TX desc: %x\n", edi
2241
        DEBUGF  1,"Previous TX desc: %x\n", edi
2239
        add     edi, sizeof.tx_desc
2242
        add     edi, sizeof.tx_desc
2240
        lea     ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc]
2243
        lea     ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc]
2241
        cmp     edi, ecx
2244
        cmp     edi, ecx
2242
        jb      @f
2245
        jb      @f
2243
        lea     edi, [ebx + device.tx_desc_buffer]      ; Wrap if needed
2246
        lea     edi, [ebx + device.tx_desc_buffer]      ; Wrap if needed
2244
       @@:
2247
       @@:
2245
        DEBUGF  1,"Using TX desc: %x\n", esi
2248
        DEBUGF  1,"Using TX desc: %x\n", esi
2246
 
2249
 
2247
; check DnListPtr
2250
; check DnListPtr
2248
        set_io  [ebx + device.io_addr], 0
2251
        set_io  [ebx + device.io_addr], 0
2249
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2252
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2250
        in      eax, dx
2253
        in      eax, dx
2251
; mark if Dn_List_Ptr is cleared
2254
; mark if Dn_List_Ptr is cleared
2252
        test    eax, eax
2255
        test    eax, eax
2253
        setz    [ebx + device.dn_list_ptr_cleared]
2256
        setz    [ebx + device.dn_list_ptr_cleared]
2254
 
2257
 
2255
; finish if no more free descriptor is available - FIXME!
2258
; finish if no more free descriptor is available - FIXME!
2256
;        cmp     eax, esi
2259
;        cmp     eax, esi
2257
;        jz      .finish
2260
;        jz      .finish
2258
 
2261
 
2259
; update statistics
2262
; update statistics
2260
        inc     [ebx + device.packets_tx]
2263
        inc     [ebx + device.packets_tx]
2261
        mov     ecx, [esi + NET_BUFF.length]
2264
        mov     ecx, [esi + NET_BUFF.length]
2262
        add     dword [ebx + device.bytes_tx], ecx
2265
        add     dword [ebx + device.bytes_tx], ecx
2263
        adc     dword [ebx + device.bytes_tx + 4], 0
2266
        adc     dword [ebx + device.bytes_tx + 4], 0
2264
 
2267
 
2265
; program DPD
2268
; program DPD
2266
        and     [edi + tx_desc.next_ptr], 0
2269
        and     [edi + tx_desc.next_ptr], 0
2267
        mov     eax, [bufferptr]
2270
        mov     eax, [bufferptr]
2268
        mov     [edi + tx_desc.realaddr], eax
2271
        mov     [edi + tx_desc.realaddr], eax
2269
        add     eax, [eax + NET_BUFF.offset]
2272
        add     eax, [eax + NET_BUFF.offset]
2270
        invoke  GetPhysAddr
2273
        invoke  GetPhysAddr
2271
        mov     [edi + tx_desc.frag_addr], eax
2274
        mov     [edi + tx_desc.frag_addr], eax
2272
;;;        mov     ecx, [buffersize]
2275
;;;        mov     ecx, [buffersize]
2273
        or      ecx, 0x80000000         ; last fragment flag
2276
        or      ecx, 0x80000000         ; last fragment flag
2274
        mov     [edi + tx_desc.frag_len], ecx
2277
        mov     [edi + tx_desc.frag_len], ecx
2275
 
2278
 
2276
;;;        mov     ecx, [buffersize]       ; packet size
2279
;;;        mov     ecx, [buffersize]       ; packet size
2277
        or      ecx, 0x80008000         ; set OWN bit + transmission complete notification flag
2280
        or      ecx, 0x80008000         ; set OWN bit + transmission complete notification flag
2278
;        test    byte [ebx + device.has_hwcksm], 0xff
2281
;        test    byte [ebx + device.has_hwcksm], 0xff
2279
;        jz      @f
2282
;        jz      @f
2280
;        or      ecx, (1 shl 26)         ; set AddTcpChecksum
2283
;        or      ecx, (1 shl 26)         ; set AddTcpChecksum
2281
;@@:
2284
;@@:
2282
        mov     [edi + tx_desc.frame_start_hdr], ecx
2285
        mov     [edi + tx_desc.frame_start_hdr], ecx
2283
        DEBUGF  1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [edi+tx_desc.realaddr]:8, [edi+tx_desc.frag_addr]:8, [edi+tx_desc.frag_len]:8, [edi+tx_desc.frame_start_hdr]:8
2286
        DEBUGF  1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [edi+tx_desc.realaddr]:8, [edi+tx_desc.frag_addr]:8, [edi+tx_desc.frag_len]:8, [edi+tx_desc.frame_start_hdr]:8
2284
 
2287
 
2285
; calculate physical address of tx descriptor
2288
; calculate physical address of tx descriptor
2286
        mov     eax, edi
2289
        mov     eax, edi
2287
        invoke  GetPhysAddr
2290
        invoke  GetPhysAddr
2288
        cmp     [ebx + device.dn_list_ptr_cleared], 0
2291
        cmp     [ebx + device.dn_list_ptr_cleared], 0
2289
        je      .add_to_list
2292
        je      .add_to_list
2290
 
2293
 
2291
; write Dn_List_Ptr
2294
; write Dn_List_Ptr
2292
        DEBUGF  1,"TX desc phys addr=%x\n", eax
2295
        DEBUGF  1,"TX desc phys addr=%x\n", eax
2293
        set_io  [ebx + device.io_addr], 0
2296
        set_io  [ebx + device.io_addr], 0
2294
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2297
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2295
        out     dx, eax
2298
        out     dx, eax
2296
        jmp     .finish
2299
        jmp     .finish
2297
 
2300
 
2298
  .add_to_list:
2301
  .add_to_list:
2299
        DEBUGF  1,"Adding To list\n"
2302
        DEBUGF  1,"Adding To list\n"
2300
        push    eax
2303
        push    eax
2301
; DnStall
2304
; DnStall
2302
        set_io  [ebx + device.io_addr], 0
2305
        set_io  [ebx + device.io_addr], 0
2303
        set_io  [ebx + device.io_addr], REG_COMMAND
2306
        set_io  [ebx + device.io_addr], REG_COMMAND
2304
        mov     ax, ((110b shl 11)+2)
2307
        mov     ax, ((110b shl 11)+2)
2305
        out     dx, ax
2308
        out     dx, ax
2306
 
2309
 
2307
; wait for DnStall to complete
2310
; wait for DnStall to complete
2308
        DEBUGF  1,"Waiting for DnStall\n"
2311
        DEBUGF  1,"Waiting for DnStall\n"
2309
        mov     ecx, 6000
2312
        mov     ecx, 6000
2310
  .wait_for_stall:
2313
  .wait_for_stall:
2311
        in      ax, dx                  ; read REG_INT_STATUS
2314
        in      ax, dx                  ; read REG_INT_STATUS
2312
        test    ah, 10000b
2315
        test    ah, 10000b
2313
        jz      .dnstall_ok
2316
        jz      .dnstall_ok
2314
        dec     ecx
2317
        dec     ecx
2315
        jnz     .wait_for_stall
2318
        jnz     .wait_for_stall
2316
 
2319
 
2317
  .dnstall_ok:
2320
  .dnstall_ok:
2318
        DEBUGF  1,"DnStall ok!\n"
2321
        DEBUGF  1,"DnStall ok!\n"
2319
        mov     ecx, [ebx + device.curr_tx]
2322
        mov     ecx, [ebx + device.curr_tx]
2320
        mov     [ecx + tx_desc.next_ptr], eax
2323
        mov     [ecx + tx_desc.next_ptr], eax
2321
 
2324
 
2322
        set_io  [ebx + device.io_addr], 0
2325
        set_io  [ebx + device.io_addr], 0
2323
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2326
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2324
        in      eax, dx
2327
        in      eax, dx
2325
        test    eax, eax
2328
        test    eax, eax
2326
        pop     eax
2329
        pop     eax
2327
        jnz     .dnunstall
2330
        jnz     .dnunstall
2328
 
2331
 
2329
; if Dn_List_Ptr has been cleared fill it up
2332
; if Dn_List_Ptr has been cleared fill it up
2330
        DEBUGF  1,"DnList Ptr has been cleared\n"
2333
        DEBUGF  1,"DnList Ptr has been cleared\n"
2331
        out     dx, eax
2334
        out     dx, eax
2332
 
2335
 
2333
  .dnunstall:
2336
  .dnunstall:
2334
; DnUnStall
2337
; DnUnStall
2335
        set_io  [ebx + device.io_addr], 0
2338
        set_io  [ebx + device.io_addr], 0
2336
        set_io  [ebx + device.io_addr], REG_COMMAND
2339
        set_io  [ebx + device.io_addr], REG_COMMAND
2337
        mov     ax, ((110b shl 11)+3)
2340
        mov     ax, ((110b shl 11)+3)
2338
        out     dx, ax
2341
        out     dx, ax
2339
 
2342
 
2340
  .finish:
2343
  .finish:
2341
        mov     [ebx + device.curr_tx], edi
2344
        mov     [ebx + device.curr_tx], edi
-
 
2345
 
2342
        popf
2346
; Update stats
-
 
2347
        inc     [ebx + device.packets_tx]
-
 
2348
        mov     eax, [esi + NET_BUFF.length]
-
 
2349
        add     dword[ebx + device.bytes_tx], eax
-
 
2350
        adc     dword[ebx + device.bytes_tx + 4], 0
-
 
2351
 
-
 
2352
        spin_unlock_irqrestore
2343
        xor     eax, eax
2353
        xor     eax, eax
2344
        ret
2354
        ret
2345
 
2355
 
-
 
2356
  .error:
-
 
2357
        DEBUGF  2, "TX packet error\n"
-
 
2358
        inc     [ebx + device.packets_tx_err]
-
 
2359
        invoke  NetFree, [bufferptr]
-
 
2360
 
-
 
2361
        spin_unlock_irqrestore
-
 
2362
        or      eax, -1
-
 
2363
        ret
-
 
2364
 
2346
  .fail:
2365
  .overrun:
-
 
2366
        DEBUGF  2, "TX overrun\n"
2347
        DEBUGF  2,"Send failed\n"
2367
        inc     [ebx + device.packets_tx_ovr]
-
 
2368
        invoke  NetFree, [bufferptr]
2348
        invoke  NetFree, [bufferptr]
2369
 
2349
        popf
2370
        spin_unlock_irqrestore
2350
        or      eax, -1
2371
        or      eax, -1
2351
        ret
2372
        ret
2352
 
2373
 
2353
endp
2374
endp
2354
 
2375
 
2355
 
2376
 
2356
 
2377
 
2357
;---------------------------------
2378
;---------------------------------
2358
; Write MAC
2379
; Write MAC
2359
 
2380
 
2360
align 4
2381
align 4
2361
write_mac:
2382
write_mac:
2362
 
2383
 
2363
        DEBUGF 1,"Writing mac\n"
2384
        DEBUGF 1,"Writing mac\n"
2364
 
2385
 
2365
        set_io  [ebx + device.io_addr], 0
2386
        set_io  [ebx + device.io_addr], 0
2366
        set_io  [ebx + device.io_addr], REG_COMMAND
2387
        set_io  [ebx + device.io_addr], REG_COMMAND
2367
 
2388
 
2368
; switch to register window 2
2389
; switch to register window 2
2369
        mov     ax, SELECT_REGISTER_WINDOW+2
2390
        mov     ax, SELECT_REGISTER_WINDOW+2
2370
        out     dx, ax
2391
        out     dx, ax
2371
 
2392
 
2372
; write MAC addres back into the station address registers
2393
; write MAC addres back into the station address registers
2373
        set_io  [ebx + device.io_addr], REG_STATION_ADDRESS_LO
2394
        set_io  [ebx + device.io_addr], REG_STATION_ADDRESS_LO
2374
        lea     esi, [ebx + device.mac]
2395
        lea     esi, [ebx + device.mac]
2375
        outsw
2396
        outsw
2376
        inc     dx
2397
        inc     dx
2377
        inc     dx
2398
        inc     dx
2378
        outsw
2399
        outsw
2379
        inc     dx
2400
        inc     dx
2380
        inc     dx
2401
        inc     dx
2381
        outsw
2402
        outsw
2382
 
2403
 
2383
 
2404
 
2384
;----------------------------
2405
;----------------------------
2385
; Read MAC
2406
; Read MAC
2386
 
2407
 
2387
align 4
2408
align 4
2388
read_mac:
2409
read_mac:
2389
 
2410
 
2390
        DEBUGF 1,"Reading MAC\n"
2411
        DEBUGF 1,"Reading MAC\n"
2391
 
2412
 
2392
        set_io  [ebx + device.io_addr], 0
2413
        set_io  [ebx + device.io_addr], 0
2393
        set_io  [ebx + device.io_addr], REG_COMMAND
2414
        set_io  [ebx + device.io_addr], REG_COMMAND
2394
 
2415
 
2395
; switch to register window 2
2416
; switch to register window 2
2396
        mov     ax, SELECT_REGISTER_WINDOW+2
2417
        mov     ax, SELECT_REGISTER_WINDOW+2
2397
        out     dx, ax
2418
        out     dx, ax
2398
 
2419
 
2399
; Read the MAC and write it to device.mac
2420
; Read the MAC and write it to device.mac
2400
        set_io  [ebx + device.io_addr], REG_STATION_ADDRESS_LO
2421
        set_io  [ebx + device.io_addr], REG_STATION_ADDRESS_LO
2401
        lea     edi, [ebx + device.mac]
2422
        lea     edi, [ebx + device.mac]
2402
        insw
2423
        insw
2403
        inc     dx
2424
        inc     dx
2404
        inc     dx
2425
        inc     dx
2405
        insw
2426
        insw
2406
        inc     dx
2427
        inc     dx
2407
        inc     dx
2428
        inc     dx
2408
        insw
2429
        insw
2409
 
2430
 
2410
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n", \
2431
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n", \
2411
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
2432
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
2412
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
2433
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
2413
 
2434
 
2414
        ret
2435
        ret
2415
 
2436
 
2416
 
2437
 
2417
;------------------------------------
2438
;------------------------------------
2418
; Read MAC from eeprom
2439
; Read MAC from eeprom
2419
 
2440
 
2420
align 4
2441
align 4
2421
read_mac_eeprom:
2442
read_mac_eeprom:
2422
 
2443
 
2423
        DEBUGF 1,"Reading MAC from eeprom\n"
2444
        DEBUGF 1,"Reading MAC from eeprom\n"
2424
 
2445
 
2425
; read MAC from eeprom and write it to device.mac
2446
; read MAC from eeprom and write it to device.mac
2426
        mov     ecx, 3
2447
        mov     ecx, 3
2427
  .mac_loop:
2448
  .mac_loop:
2428
        lea     ax, [EEPROM_REG_OEM_NODE_ADDR+ecx-1]
2449
        lea     ax, [EEPROM_REG_OEM_NODE_ADDR+ecx-1]
2429
        push    ecx
2450
        push    ecx
2430
        call    read_eeprom
2451
        call    read_eeprom
2431
        pop     ecx
2452
        pop     ecx
2432
        xchg    ah, al
2453
        xchg    ah, al
2433
        mov     word [ebx + device.mac+ecx*2-2], ax
2454
        mov     word [ebx + device.mac+ecx*2-2], ax
2434
        loop    .mac_loop
2455
        loop    .mac_loop
2435
 
2456
 
2436
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",\
2457
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",\
2437
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
2458
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
2438
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
2459
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
2439
 
2460
 
2440
        ret
2461
        ret
2441
 
2462
 
2442
 
2463
 
2443
 
2464
 
2444
 
2465
 
2445
 
2466
 
2446
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2467
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2447
;;                          ;;
2468
;;                          ;;
2448
;; Vortex Interrupt handler ;;
2469
;; Vortex Interrupt handler ;;
2449
;;                          ;;
2470
;;                          ;;
2450
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2471
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2451
 
-
 
2452
align 4
2472
align 16
2453
int_vortex:
2473
int_vortex:
2454
 
2474
 
2455
        push    ebx esi edi
2475
        push    ebx esi edi
2456
 
-
 
2457
        DEBUGF  1,"INT\n"
-
 
2458
 
-
 
2459
; find pointer of device wich made IRQ occur
-
 
2460
 
2476
 
2461
        mov     ecx, [vortex_devices]
2477
        mov     ebx, [esp+4*4]
2462
        test    ecx, ecx
-
 
2463
        jz      .nothing
-
 
2464
        mov     esi, vortex_list
-
 
2465
  .nextdevice:
-
 
-
 
2478
        DEBUGF  1,"INT for 0x%x\n", ebx
2466
        mov     ebx, [esi]
2479
 
2467
 
2480
; TODO? if we are paranoid, we can check that the value from ebx is present in the current device_list
2468
 
2481
 
2469
        set_io  [ebx + device.io_addr], 0
2482
        set_io  [ebx + device.io_addr], 0
2470
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2483
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2471
        in      ax, dx
2484
        in      ax, dx
2472
        and     ax, S_5_INTS
2485
        and     ax, S_5_INTS
2473
        jnz     .nothing
2486
        jnz     .nothing
2474
 
-
 
2475
        add     esi, 4
-
 
2476
 
-
 
2477
        test    ax , ax
-
 
2478
        jnz     .got_it
-
 
2479
        loop    .nextdevice
-
 
2480
 
-
 
2481
  .nothing:
-
 
2482
        pop     edi esi ebx
-
 
2483
        xor     eax, eax
-
 
2484
 
-
 
2485
        ret
-
 
2486
 
-
 
2487
.got_it:
-
 
2488
 
2487
 
2489
        DEBUGF  1,"Device: %x Status: %x\n", ebx, eax:4
2488
        DEBUGF  1,"Status: %x\n", eax:4
2490
 
2489
 
2491
        test    ax, RxComplete
2490
        test    ax, RxComplete
2492
        jz      .noRX
2491
        jz      .noRX
2493
 
2492
 
2494
        set_io  [ebx + device.io_addr], 0
2493
        set_io  [ebx + device.io_addr], 0
2495
  .rx_status_loop:
2494
  .rx_status_loop:
2496
; examine RxStatus
2495
; examine RxStatus
2497
        set_io  [ebx + device.io_addr], REG_RX_STATUS
2496
        set_io  [ebx + device.io_addr], REG_RX_STATUS
2498
        in      ax, dx
2497
        in      ax, dx
2499
        test    ax, ax
2498
        test    ax, ax
2500
        jz      .finish
2499
        jz      .finish
2501
 
2500
 
2502
        test    ah, 0x80 ; rxIncomplete
2501
        test    ah, 0x80 ; rxIncomplete
2503
        jnz     .finish
2502
        jnz     .finish
2504
 
2503
 
2505
        test    ah, 0x40
2504
        test    ah, 0x40
2506
        jz      .check_length
2505
        jz      .check_length
2507
 
2506
 
2508
; discard the top frame received advancing the next one
2507
; discard the top frame received advancing the next one
2509
        set_io  [ebx + device.io_addr], REG_COMMAND
2508
        set_io  [ebx + device.io_addr], REG_COMMAND
2510
        mov     ax, (01000b shl 11)
2509
        mov     ax, (01000b shl 11)
2511
        out     dx, ax
2510
        out     dx, ax
2512
        jmp     .rx_status_loop
2511
        jmp     .rx_status_loop
2513
 
2512
 
2514
  .check_length:
2513
  .check_length:
2515
        and     eax, 0x1fff
2514
        and     eax, 0x1fff
2516
        cmp     eax, MAX_ETH_FRAME_SIZE
2515
        cmp     eax, MAX_ETH_FRAME_SIZE
2517
        ja      .discard_frame ; frame is too long discard it
2516
        ja      .discard_frame ; frame is too long discard it
2518
 
2517
 
2519
  .check_dma:
2518
  .check_dma:
2520
        mov     ecx, eax
2519
        mov     ecx, eax
2521
; switch to register window 7
2520
; switch to register window 7
2522
        set_io  [ebx + device.io_addr], 0
2521
        set_io  [ebx + device.io_addr], 0
2523
        set_io  [ebx + device.io_addr], REG_COMMAND
2522
        set_io  [ebx + device.io_addr], REG_COMMAND
2524
        mov     ax, SELECT_REGISTER_WINDOW+7
2523
        mov     ax, SELECT_REGISTER_WINDOW+7
2525
        out     dx, ax
2524
        out     dx, ax
2526
; check for master operation in progress
2525
; check for master operation in progress
2527
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
2526
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
2528
        in      ax, dx
2527
        in      ax, dx
2529
 
2528
 
2530
        test    ah, 0x80
2529
        test    ah, 0x80
2531
        jnz     .finish
2530
        jnz     .finish
2532
 
2531
 
2533
  .read_frame:
2532
  .read_frame:
2534
; program buffer address to read in
2533
; program buffer address to read in
2535
        push    ecx
2534
        push    ecx
2536
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
2535
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
2537
        pop     ecx
2536
        pop     ecx
2538
        test    eax, eax
2537
        test    eax, eax
2539
        jz      .finish
2538
        jz      .finish
2540
 
2539
 
2541
        push    .discard_frame
2540
        push    .discard_frame
2542
        push    eax
2541
        push    eax
2543
        mov     [eax + NET_BUFF.length], ecx
2542
        mov     [eax + NET_BUFF.length], ecx
2544
        mov     [eax + NET_BUFF.device], ebx
2543
        mov     [eax + NET_BUFF.device], ebx
2545
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
2544
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
2546
        invoke  GetPhysAddr
2545
        invoke  GetPhysAddr
2547
        add     eax, NET_BUFF.data
2546
        add     eax, NET_BUFF.data
2548
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2547
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2549
        out     dx, eax
2548
        out     dx, eax
2550
 
2549
 
2551
; program frame length
2550
; program frame length
2552
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2551
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2553
        mov     ax, 1560
2552
        mov     ax, 1560
2554
        out     dx, ax
2553
        out     dx, ax
2555
 
2554
 
2556
; start DMA Up
2555
; start DMA Up
2557
        set_io  [ebx + device.io_addr], REG_COMMAND
2556
        set_io  [ebx + device.io_addr], REG_COMMAND
2558
        mov     ax, (10100b shl 11) ; StartDMAUp
2557
        mov     ax, (10100b shl 11) ; StartDMAUp
2559
        out     dx, ax
2558
        out     dx, ax
2560
 
2559
 
2561
; check for master operation in progress
2560
; check for master operation in progress
2562
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS   ; TODO: use timeout and reset after timeout expired
2561
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS   ; TODO: use timeout and reset after timeout expired
2563
  .dma_loop:
2562
  .dma_loop:
2564
        in      ax, dx
2563
        in      ax, dx
2565
        test    ah, 0x80
2564
        test    ah, 0x80
2566
        jnz     .dma_loop
2565
        jnz     .dma_loop
2567
 
2566
 
2568
; registrate the received packet to kernel
2567
; registrate the received packet to kernel
2569
        jmp     [EthInput]
2568
        jmp     [EthInput]
2570
 
2569
 
2571
; discard the top frame received
2570
; discard the top frame received
2572
  .discard_frame:
2571
  .discard_frame:
2573
        set_io  [ebx + device.io_addr], 0
2572
        set_io  [ebx + device.io_addr], 0
2574
        set_io  [ebx + device.io_addr], REG_COMMAND
2573
        set_io  [ebx + device.io_addr], REG_COMMAND
2575
        mov     ax, (01000b shl 11)
2574
        mov     ax, (01000b shl 11)
2576
        out     dx, ax
2575
        out     dx, ax
2577
 
2576
 
2578
  .finish:
2577
  .finish:
2579
 
-
 
2580
 
-
 
2581
  .noRX:
2578
  .noRX:
2582
 
-
 
2583
        test    ax, DMADone
2579
        test    ax, DMADone
2584
        jz      .noDMA
2580
        jz      .noDMA
2585
 
2581
 
2586
        push    ax
2582
        push    ax
2587
 
2583
 
2588
        set_io  [ebx + device.io_addr], 0
2584
        set_io  [ebx + device.io_addr], 0
2589
        set_io  [ebx + device.io_addr], 12
2585
        set_io  [ebx + device.io_addr], 12
2590
        in      ax, dx
2586
        in      ax, dx
2591
        test    ax, 0x1000
2587
        test    ax, 0x1000
2592
        jz      .nodmaclear
2588
        jz      .nodmaclear
2593
 
2589
 
2594
        mov     ax, 0x1000
2590
        mov     ax, 0x1000
2595
        out     dx, ax
2591
        out     dx, ax
2596
 
2592
 
2597
  .nodmaclear:
2593
  .nodmaclear:
2598
 
-
 
2599
        pop     ax
2594
        pop     ax
2600
 
2595
 
2601
        DEBUGF  1, "DMA Done!\n", cx
2596
        DEBUGF  1, "DMA Done!\n", cx
2602
 
-
 
2603
 
-
 
2604
 
2597
 
2605
  .noDMA:
-
 
2606
 
-
 
2607
 
-
 
2608
 
2598
  .noDMA:
2609
  .ACK:
2599
  .ACK:
2610
        set_io  [ebx + device.io_addr], 0
2600
        set_io  [ebx + device.io_addr], 0
2611
        set_io  [ebx + device.io_addr], REG_COMMAND
2601
        set_io  [ebx + device.io_addr], REG_COMMAND
2612
        mov     ax, AckIntr + IntReq + IntLatch
2602
        mov     ax, AckIntr + IntReq + IntLatch
2613
        out     dx, ax
2603
        out     dx, ax
2614
 
2604
 
2615
        pop     edi esi ebx
2605
        pop     edi esi ebx
-
 
2606
        xor     eax, eax
-
 
2607
        inc     eax
-
 
2608
 
-
 
2609
        ret
-
 
2610
 
-
 
2611
  .nothing:
-
 
2612
        pop     edi esi ebx
-
 
2613
        xor     eax, eax
2616
 
2614
 
2617
        ret
2615
        ret
2618
 
2616
 
2619
 
2617
 
2620
 
2618
 
2621
 
2619
 
2622
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2620
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2623
;;                             ;;
2621
;;                             ;;
2624
;; Boomerang Interrupt handler ;;
2622
;; Boomerang Interrupt handler ;;
2625
;;                             ;;
2623
;;                             ;;
2626
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2624
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2627
 
-
 
2628
align 4
2625
align 16
2629
int_boomerang:
2626
int_boomerang:
2630
 
2627
 
2631
        push    ebx esi edi
2628
        push    ebx esi edi
-
 
2629
 
2632
 
2630
        mov     ebx, [esp+4*4]
2633
        DEBUGF  1,"INT\n"
-
 
2634
 
-
 
2635
; find pointer of device wich made IRQ occur
2631
        DEBUGF  1,"INT for 0x%x\n", ebx
2636
 
-
 
2637
        mov     ecx, [boomerang_devices]
-
 
2638
        test    ecx, ecx
-
 
2639
        jz      .nothing
-
 
2640
        mov     esi, boomerang_list
-
 
2641
  .nextdevice:
2632
 
2642
        mov     ebx, [esi]
2633
; TODO? if we are paranoid, we can check that the value from ebx is present in the current device_list
2643
 
2634
 
2644
        set_io  [ebx + device.io_addr], 0
2635
        set_io  [ebx + device.io_addr], 0
2645
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2636
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2646
        in      ax, dx
2637
        in      ax, dx
2647
        test    ax, S_5_INTS
2638
        test    ax, S_5_INTS
2648
        jnz     .got_it
2639
        jz      .nothing
2649
  .continue:
-
 
2650
        add     esi, 4
-
 
2651
        dec     ecx
-
 
2652
        jnz     .nextdevice
-
 
2653
  .nothing:
-
 
2654
        pop     edi esi ebx
-
 
2655
        xor     eax, eax
-
 
2656
 
-
 
2657
        ret
-
 
2658
 
-
 
2659
  .got_it:
2640
  .got_it:
-
 
2641
        DEBUGF  1,"Status: %x\n", ax
2660
 
-
 
2661
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
2642
 
2662
        push    ax
2643
        push    ax
2663
 
2644
 
2664
; disable all INTS
2645
; disable all INTS
2665
 
2646
 
2666
        set_io  [ebx + device.io_addr], REG_COMMAND
2647
        set_io  [ebx + device.io_addr], REG_COMMAND
2667
        mov     ax, SetIntrEnb
2648
        mov     ax, SetIntrEnb
2668
        out     dx, ax
2649
        out     dx, ax
2669
 
2650
 
2670
;--------------------------------------------------------------------------
2651
;--------------------------------------------------------------------------
2671
        test    word[esp], UpComplete
2652
        test    word[esp], UpComplete
2672
        jz      .noRX
2653
        jz      .noRX
2673
 
2654
 
2674
        push    ebx
2655
        push    ebx
2675
 
2656
 
2676
  .receive:
2657
  .receive:
2677
        DEBUGF  1,"UpComplete\n"
2658
        DEBUGF  1,"UpComplete\n"
2678
 
2659
 
2679
; check if packet is uploaded
2660
; check if packet is uploaded
2680
        mov     esi, [ebx + device.curr_rx]
2661
        mov     esi, [ebx + device.curr_rx]
2681
        test    byte [esi+rx_desc.pkt_status+1], 0x80 ; upPktComplete
2662
        test    byte [esi+rx_desc.pkt_status+1], 0x80 ; upPktComplete
2682
        jz      .finish
2663
        jz      .finish
2683
        DEBUGF  1, "Current RX desc: %x\n", esi
2664
        DEBUGF  1, "Current RX desc: %x\n", esi
2684
; packet is uploaded check for any error
2665
; packet is uploaded check for any error
2685
  .check_error:
2666
  .check_error:
2686
        test    byte [esi + rx_desc.pkt_status+1], 0x40 ; upError
2667
        test    byte [esi + rx_desc.pkt_status+1], 0x40 ; upError
2687
        jz      .copy_packet_length
2668
        jz      .copy_packet_length
2688
        DEBUGF  1,"Error in packet\n"
2669
        DEBUGF  1,"Error in packet\n"
2689
        and     [esi + rx_desc.pkt_status], 0           ; mark packet as read
2670
        and     [esi + rx_desc.pkt_status], 0           ; mark packet as read
2690
        jmp     .finish
2671
        jmp     .finish
2691
  .copy_packet_length:
2672
  .copy_packet_length:
2692
        mov     ecx, [esi + rx_desc.pkt_status]
2673
        mov     ecx, [esi + rx_desc.pkt_status]
2693
        and     ecx, 0x1fff
2674
        and     ecx, 0x1fff
2694
 
2675
 
2695
;        cmp     ecx, MAX_ETH_PKT_SIZE
2676
;        cmp     ecx, MAX_ETH_PKT_SIZE
2696
;        jbe     .copy_packet
2677
;        jbe     .copy_packet
2697
;        and     [esi+rx_desc.pkt_status], 0
2678
;        and     [esi+rx_desc.pkt_status], 0
2698
;        jmp     .finish
2679
;        jmp     .finish
2699
;  .copy_packet:
2680
;  .copy_packet:
2700
 
2681
 
2701
        DEBUGF  1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8
2682
        DEBUGF  1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8
2702
 
2683
 
2703
        push    dword .loop ;.finish
2684
        push    dword .loop ;.finish
2704
        mov     eax, [esi + rx_desc.realaddr]
2685
        mov     eax, [esi + rx_desc.realaddr]
2705
        push    eax
2686
        push    eax
2706
        mov     [eax + NET_BUFF.length], ecx
2687
        mov     [eax + NET_BUFF.length], ecx
2707
        mov     [eax + NET_BUFF.device], ebx
2688
        mov     [eax + NET_BUFF.device], ebx
2708
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
2689
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
2709
 
2690
 
2710
; update statistics
2691
; update statistics
2711
        inc     [ebx + device.packets_rx]
2692
        inc     [ebx + device.packets_rx]
2712
        add     dword [ebx + device.bytes_rx], ecx
2693
        add     dword [ebx + device.bytes_rx], ecx
2713
        adc     dword [ebx + device.bytes_rx + 4], 0
2694
        adc     dword [ebx + device.bytes_rx + 4], 0
2714
 
2695
 
2715
; update rx descriptor (Alloc new buffer for next packet)
2696
; update rx descriptor (Alloc new buffer for next packet)
2716
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
2697
        invoke  NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
2717
        mov     [esi + rx_desc.realaddr], eax
2698
        mov     [esi + rx_desc.realaddr], eax
2718
        invoke  GetPhysAddr
2699
        invoke  GetPhysAddr
2719
        add     eax, NET_BUFF.data
2700
        add     eax, NET_BUFF.data
2720
        mov     [esi + rx_desc.frag_addr], eax
2701
        mov     [esi + rx_desc.frag_addr], eax
2721
        and     [esi + rx_desc.pkt_status], 0
2702
        and     [esi + rx_desc.pkt_status], 0
2722
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
2703
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
2723
 
2704
 
2724
; Update rx descriptor pointer
2705
; Update rx descriptor pointer
2725
        add     esi, sizeof.rx_desc
2706
        add     esi, sizeof.rx_desc
2726
        lea     ecx, [ebx + device.rx_desc_buffer+(NUM_RX_DESC)*sizeof.rx_desc]
2707
        lea     ecx, [ebx + device.rx_desc_buffer+(NUM_RX_DESC)*sizeof.rx_desc]
2727
        cmp     esi, ecx
2708
        cmp     esi, ecx
2728
        jb      @f
2709
        jb      @f
2729
        lea     esi, [ebx + device.rx_desc_buffer]
2710
        lea     esi, [ebx + device.rx_desc_buffer]
2730
       @@:
2711
       @@:
2731
        mov     [ebx + device.curr_rx], esi
2712
        mov     [ebx + device.curr_rx], esi
2732
        DEBUGF  1, "Next RX desc: %x\n", esi
2713
        DEBUGF  1, "Next RX desc: %x\n", esi
2733
 
2714
 
2734
        jmp     [EthInput]
2715
        jmp     [EthInput]
2735
  .loop:
2716
  .loop:
2736
 
2717
 
2737
        mov     ebx, [esp]
2718
        mov     ebx, [esp]
2738
        jmp     .receive
2719
        jmp     .receive
2739
 
2720
 
2740
  .finish:
2721
  .finish:
2741
        pop     ebx
2722
        pop     ebx
2742
 
2723
 
2743
; check if the NIC is in the upStall state
2724
; check if the NIC is in the upStall state
2744
        set_io  [ebx + device.io_addr], 0
2725
        set_io  [ebx + device.io_addr], 0
2745
        set_io  [ebx + device.io_addr], REG_UP_PKT_STATUS
2726
        set_io  [ebx + device.io_addr], REG_UP_PKT_STATUS
2746
        in      eax, dx
2727
        in      eax, dx
2747
        test    ah, 0x20             ; UpStalled
2728
        test    ah, 0x20             ; UpStalled
2748
        jz      .noUpUnStall
2729
        jz      .noUpUnStall
2749
 
2730
 
2750
        DEBUGF  1, "upUnStalling\n"
2731
        DEBUGF  1, "upUnStalling\n"
2751
; issue upUnStall command
2732
; issue upUnStall command
2752
        set_io  [ebx + device.io_addr], REG_COMMAND
2733
        set_io  [ebx + device.io_addr], REG_COMMAND
2753
        mov     ax, ((11b shl 12)+1) ; upUnStall
2734
        mov     ax, ((11b shl 12)+1) ; upUnStall
2754
        out     dx, ax
2735
        out     dx, ax
2755
 
2736
 
2756
        ;;;; FIXME: make upunstall work
2737
        ;;;; FIXME: make upunstall work
2757
 
2738
 
2758
  .noUpUnStall:
2739
  .noUpUnStall:
2759
.noRX:
2740
  .noRX:
2760
        test    word[esp], DownComplete
2741
        test    word[esp], DownComplete
2761
        jz      .noTX
2742
        jz      .noTX
2762
        DEBUGF  1, "Downcomplete!\n"
2743
        DEBUGF  1, "Downcomplete!\n"
2763
 
2744
 
2764
        mov     ecx, NUM_TX_DESC
2745
        mov     ecx, NUM_TX_DESC
2765
        lea     esi, [ebx + device.tx_desc_buffer]
2746
        lea     esi, [ebx + device.tx_desc_buffer]
2766
  .txloop:
2747
  .txloop:
2767
        test    [esi+tx_desc.frame_start_hdr], 1 shl 31
2748
        test    [esi+tx_desc.frame_start_hdr], 1 shl 31
2768
        jz      .maybenext
2749
        jz      .maybenext
2769
 
2750
 
2770
        and     [esi+tx_desc.frame_start_hdr], 0
2751
        and     [esi+tx_desc.frame_start_hdr], 0
2771
        push    ecx
2752
        push    ecx
2772
        invoke  NetFree, [esi+tx_desc.realaddr]
2753
        invoke  NetFree, [esi+tx_desc.realaddr]
2773
        pop     ecx
2754
        pop     ecx
2774
 
2755
 
2775
  .maybenext:
2756
  .maybenext:
2776
        add     esi, sizeof.tx_desc
2757
        add     esi, sizeof.tx_desc
2777
        dec     ecx
2758
        dec     ecx
2778
        jnz     .txloop
2759
        jnz     .txloop
2779
 
2760
 
2780
.noTX:
2761
  .noTX:
2781
        pop     ax
2762
        pop     ax
2782
 
2763
 
2783
        set_io  [ebx + device.io_addr], 0
2764
        set_io  [ebx + device.io_addr], 0
2784
        set_io  [ebx + device.io_addr], REG_COMMAND
2765
        set_io  [ebx + device.io_addr], REG_COMMAND
2785
        or      ax, AckIntr
2766
        or      ax, AckIntr
2786
        out     dx, ax
2767
        out     dx, ax
2787
 
2768
 
2788
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2769
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2789
        in      ax, dx
2770
        in      ax, dx
2790
        test    ax, S_5_INTS
2771
        test    ax, S_5_INTS
2791
        jnz     .got_it
2772
        jnz     .got_it
2792
 
2773
 
2793
;re-enable ints
2774
;re-enable ints
2794
        set_io  [ebx + device.io_addr], REG_COMMAND
2775
        set_io  [ebx + device.io_addr], REG_COMMAND
2795
        mov     ax, SetIntrEnb + S_5_INTS
2776
        mov     ax, SetIntrEnb + S_5_INTS
2796
        out     dx, ax
2777
        out     dx, ax
2797
 
2778
 
2798
        pop     edi esi ebx
2779
        pop     edi esi ebx
-
 
2780
        xor     eax, eax
-
 
2781
        inc     eax
-
 
2782
 
-
 
2783
        ret
-
 
2784
 
-
 
2785
  .nothing:
-
 
2786
        pop     edi esi ebx
-
 
2787
        xor     eax, eax
2799
 
2788
 
2800
        ret
2789
        ret
2801
 
2790
 
2802
 
2791
 
2803
 
2792
 
2804
 
2793
 
2805
; End of code
2794
; End of code
2806
 
2795
 
2807
data fixups
2796
data fixups
2808
end data
2797
end data
2809
 
2798
 
2810
include '../peimport.inc'
2799
include '../peimport.inc'
2811
 
2800
 
2812
my_service           db '3C59X',0                    ; max 16 chars include zero
2801
my_service           db '3C59X',0                    ; max 16 chars include zero
2813
 
2802
 
2814
macro strtbl name, [string]
2803
macro strtbl name, [string]
2815
{
2804
{
2816
common
2805
common
2817
        label name dword
2806
        label name dword
2818
forward
2807
forward
2819
        local label
2808
        local label
2820
        dd label
2809
        dd label
2821
forward
2810
forward
2822
        label db string, 0
2811
        label db string, 0
2823
}
2812
}
2824
 
2813
 
2825
strtbl link_str, \
2814
strtbl link_str, \
2826
        "No valid link type detected", \
2815
        "No valid link type detected", \
2827
        "10BASE-T half duplex", \
2816
        "10BASE-T half duplex", \
2828
        "10BASE-T full-duplex", \
2817
        "10BASE-T full-duplex", \
2829
        "100BASE-TX half duplex", \
2818
        "100BASE-TX half duplex", \
2830
        "100BASE-TX full duplex", \
2819
        "100BASE-TX full duplex", \
2831
        "100BASE-T4", \
2820
        "100BASE-T4", \
2832
        "100BASE-FX", \
2821
        "100BASE-FX", \
2833
        "10Mbps AUI", \
2822
        "10Mbps AUI", \
2834
        "10Mbps COAX (BNC)", \
2823
        "10Mbps COAX (BNC)", \
2835
        "miiDevice - not supported"
2824
        "miiDevice - not supported"
2836
 
2825
 
2837
strtbl hw_str, \
2826
strtbl hw_str, \
2838
        "3c590 Vortex 10Mbps", \
2827
        "3c590 Vortex 10Mbps", \
2839
        "3c592 EISA 10Mbps Demon/Vortex", \
2828
        "3c592 EISA 10Mbps Demon/Vortex", \
2840
        "3c597 EISA Fast Demon/Vortex", \
2829
        "3c597 EISA Fast Demon/Vortex", \
2841
        "3c595 Vortex 100baseTx", \
2830
        "3c595 Vortex 100baseTx", \
2842
        "3c595 Vortex 100baseT4", \
2831
        "3c595 Vortex 100baseT4", \
2843
        "3c595 Vortex 100base-MII", \
2832
        "3c595 Vortex 100base-MII", \
2844
        "3c900 Boomerang 10baseT", \
2833
        "3c900 Boomerang 10baseT", \
2845
        "3c900 Boomerang 10Mbps Combo", \
2834
        "3c900 Boomerang 10Mbps Combo", \
2846
        "3c900 Cyclone 10Mbps TPO", \
2835
        "3c900 Cyclone 10Mbps TPO", \
2847
        "3c900 Cyclone 10Mbps Combo", \
2836
        "3c900 Cyclone 10Mbps Combo", \
2848
        "3c900 Cyclone 10Mbps TPC", \
2837
        "3c900 Cyclone 10Mbps TPC", \
2849
        "3c900B-FL Cyclone 10base-FL", \
2838
        "3c900B-FL Cyclone 10base-FL", \
2850
        "3c905 Boomerang 100baseTx", \
2839
        "3c905 Boomerang 100baseTx", \
2851
        "3c905 Boomerang 100baseT4", \
2840
        "3c905 Boomerang 100baseT4", \
2852
        "3c905B Cyclone 100baseTx", \
2841
        "3c905B Cyclone 100baseTx", \
2853
        "3c905B Cyclone 10/100/BNC", \
2842
        "3c905B Cyclone 10/100/BNC", \
2854
        "3c905B-FX Cyclone 100baseFx", \
2843
        "3c905B-FX Cyclone 100baseFx", \
2855
        "3c905C Tornado", \
2844
        "3c905C Tornado", \
2856
        "3c980 Cyclone", \
2845
        "3c980 Cyclone", \
2857
        "3c982 Dual Port Server Cyclone", \
2846
        "3c982 Dual Port Server Cyclone", \
2858
        "3cSOHO100-TX Hurricane", \
2847
        "3cSOHO100-TX Hurricane", \
2859
        "3c555 Laptop Hurricane", \
2848
        "3c555 Laptop Hurricane", \
2860
        "3c556 Laptop Tornado", \
2849
        "3c556 Laptop Tornado", \
2861
        "3c556B Laptop Hurricane", \
2850
        "3c556B Laptop Hurricane", \
2862
        "3c575 [Megahertz] 10/100 LAN CardBus", \
2851
        "3c575 [Megahertz] 10/100 LAN CardBus", \
2863
        "3c575 Boomerang CardBus", \
2852
        "3c575 Boomerang CardBus", \
2864
        "3CCFE575BT Cyclone CardBus", \
2853
        "3CCFE575BT Cyclone CardBus", \
2865
        "3CCFE575CT Tornado CardBus", \
2854
        "3CCFE575CT Tornado CardBus", \
2866
        "3CCFE656 Cyclone CardBus", \
2855
        "3CCFE656 Cyclone CardBus", \
2867
        "3CCFEM656B Cyclone+Winmodem CardBus", \
2856
        "3CCFEM656B Cyclone+Winmodem CardBus", \
2868
        "3CXFEM656C Tornado+Winmodem CardBus", \
2857
        "3CXFEM656C Tornado+Winmodem CardBus", \
2869
        "3c450 HomePNA Tornado", \
2858
        "3c450 HomePNA Tornado", \
2870
        "3c920 Tornado", \
2859
        "3c920 Tornado", \
2871
        "3c982 Hydra Dual Port A", \
2860
        "3c982 Hydra Dual Port A", \
2872
        "3c982 Hydra Dual Port B", \
2861
        "3c982 Hydra Dual Port B", \
2873
        "3c905B-T4", \
2862
        "3c905B-T4", \
2874
        "3c920B-EMB-WNM Tornado"
2863
        "3c920B-EMB-WNM Tornado"
2875
 
2864
 
2876
 
2865
 
2877
 
2866
 
2878
align 4
2867
align 4
2879
hw_versions:
2868
hw_versions:
2880
dw 0x5900, IS_VORTEX                                                                                                            ; 3c590 Vortex 10Mbps
2869
dw 0x5900, IS_VORTEX                                                                                                            ; 3c590 Vortex 10Mbps
2881
dw 0x5920, IS_VORTEX                                                                                                            ; 3c592 EISA 10Mbps Demon/Vortex
2870
dw 0x5920, IS_VORTEX                                                                                                            ; 3c592 EISA 10Mbps Demon/Vortex
2882
dw 0x5970, IS_VORTEX                                                                                                            ; 3c597 EISA Fast Demon/Vortex
2871
dw 0x5970, IS_VORTEX                                                                                                            ; 3c597 EISA Fast Demon/Vortex
2883
dw 0x5950, IS_VORTEX                                                                                                            ; 3c595 Vortex 100baseTx
2872
dw 0x5950, IS_VORTEX                                                                                                            ; 3c595 Vortex 100baseTx
2884
dw 0x5951, IS_VORTEX                                                                                                            ; 3c595 Vortex 100baseT4
2873
dw 0x5951, IS_VORTEX                                                                                                            ; 3c595 Vortex 100baseT4
2885
dw 0x5952, IS_VORTEX                                                                                                            ; 3c595 Vortex 100base-MII
2874
dw 0x5952, IS_VORTEX                                                                                                            ; 3c595 Vortex 100base-MII
2886
dw 0x9000, IS_BOOMERANG                                                                                                         ; 3c900 Boomerang 10baseT
2875
dw 0x9000, IS_BOOMERANG                                                                                                         ; 3c900 Boomerang 10baseT
2887
dw 0x9001, IS_BOOMERANG                                                                                                         ; 3c900 Boomerang 10Mbps Combo
2876
dw 0x9001, IS_BOOMERANG                                                                                                         ; 3c900 Boomerang 10Mbps Combo
2888
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c900 Cyclone 10Mbps TPO
2877
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c900 Cyclone 10Mbps TPO
2889
dw 0x9005, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900 Cyclone 10Mbps Combo
2878
dw 0x9005, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900 Cyclone 10Mbps Combo
2890
dw 0x9006, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900 Cyclone 10Mbps TPC
2879
dw 0x9006, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900 Cyclone 10Mbps TPC
2891
dw 0x900A, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900B-FL Cyclone 10base-FL
2880
dw 0x900A, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c900B-FL Cyclone 10base-FL
2892
dw 0x9050, IS_BOOMERANG or HAS_MII                                                                                              ; 3c905 Boomerang 100baseTx
2881
dw 0x9050, IS_BOOMERANG or HAS_MII                                                                                              ; 3c905 Boomerang 100baseTx
2893
dw 0x9051, IS_BOOMERANG or HAS_MII                                                                                              ; 3c905 Boomerang 100baseT4
2882
dw 0x9051, IS_BOOMERANG or HAS_MII                                                                                              ; 3c905 Boomerang 100baseT4
2894
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE                                                               ; 3c905B Cyclone 100baseTx
2883
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE                                                               ; 3c905B Cyclone 100baseTx
2895
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c905B Cyclone 10/100/BNC
2884
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c905B Cyclone 10/100/BNC
2896
dw 0x905A, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c905B-FX Cyclone 100baseFx
2885
dw 0x905A, IS_CYCLONE or HAS_HWCKSM                                                                                             ; 3c905B-FX Cyclone 100baseFx
2897
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c905C Tornado
2886
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c905C Tornado
2898
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c980 Cyclone
2887
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c980 Cyclone
2899
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c982 Dual Port Server Cyclone
2888
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c982 Dual Port Server Cyclone
2900
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3cSOHO100-TX Hurricane
2889
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3cSOHO100-TX Hurricane
2901
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM                                                                              ; 3c555 Laptop Hurricane
2890
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM                                                                              ; 3c555 Laptop Hurricane
2902
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM                                  ; 3c556 Laptop Tornado
2891
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM                                  ; 3c556 Laptop Tornado
2903
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM                                ; 3c556B Laptop Hurricane
2892
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM                                ; 3c556B Laptop Hurricane
2904
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT                                                                               ; 3c575 [Megahertz] 10/100 LAN CardBus
2893
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT                                                                               ; 3c575 [Megahertz] 10/100 LAN CardBus
2905
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT                                                                               ; 3c575 Boomerang CardBus
2894
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT                                                                               ; 3c575 Boomerang CardBus
2906
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_LED_PWR or HAS_HWCKSM                                  ; 3CCFE575BT Cyclone CardBus
2895
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_LED_PWR or HAS_HWCKSM                                  ; 3CCFE575BT Cyclone CardBus
2907
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM           ; 3CCFE575CT Tornado CardBus
2896
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM           ; 3CCFE575CT Tornado CardBus
2908
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM                ; 3CCFE656 Cyclone CardBus
2897
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM                ; 3CCFE656 Cyclone CardBus
2909
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM                ; 3CCFEM656B Cyclone+Winmodem CardBus
2898
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM                ; 3CCFEM656B Cyclone+Winmodem CardBus
2910
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM           ; 3CXFEM656C Tornado+Winmodem CardBus
2899
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM           ; 3CXFEM656C Tornado+Winmodem CardBus
2911
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c450 HomePNA Tornado
2900
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c450 HomePNA Tornado
2912
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920 Tornado
2901
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920 Tornado
2913
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY                                                                                 ; 3c982 Hydra Dual Port A
2902
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY                                                                                 ; 3c982 Hydra Dual Port A
2914
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY                                                                                 ; 3c982 Hydra Dual Port B
2903
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY                                                                                 ; 3c982 Hydra Dual Port B
2915
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE                                                               ; 3c905B-T4
2904
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE                                                               ; 3c905B-T4
2916
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920B-EMB-WNM Tornado
2905
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920B-EMB-WNM Tornado
2917
HW_VERSIONS_SIZE = $ - hw_versions
2906
HW_VERSIONS_SIZE = $ - hw_versions
2918
 
2907
 
2919
include_debug_strings                           ; All data wich FDO uses will be included here
2908
include_debug_strings                           ; All data wich FDO uses will be included here
2920
 
2909
 
2921
align 4
2910
align 4
2922
vortex_devices          dd 0
2911
devices         dd 0
2923
boomerang_devices       dd 0
-
 
2924
vortex_list             rd MAX_DEVICES
2912
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
2925
boomerang_list          rd MAX_DEVICES
-