Subversion Repositories Kolibri OS

Rev

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

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