Subversion Repositories Kolibri OS

Rev

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

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