Subversion Repositories Kolibri OS

Rev

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

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