Subversion Repositories Kolibri OS

Rev

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

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