Subversion Repositories Kolibri OS

Rev

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

Rev 2288 Rev 2455
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2011. 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 2288 $
8
$Revision: 2455 $
9
 
9
 
10
 
10
 
11
;; Copyright (c) 2004, Endre Kozma 
11
;; Copyright (c) 2004, Endre Kozma 
12
;; All rights reserved.
12
;; All rights reserved.
13
;;
13
;;
14
;; Redistribution  and  use  in  source  and  binary  forms, with or without
14
;; Redistribution  and  use  in  source  and  binary  forms, with or without
15
;; modification, are permitted provided  that  the following  conditions are
15
;; modification, are permitted provided  that  the following  conditions are
16
;; met:
16
;; met:
17
;;
17
;;
18
;; 1. Redistributions of source code must retain the above  copyright notice,
18
;; 1. Redistributions of source code must retain the above  copyright notice,
19
;;    this list of conditions and the following disclaimer.
19
;;    this list of conditions and the following disclaimer.
20
;;
20
;;
21
;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
21
;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
22
;;    notice, this  list of conditions  and the  following disclaimer in the
22
;;    notice, this  list of conditions  and the  following disclaimer in the
23
;;    documentation and/or other  materials  provided with  the distribution.
23
;;    documentation and/or other  materials  provided with  the distribution.
24
;;
24
;;
25
;; 3. The name of the author may not be used to  endorse or promote products
25
;; 3. The name of the author may not be used to  endorse or promote products
26
;;    derived from this software without  specific prior  written permission.
26
;;    derived from this software without  specific prior  written permission.
27
;;
27
;;
28
;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
28
;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
29
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30
;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
30
;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
31
;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
31
;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
32
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33
;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33
;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
34
;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
35
;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
35
;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
36
;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
36
;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
37
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
 
38
 
39
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40
;;                                                                         ;;
40
;;                                                                         ;;
41
;;  3C59X.INC                                                              ;;
41
;;  3C59X.INC                                                              ;;
42
;;                                                                         ;;
42
;;                                                                         ;;
43
;;  Ethernet driver for Menuet OS                                          ;;
43
;;  Ethernet driver for Menuet OS                                          ;;
44
;;                                                                         ;;
44
;;                                                                         ;;
45
;;  Driver for 3Com fast etherlink 3c59x and                               ;;
45
;;  Driver for 3Com fast etherlink 3c59x and                               ;;
46
;;         etherlink XL 3c900 and 3c905 cards                              ;;
46
;;         etherlink XL 3c900 and 3c905 cards                              ;;
47
;;  References:                                                            ;;
47
;;  References:                                                            ;;
48
;;    www.3Com.com - data sheets                                           ;;
48
;;    www.3Com.com - data sheets                                           ;;
49
;;    DP83840A.pdf - ethernet physical layer                               ;;
49
;;    DP83840A.pdf - ethernet physical layer                               ;;
50
;;    3c59x.c - linux driver                                               ;;
50
;;    3c59x.c - linux driver                                               ;;
51
;;    ethernet driver template by Mike Hibbett                             ;;
51
;;    ethernet driver template by Mike Hibbett                             ;;
52
;;                                                                         ;;
52
;;                                                                         ;;
53
;;  Credits                                                                ;;
53
;;  Credits                                                                ;;
54
;;   Mike Hibbett,                                                         ;;
54
;;   Mike Hibbett,                                                         ;;
55
;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
55
;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
56
;;                                                                         ;;
56
;;                                                                         ;;
57
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
58
;;  History
58
;;  History
59
;;  =======
59
;;  =======
60
;;  $Log: 3C59X.INC,v $
60
;;  $Log: 3C59X.INC,v $
61
;;  Revision 1.3  2004/07/11 12:21:12  kozma
61
;;  Revision 1.3  2004/07/11 12:21:12  kozma
62
;;  Support of vortex chips (3c59x) added.
62
;;  Support of vortex chips (3c59x) added.
63
;;  Support of 3c920 and 3c982 added.
63
;;  Support of 3c920 and 3c982 added.
64
;;  Corrections.
64
;;  Corrections.
65
;;
65
;;
66
;;  Revision 1.2  2004/06/12 19:40:20  kozma
66
;;  Revision 1.2  2004/06/12 19:40:20  kozma
67
;;  Function e3c59x_set_available_media added in order to set
67
;;  Function e3c59x_set_available_media added in order to set
68
;;  the default media in case auto detection finds no valid link.
68
;;  the default media in case auto detection finds no valid link.
69
;;  Incorrect mii check removed (3c900 Cyclone works now).
69
;;  Incorrect mii check removed (3c900 Cyclone works now).
70
;;  Cleanups.
70
;;  Cleanups.
71
;;
71
;;
72
;;  Revision 1.1  2004/06/12 18:27:15  kozma
72
;;  Revision 1.1  2004/06/12 18:27:15  kozma
73
;;  Initial revision
73
;;  Initial revision
74
;;
74
;;
75
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
75
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
76
 
76
 
77
; comment the next line out if you don't want debug info printed
77
; comment the next line out if you don't want debug info printed
78
; on the debug board. This option adds a lot of bytes to the driver
78
; on the debug board. This option adds a lot of bytes to the driver
79
; so it's worth to comment it out.
79
; so it's worth to comment it out.
80
;        E3C59X_DEBUG    equ 1
80
;        E3C59X_DEBUG    equ 1
81
 
81
 
82
; forcing full duplex mode makes sense at some cards and link types
82
; forcing full duplex mode makes sense at some cards and link types
83
        E3C59X_FORCE_FD equ 1
83
        E3C59X_FORCE_FD equ 1
84
 
84
 
85
macro virt_to_dma reg
85
macro virt_to_dma reg
86
{
86
{
87
        sub     reg, OS_BASE
87
        sub     reg, OS_BASE
88
}
88
}
89
 
89
 
90
macro dma_to_virt reg
90
macro dma_to_virt reg
91
{
91
{
92
        add     reg, OS_BASE
92
        add     reg, OS_BASE
93
}
93
}
94
 
94
 
95
macro zero_to_virt reg
95
macro zero_to_virt reg
96
{
96
{
97
 
97
 
98
}
98
}
99
 
99
 
100
macro virt_to_zero reg
100
macro virt_to_zero reg
101
{
101
{
102
 
102
 
103
}
103
}
104
 
104
 
105
macro zero_to_dma reg
105
macro zero_to_dma reg
106
{
106
{
107
        sub     reg, OS_BASE
107
        sub     reg, OS_BASE
108
}
108
}
109
 
109
 
110
macro dma_to_zero reg
110
macro dma_to_zero reg
111
{
111
{
112
        add     reg, OS_BASE
112
        add     reg, OS_BASE
113
}
113
}
114
 
114
 
115
macro strtbl name, [string]
115
macro strtbl name, [string]
116
{
116
{
117
common
117
common
118
        label name dword
118
        label name dword
119
forward
119
forward
120
        local label
120
        local label
121
        dd label
121
        dd label
122
forward
122
forward
123
        label db string, 0
123
        label db string, 0
124
}
124
}
125
 
125
 
126
; Ethernet frame symbols
126
; Ethernet frame symbols
127
        ETH_ALEN                       equ 6
127
        ETH_ALEN                       equ 6
128
        ETH_HLEN                       equ (2*ETH_ALEN+2)
128
        ETH_HLEN                       equ (2*ETH_ALEN+2)
129
        ETH_ZLEN                       equ 60 ; 60 + 4bytes auto payload for
129
        ETH_ZLEN                       equ 60 ; 60 + 4bytes auto payload for
130
                                              ; mininmum 64bytes frame length
130
                                              ; mininmum 64bytes frame length
131
; PCI programming
131
; PCI programming
132
        PCI_REG_COMMAND                equ 0x4 ; command register
132
        PCI_REG_COMMAND                equ 0x4 ; command register
133
        PCI_REG_STATUS                 equ 0x6 ; status register
133
        PCI_REG_STATUS                 equ 0x6 ; status register
134
        PCI_REG_LATENCY                equ 0xd ; latency timer register
134
        PCI_REG_LATENCY                equ 0xd ; latency timer register
135
        PCI_REG_CAP_PTR                equ 0x34 ; capabilities pointer
135
        PCI_REG_CAP_PTR                equ 0x34 ; capabilities pointer
136
        PCI_REG_CAPABILITY_ID          equ 0x0 ; capapility ID in pm register block
136
        PCI_REG_CAPABILITY_ID          equ 0x0 ; capapility ID in pm register block
137
        PCI_REG_PM_STATUS              equ 0x4 ; power management status register
137
        PCI_REG_PM_STATUS              equ 0x4 ; power management status register
138
        PCI_REG_PM_CTRL                equ 0x4 ; power management control register
138
        PCI_REG_PM_CTRL                equ 0x4 ; power management control register
139
        PCI_BIT_PIO                    equ 0 ; bit0: io space control
139
        PCI_BIT_PIO                    equ 0 ; bit0: io space control
140
        PCI_BIT_MMIO                   equ 1 ; bit1: memory space control
140
        PCI_BIT_MMIO                   equ 1 ; bit1: memory space control
141
        PCI_BIT_MASTER                 equ 2 ; bit2: device acts as a PCI master
141
        PCI_BIT_MASTER                 equ 2 ; bit2: device acts as a PCI master
142
; Registers
142
; Registers
143
        E3C59X_REG_POWER_MGMT_CTRL     equ 0x7c
143
        E3C59X_REG_POWER_MGMT_CTRL     equ 0x7c
144
        E3C59X_REG_UP_LIST_PTR         equ 0x38
144
        E3C59X_REG_UP_LIST_PTR         equ 0x38
145
        E3C59X_REG_UP_PKT_STATUS       equ 0x30
145
        E3C59X_REG_UP_PKT_STATUS       equ 0x30
146
        E3C59X_REG_TX_FREE_THRESH      equ 0x2f
146
        E3C59X_REG_TX_FREE_THRESH      equ 0x2f
147
        E3C59X_REG_DN_LIST_PTR         equ 0x24
147
        E3C59X_REG_DN_LIST_PTR         equ 0x24
148
        E3C59X_REG_DMA_CTRL            equ 0x20
148
        E3C59X_REG_DMA_CTRL            equ 0x20
149
        E3C59X_REG_TX_STATUS           equ 0x1b
149
        E3C59X_REG_TX_STATUS           equ 0x1b
150
        E3C59X_REG_RX_STATUS           equ 0x18
150
        E3C59X_REG_RX_STATUS           equ 0x18
151
        E3C59X_REG_TX_DATA             equ 0x10
151
        E3C59X_REG_TX_DATA             equ 0x10
152
; Common window registers
152
; Common window registers
153
        E3C59X_REG_INT_STATUS          equ 0xe
153
        E3C59X_REG_INT_STATUS          equ 0xe
154
        E3C59X_REG_COMMAND             equ 0xe
154
        E3C59X_REG_COMMAND             equ 0xe
155
; Register window 7
155
; Register window 7
156
        E3C59X_REG_MASTER_STATUS       equ 0xc
156
        E3C59X_REG_MASTER_STATUS       equ 0xc
157
        E3C59X_REG_POWER_MGMT_EVENT    equ 0xc
157
        E3C59X_REG_POWER_MGMT_EVENT    equ 0xc
158
        E3C59X_REG_MASTER_LEN          equ 0x6
158
        E3C59X_REG_MASTER_LEN          equ 0x6
159
        E3C59X_REG_VLAN_ETHER_TYPE     equ 0x4
159
        E3C59X_REG_VLAN_ETHER_TYPE     equ 0x4
160
        E3C59X_REG_VLAN_MASK           equ 0x0
160
        E3C59X_REG_VLAN_MASK           equ 0x0
161
        E3C59X_REG_MASTER_ADDRESS      equ 0x0
161
        E3C59X_REG_MASTER_ADDRESS      equ 0x0
162
; Register window 6
162
; Register window 6
163
        E3C59X_REG_BYTES_XMITTED_OK    equ 0xc
163
        E3C59X_REG_BYTES_XMITTED_OK    equ 0xc
164
        E3C59X_REG_BYTES_RCVD_OK       equ 0xa
164
        E3C59X_REG_BYTES_RCVD_OK       equ 0xa
165
        E3C59X_REG_UPPER_FRAMES_OK     equ 0x9
165
        E3C59X_REG_UPPER_FRAMES_OK     equ 0x9
166
        E3C59X_REG_FRAMES_DEFERRED     equ 0x8
166
        E3C59X_REG_FRAMES_DEFERRED     equ 0x8
167
        E3C59X_REG_FRAMES_RCVD_OK      equ 0x7
167
        E3C59X_REG_FRAMES_RCVD_OK      equ 0x7
168
        E3C59X_REG_FRAMES_XMITTED_OK   equ 0x6
168
        E3C59X_REG_FRAMES_XMITTED_OK   equ 0x6
169
        E3C59X_REG_RX_OVERRUNS         equ 0x5
169
        E3C59X_REG_RX_OVERRUNS         equ 0x5
170
        E3C59X_REG_LATE_COLLISIONS     equ 0x4
170
        E3C59X_REG_LATE_COLLISIONS     equ 0x4
171
        E3C59X_REG_SINGLE_COLLISIONS   equ 0x3
171
        E3C59X_REG_SINGLE_COLLISIONS   equ 0x3
172
        E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2
172
        E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2
173
        E3C59X_REG_SQE_ERRORS          equ 0x1
173
        E3C59X_REG_SQE_ERRORS          equ 0x1
174
        E3C59X_REG_CARRIER_LOST        equ 0x0
174
        E3C59X_REG_CARRIER_LOST        equ 0x0
175
; Register window 5
175
; Register window 5
176
        E3C59X_REG_INDICATION_ENABLE   equ 0xc
176
        E3C59X_REG_INDICATION_ENABLE   equ 0xc
177
        E3C59X_REG_INTERRUPT_ENABLE    equ 0xa
177
        E3C59X_REG_INTERRUPT_ENABLE    equ 0xa
178
        E3C59X_REG_TX_RECLAIM_THRESH   equ 0x9
178
        E3C59X_REG_TX_RECLAIM_THRESH   equ 0x9
179
        E3C59X_REG_RX_FILTER           equ 0x8
179
        E3C59X_REG_RX_FILTER           equ 0x8
180
        E3C59X_REG_RX_EARLY_THRESH     equ 0x6
180
        E3C59X_REG_RX_EARLY_THRESH     equ 0x6
181
        E3C59X_REG_TX_START_THRESH     equ 0x0
181
        E3C59X_REG_TX_START_THRESH     equ 0x0
182
; Register window 4
182
; Register window 4
183
        E3C59X_REG_UPPER_BYTES_OK      equ 0xe
183
        E3C59X_REG_UPPER_BYTES_OK      equ 0xe
184
        E3C59X_REG_BAD_SSD             equ 0xc
184
        E3C59X_REG_BAD_SSD             equ 0xc
185
        E3C59X_REG_MEDIA_STATUS        equ 0xa
185
        E3C59X_REG_MEDIA_STATUS        equ 0xa
186
        E3C59X_REG_PHYSICAL_MGMT       equ 0x8
186
        E3C59X_REG_PHYSICAL_MGMT       equ 0x8
187
        E3C59X_REG_NETWORK_DIAGNOSTIC  equ 0x6
187
        E3C59X_REG_NETWORK_DIAGNOSTIC  equ 0x6
188
        E3C59X_REG_FIFO_DIAGNOSTIC     equ 0x4
188
        E3C59X_REG_FIFO_DIAGNOSTIC     equ 0x4
189
        E3C59X_REG_VCO_DIAGNOSTIC      equ 0x2 ; may not supported
189
        E3C59X_REG_VCO_DIAGNOSTIC      equ 0x2 ; may not supported
190
; Bits in register window 4
190
; Bits in register window 4
191
        E3C59X_BIT_AUTOSELECT          equ 24
191
        E3C59X_BIT_AUTOSELECT          equ 24
192
; Register window 3
192
; Register window 3
193
        E3C59X_REG_TX_FREE             equ 0xc
193
        E3C59X_REG_TX_FREE             equ 0xc
194
        E3C59X_REG_RX_FREE             equ 0xa
194
        E3C59X_REG_RX_FREE             equ 0xa
195
        E3C59X_REG_MEDIA_OPTIONS       equ 0x8
195
        E3C59X_REG_MEDIA_OPTIONS       equ 0x8
196
        E3C59X_REG_MAC_CONTROL         equ 0x6
196
        E3C59X_REG_MAC_CONTROL         equ 0x6
197
        E3C59X_REG_MAX_PKT_SIZE        equ 0x4
197
        E3C59X_REG_MAX_PKT_SIZE        equ 0x4
198
        E3C59X_REG_INTERNAL_CONFIG     equ 0x0
198
        E3C59X_REG_INTERNAL_CONFIG     equ 0x0
199
; Register window 2
199
; Register window 2
200
        E3C59X_REG_RESET_OPTIONS       equ 0xc
200
        E3C59X_REG_RESET_OPTIONS       equ 0xc
201
        E3C59X_REG_STATION_MASK_HI     equ 0xa
201
        E3C59X_REG_STATION_MASK_HI     equ 0xa
202
        E3C59X_REG_STATION_MASK_MID    equ 0x8
202
        E3C59X_REG_STATION_MASK_MID    equ 0x8
203
        E3C59X_REG_STATION_MASK_LO     equ 0x6
203
        E3C59X_REG_STATION_MASK_LO     equ 0x6
204
        E3C59X_REG_STATION_ADDRESS_HI  equ 0x4
204
        E3C59X_REG_STATION_ADDRESS_HI  equ 0x4
205
        E3C59X_REG_STATION_ADDRESS_MID equ 0x2
205
        E3C59X_REG_STATION_ADDRESS_MID equ 0x2
206
        E3C59X_REG_STATION_ADDRESS_LO  equ 0x0
206
        E3C59X_REG_STATION_ADDRESS_LO  equ 0x0
207
; Register window 1
207
; Register window 1
208
        E3C59X_REG_TRIGGER_BITS        equ 0xc
208
        E3C59X_REG_TRIGGER_BITS        equ 0xc
209
        E3C59X_REG_SOS_BITS            equ 0xa
209
        E3C59X_REG_SOS_BITS            equ 0xa
210
        E3C59X_REG_WAKE_ON_TIMER       equ 0x8
210
        E3C59X_REG_WAKE_ON_TIMER       equ 0x8
211
        E3C59X_REG_SMB_RXBYTES         equ 0x7
211
        E3C59X_REG_SMB_RXBYTES         equ 0x7
212
        E3C59X_REG_SMB_DIAG            equ 0x5
212
        E3C59X_REG_SMB_DIAG            equ 0x5
213
        E3C59X_REG_SMB_ARB             equ 0x4
213
        E3C59X_REG_SMB_ARB             equ 0x4
214
        E3C59X_REG_SMB_STATUS          equ 0x2
214
        E3C59X_REG_SMB_STATUS          equ 0x2
215
        E3C59X_REG_SMB_ADDRESS         equ 0x1
215
        E3C59X_REG_SMB_ADDRESS         equ 0x1
216
        E3C59X_REG_SMB_FIFO_DATA       equ 0x0
216
        E3C59X_REG_SMB_FIFO_DATA       equ 0x0
217
; Register window 0
217
; Register window 0
218
        E3C59X_REG_EEPROM_DATA         equ 0xc
218
        E3C59X_REG_EEPROM_DATA         equ 0xc
219
        E3C59X_REG_EEPROM_COMMAND      equ 0xa
219
        E3C59X_REG_EEPROM_COMMAND      equ 0xa
220
        E3C59X_REG_BIOS_ROM_DATA       equ 0x8
220
        E3C59X_REG_BIOS_ROM_DATA       equ 0x8
221
        E3C59X_REG_BIOS_ROM_ADDR       equ 0x4
221
        E3C59X_REG_BIOS_ROM_ADDR       equ 0x4
222
; Physical management bits
222
; Physical management bits
223
        E3C59X_BIT_MGMT_DIR            equ 2 ; drive with the data written in mgmtData
223
        E3C59X_BIT_MGMT_DIR            equ 2 ; drive with the data written in mgmtData
224
        E3C59X_BIT_MGMT_DATA           equ 1 ; MII management data bit
224
        E3C59X_BIT_MGMT_DATA           equ 1 ; MII management data bit
225
        E3C59X_BIT_MGMT_CLK            equ 0 ; MII management clock
225
        E3C59X_BIT_MGMT_CLK            equ 0 ; MII management clock
226
; MII commands
226
; MII commands
227
        E3C59X_MII_CMD_MASK            equ (1111b shl 10)
227
        E3C59X_MII_CMD_MASK            equ (1111b shl 10)
228
        E3C59X_MII_CMD_READ            equ (0110b shl 10)
228
        E3C59X_MII_CMD_READ            equ (0110b shl 10)
229
        E3C59X_MII_CMD_WRITE           equ (0101b shl 10)
229
        E3C59X_MII_CMD_WRITE           equ (0101b shl 10)
230
; MII registers
230
; MII registers
231
        E3C59X_REG_MII_BMCR            equ 0 ; basic mode control register
231
        E3C59X_REG_MII_BMCR            equ 0 ; basic mode control register
232
        E3C59X_REG_MII_BMSR            equ 1 ; basic mode status register
232
        E3C59X_REG_MII_BMSR            equ 1 ; basic mode status register
233
        E3C59X_REG_MII_ANAR            equ 4 ; auto negotiation advertisement register
233
        E3C59X_REG_MII_ANAR            equ 4 ; auto negotiation advertisement register
234
        E3C59X_REG_MII_ANLPAR          equ 5 ; auto negotiation link partner ability register
234
        E3C59X_REG_MII_ANLPAR          equ 5 ; auto negotiation link partner ability register
235
        E3C59X_REG_MII_ANER            equ 6 ; auto negotiation expansion register
235
        E3C59X_REG_MII_ANER            equ 6 ; auto negotiation expansion register
236
; MII bits
236
; MII bits
237
        E3C59X_BIT_MII_AUTONEG_COMPLETE     equ 5 ; auto-negotiation complete
237
        E3C59X_BIT_MII_AUTONEG_COMPLETE     equ 5 ; auto-negotiation complete
238
        E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6
238
        E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6
239
; eeprom bits and commands
239
; eeprom bits and commands
240
        E3C59X_EEPROM_CMD_READ         equ 0x80
240
        E3C59X_EEPROM_CMD_READ         equ 0x80
241
        E3C59X_EEPROM_BIT_BUSY         equ 15
241
        E3C59X_EEPROM_BIT_BUSY         equ 15
242
; eeprom registers
242
; eeprom registers
243
        E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa
243
        E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa
244
        E3C59X_EEPROM_REG_CAPABILITIES  equ 0x10
244
        E3C59X_EEPROM_REG_CAPABILITIES  equ 0x10
245
; Commands for command register
245
; Commands for command register
246
        E3C59X_SELECT_REGISTER_WINDOW  equ (1 shl 11)
246
        E3C59X_SELECT_REGISTER_WINDOW  equ (1 shl 11)
247
 
247
 
248
        IS_VORTEX                      equ 0x1
248
        IS_VORTEX                      equ 0x1
249
        IS_BOOMERANG                   equ 0x2
249
        IS_BOOMERANG                   equ 0x2
250
        IS_CYCLONE                     equ 0x4
250
        IS_CYCLONE                     equ 0x4
251
        IS_TORNADO                     equ 0x8
251
        IS_TORNADO                     equ 0x8
252
        EEPROM_8BIT                    equ 0x10
252
        EEPROM_8BIT                    equ 0x10
253
        HAS_PWR_CTRL                   equ 0x20
253
        HAS_PWR_CTRL                   equ 0x20
254
        HAS_MII                        equ 0x40
254
        HAS_MII                        equ 0x40
255
        HAS_NWAY                       equ 0x80
255
        HAS_NWAY                       equ 0x80
256
        HAS_CB_FNS                     equ 0x100
256
        HAS_CB_FNS                     equ 0x100
257
        INVERT_MII_PWR                 equ 0x200
257
        INVERT_MII_PWR                 equ 0x200
258
        INVERT_LED_PWR                 equ 0x400
258
        INVERT_LED_PWR                 equ 0x400
259
        MAX_COLLISION_RESET            equ 0x800
259
        MAX_COLLISION_RESET            equ 0x800
260
        EEPROM_OFFSET                  equ 0x1000
260
        EEPROM_OFFSET                  equ 0x1000
261
        HAS_HWCKSM                     equ 0x2000
261
        HAS_HWCKSM                     equ 0x2000
262
        EXTRA_PREAMBLE                 equ 0x4000
262
        EXTRA_PREAMBLE                 equ 0x4000
263
 
263
 
264
iglobal
264
iglobal
265
        align 4
265
        align 4
266
e3c59x_hw_versions:
266
e3c59x_hw_versions:
267
        dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps
267
        dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps
268
        dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex
268
        dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex
269
        dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex
269
        dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex
270
        dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx
270
        dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx
271
        dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4
271
        dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4
272
        dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII
272
        dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII
273
        dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT
273
        dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT
274
        dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo
274
        dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo
275
        dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO
275
        dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO
276
        dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo
276
        dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo
277
        dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC
277
        dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC
278
        dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL
278
        dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL
279
        dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx
279
        dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx
280
        dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4
280
        dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4
281
        dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx
281
        dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx
282
        dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC
282
        dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC
283
        dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx
283
        dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx
284
        dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado
284
        dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado
285
        dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone
285
        dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone
286
        dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone
286
        dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone
287
        dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane
287
        dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane
288
        dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane
288
        dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane
289
        dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \
289
        dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \
290
        or      INVERT_MII_PWR or HAS_HWCKSM                  ; 3c556 Laptop Tornado
290
        or      INVERT_MII_PWR or HAS_HWCKSM                  ; 3c556 Laptop Tornado
291
        dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \
291
        dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \
292
        or      INVERT_MII_PWR or HAS_HWCKSM                  ; 3c556B Laptop Hurricane
292
        or      INVERT_MII_PWR or HAS_HWCKSM                  ; 3c556B Laptop Hurricane
293
        dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus
293
        dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus
294
        dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus
294
        dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus
295
        dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \
295
        dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \
296
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFE575BT Cyclone CardBus
296
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFE575BT Cyclone CardBus
297
        dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
297
        dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
298
        or      MAX_COLLISION_RESET or HAS_HWCKSM                  ; 3CCFE575CT Tornado CardBus
298
        or      MAX_COLLISION_RESET or HAS_HWCKSM                  ; 3CCFE575CT Tornado CardBus
299
        dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
299
        dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
300
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFE656 Cyclone CardBus
300
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFE656 Cyclone CardBus
301
        dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
301
        dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
302
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFEM656B Cyclone+Winmodem CardBus
302
        or      INVERT_LED_PWR or HAS_HWCKSM                  ; 3CCFEM656B Cyclone+Winmodem CardBus
303
        dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
303
        dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
304
        or      MAX_COLLISION_RESET or HAS_HWCKSM                  ; 3CXFEM656C Tornado+Winmodem CardBus
304
        or      MAX_COLLISION_RESET or HAS_HWCKSM                  ; 3CXFEM656C Tornado+Winmodem CardBus
305
        dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado
305
        dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado
306
        dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado
306
        dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado
307
        dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A
307
        dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A
308
        dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B
308
        dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B
309
        dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4
309
        dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4
310
        dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado
310
        dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado
311
E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions
311
E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions
312
endg
312
endg
313
 
313
 
314
; RX/TX buffers sizes
314
; RX/TX buffers sizes
315
        E3C59X_MAX_ETH_PKT_SIZE      equ 1536 ; max packet size
315
        E3C59X_MAX_ETH_PKT_SIZE      equ 1536 ; max packet size
316
        E3C59X_NUM_RX_DESC           equ 4 ; a power of 2 number
316
        E3C59X_NUM_RX_DESC           equ 4 ; a power of 2 number
317
        E3C59X_NUM_TX_DESC           equ 4 ; a power of 2 number
317
        E3C59X_NUM_TX_DESC           equ 4 ; a power of 2 number
318
        E3C59X_RX_BUFFER_SIZE        equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC)
318
        E3C59X_RX_BUFFER_SIZE        equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC)
319
        E3C59X_TX_BUFFER_SIZE        equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC)
319
        E3C59X_TX_BUFFER_SIZE        equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC)
320
; Download Packet Descriptor
320
; Download Packet Descriptor
321
        E3C59X_DPD_DN_NEXT_PTR       equ 0
321
        E3C59X_DPD_DN_NEXT_PTR       equ 0
322
        E3C59X_DPD_FRAME_START_HDR   equ 4
322
        E3C59X_DPD_FRAME_START_HDR   equ 4
323
        E3C59X_DPD_DN_FRAG_ADDR      equ 8 ; for packet data
323
        E3C59X_DPD_DN_FRAG_ADDR      equ 8 ; for packet data
324
        E3C59X_DPD_DN_FRAG_LEN       equ 12 ; for packet data
324
        E3C59X_DPD_DN_FRAG_LEN       equ 12 ; for packet data
325
        E3C59X_DPD_SIZE              equ 16 ; a power of 2 number
325
        E3C59X_DPD_SIZE              equ 16 ; a power of 2 number
326
; Upload Packet Descriptor
326
; Upload Packet Descriptor
327
        E3C59X_UPD_UP_NEXT_PTR       equ 0
327
        E3C59X_UPD_UP_NEXT_PTR       equ 0
328
        E3C59X_UPD_PKT_STATUS        equ 4
328
        E3C59X_UPD_PKT_STATUS        equ 4
329
        E3C59X_UPD_UP_FRAG_ADDR      equ 8 ; for packet data
329
        E3C59X_UPD_UP_FRAG_ADDR      equ 8 ; for packet data
330
        E3C59X_UPD_UP_FRAG_LEN       equ 12 ; for packet data
330
        E3C59X_UPD_UP_FRAG_LEN       equ 12 ; for packet data
331
        E3C59X_UPD_SIZE              equ 16
331
        E3C59X_UPD_SIZE              equ 16
332
 
332
 
333
; RX/TX buffers
333
; RX/TX buffers
334
if defined E3C59X_LINUX
334
if defined E3C59X_LINUX
335
        E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment
335
        E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment
336
        e3c59x_rx_buff = 0
336
        e3c59x_rx_buff = 0
337
else
337
else
338
        E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment
338
        E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment
339
        e3c59x_rx_buff = eth_data_start
339
        e3c59x_rx_buff = eth_data_start
340
end if
340
end if
341
 
341
 
342
        e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE
342
        e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE
343
        e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE
343
        e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE
344
        e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC)
344
        e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC)
345
 
345
 
346
uglobal
346
uglobal
347
e3c59x_curr_upd:
347
e3c59x_curr_upd:
348
                 dd 0
348
                 dd 0
349
e3c59x_prev_dpd:
349
e3c59x_prev_dpd:
350
                 dd 0
350
                 dd 0
351
e3c59x_prev_tx_frame:
351
e3c59x_prev_tx_frame:
352
                      dd 0
352
                      dd 0
353
e3c59x_transmit_function:
353
e3c59x_transmit_function:
354
                          dd 0
354
                          dd 0
355
e3c59x_receive_function:
355
e3c59x_receive_function:
356
                         dd 0
356
                         dd 0
357
endg
357
endg
358
 
358
 
359
iglobal
359
iglobal
360
e3c59x_ver_id:
360
e3c59x_ver_id:
361
               db 17
361
               db 17
362
endg
362
endg
363
 
363
 
364
uglobal
364
uglobal
365
e3c59x_full_bus_master:
365
e3c59x_full_bus_master:
366
                        db 0
366
                        db 0
367
e3c59x_has_hwcksm:
367
e3c59x_has_hwcksm:
368
                    db 0
368
                    db 0
369
e3c59x_preamble:
369
e3c59x_preamble:
370
                 db 0
370
                 db 0
371
e3c59x_dn_list_ptr_cleared:
371
e3c59x_dn_list_ptr_cleared:
372
                            db 0
372
                            db 0
373
e3c59x_self_directed_packet:
373
e3c59x_self_directed_packet:
374
                             rb 6
374
                             rb 6
375
endg
375
endg
376
 
376
 
377
if defined E3C59X_DEBUG
377
if defined E3C59X_DEBUG
378
e3c59x_hw_type_str:
378
e3c59x_hw_type_str:
379
                    db "Detected hardware type  : ", 0
379
                    db "Detected hardware type  : ", 0
380
e3c59x_device_str:
380
e3c59x_device_str:
381
                   db  "Device ID               : 0x"
381
                   db  "Device ID               : 0x"
382
e3c59x_device_id_str:
382
e3c59x_device_id_str:
383
                      db "ffff", 13, 10, 0
383
                      db "ffff", 13, 10, 0
384
e3c59x_vendor_str:
384
e3c59x_vendor_str:
385
                   db  "Vendor ID               : 0x"
385
                   db  "Vendor ID               : 0x"
386
e3c59x_vendor_id_str:
386
e3c59x_vendor_id_str:
387
                      db "ffff", 13, 10, 0
387
                      db "ffff", 13, 10, 0
388
e3c59x_io_info_str:
388
e3c59x_io_info_str:
389
                    db "IO address              : 0x"
389
                    db "IO address              : 0x"
390
e3c59x_io_addr_str:
390
e3c59x_io_addr_str:
391
                    db "ffff", 13, 10, 0
391
                    db "ffff", 13, 10, 0
392
e3c59x_mac_info_str:
392
e3c59x_mac_info_str:
393
                     db "MAC address             : "
393
                     db "MAC address             : "
394
e3c59x_mac_addr_str:
394
e3c59x_mac_addr_str:
395
                     db "ff:ff:ff:ff:ff:ff", 13, 10, 0
395
                     db "ff:ff:ff:ff:ff:ff", 13, 10, 0
396
e3c59x_boomerang_str:
396
e3c59x_boomerang_str:
397
                      db " (boomerang)", 13, 10, 0
397
                      db " (boomerang)", 13, 10, 0
398
e3c59x_vortex_str:
398
e3c59x_vortex_str:
399
                   db " (vortex)", 13, 10, 0
399
                   db " (vortex)", 13, 10, 0
400
e3c59x_link_type_str:
400
e3c59x_link_type_str:
401
                      db "Established link type   : ", 0
401
                      db "Established link type   : ", 0
402
e3c59x_new_line_str:
402
e3c59x_new_line_str:
403
                     db 13, 10, 0
403
                     db 13, 10, 0
404
e3c59x_link_type:
404
e3c59x_link_type:
405
                  dd 0
405
                  dd 0
406
 
406
 
407
e3c59x_charset:
407
e3c59x_charset:
408
                db '0123456789abcdef'
408
                db '0123456789abcdef'
409
 
409
 
410
strtbl e3c59x_link_str, \
410
strtbl e3c59x_link_str, \
411
        "No valid link type detected", \
411
        "No valid link type detected", \
412
        "10BASE-T half duplex", \
412
        "10BASE-T half duplex", \
413
        "10BASE-T full-duplex", \
413
        "10BASE-T full-duplex", \
414
        "100BASE-TX half duplex", \
414
        "100BASE-TX half duplex", \
415
        "100BASE-TX full duplex", \
415
        "100BASE-TX full duplex", \
416
        "100BASE-T4", \
416
        "100BASE-T4", \
417
        "100BASE-FX", \
417
        "100BASE-FX", \
418
        "10Mbps AUI", \
418
        "10Mbps AUI", \
419
        "10Mbps COAX (BNC)", \
419
        "10Mbps COAX (BNC)", \
420
        "miiDevice - not supported"
420
        "miiDevice - not supported"
421
 
421
 
422
strtbl e3c59x_hw_str, \
422
strtbl e3c59x_hw_str, \
423
        "3c590 Vortex 10Mbps", \
423
        "3c590 Vortex 10Mbps", \
424
        "3c592 EISA 10Mbps Demon/Vortex", \
424
        "3c592 EISA 10Mbps Demon/Vortex", \
425
        "3c597 EISA Fast Demon/Vortex", \
425
        "3c597 EISA Fast Demon/Vortex", \
426
        "3c595 Vortex 100baseTx", \
426
        "3c595 Vortex 100baseTx", \
427
        "3c595 Vortex 100baseT4", \
427
        "3c595 Vortex 100baseT4", \
428
        "3c595 Vortex 100base-MII", \
428
        "3c595 Vortex 100base-MII", \
429
        "3c900 Boomerang 10baseT", \
429
        "3c900 Boomerang 10baseT", \
430
        "3c900 Boomerang 10Mbps Combo", \
430
        "3c900 Boomerang 10Mbps Combo", \
431
        "3c900 Cyclone 10Mbps TPO", \
431
        "3c900 Cyclone 10Mbps TPO", \
432
        "3c900 Cyclone 10Mbps Combo", \
432
        "3c900 Cyclone 10Mbps Combo", \
433
        "3c900 Cyclone 10Mbps TPC", \
433
        "3c900 Cyclone 10Mbps TPC", \
434
        "3c900B-FL Cyclone 10base-FL", \
434
        "3c900B-FL Cyclone 10base-FL", \
435
        "3c905 Boomerang 100baseTx", \
435
        "3c905 Boomerang 100baseTx", \
436
        "3c905 Boomerang 100baseT4", \
436
        "3c905 Boomerang 100baseT4", \
437
        "3c905B Cyclone 100baseTx", \
437
        "3c905B Cyclone 100baseTx", \
438
        "3c905B Cyclone 10/100/BNC", \
438
        "3c905B Cyclone 10/100/BNC", \
439
        "3c905B-FX Cyclone 100baseFx", \
439
        "3c905B-FX Cyclone 100baseFx", \
440
        "3c905C Tornado", \
440
        "3c905C Tornado", \
441
        "3c980 Cyclone", \
441
        "3c980 Cyclone", \
442
        "3c982 Dual Port Server Cyclone", \
442
        "3c982 Dual Port Server Cyclone", \
443
        "3cSOHO100-TX Hurricane", \
443
        "3cSOHO100-TX Hurricane", \
444
        "3c555 Laptop Hurricane", \
444
        "3c555 Laptop Hurricane", \
445
        "3c556 Laptop Tornado", \
445
        "3c556 Laptop Tornado", \
446
        "3c556B Laptop Hurricane", \
446
        "3c556B Laptop Hurricane", \
447
        "3c575 [Megahertz] 10/100 LAN CardBus", \
447
        "3c575 [Megahertz] 10/100 LAN CardBus", \
448
        "3c575 Boomerang CardBus", \
448
        "3c575 Boomerang CardBus", \
449
        "3CCFE575BT Cyclone CardBus", \
449
        "3CCFE575BT Cyclone CardBus", \
450
        "3CCFE575CT Tornado CardBus", \
450
        "3CCFE575CT Tornado CardBus", \
451
        "3CCFE656 Cyclone CardBus", \
451
        "3CCFE656 Cyclone CardBus", \
452
        "3CCFEM656B Cyclone+Winmodem CardBus", \
452
        "3CCFEM656B Cyclone+Winmodem CardBus", \
453
        "3CXFEM656C Tornado+Winmodem CardBus", \
453
        "3CXFEM656C Tornado+Winmodem CardBus", \
454
        "3c450 HomePNA Tornado", \
454
        "3c450 HomePNA Tornado", \
455
        "3c920 Tornado", \
455
        "3c920 Tornado", \
456
        "3c982 Hydra Dual Port A", \
456
        "3c982 Hydra Dual Port A", \
457
        "3c982 Hydra Dual Port B", \
457
        "3c982 Hydra Dual Port B", \
458
        "3c905B-T4", \
458
        "3c905B-T4", \
459
        "3c920B-EMB-WNM Tornado"
459
        "3c920B-EMB-WNM Tornado"
460
 
460
 
461
end if ; defined E3C59X_DEBUG
461
end if ; defined E3C59X_DEBUG
462
 
462
 
463
;***************************************************************************
463
;***************************************************************************
464
;   Function
464
;   Function
465
;      e3c59x_debug
465
;      e3c59x_debug
466
;   Description
466
;   Description
467
;      prints debug info to the debug board
467
;      prints debug info to the debug board
468
;   Parameters
468
;   Parameters
469
;      ebp - io_addr
469
;      ebp - io_addr
470
;   Return value
470
;   Return value
471
;   Destroyed registers
471
;   Destroyed registers
472
;      eax, ebx, ecx, edx, edi, esi
472
;      eax, ebx, ecx, edx, edi, esi
473
;
473
;
474
;***************************************************************************
474
;***************************************************************************
475
if defined E3C59X_DEBUG
475
if defined E3C59X_DEBUG
476
        align 4
476
        align 4
477
e3c59x_debug:
477
e3c59x_debug:
478
        pushad
478
        pushad
479
; print device type
479
; print device type
480
        mov     esi, e3c59x_hw_type_str
480
        mov     esi, e3c59x_hw_type_str
481
        call    sys_msg_board_str
481
        call    sys_msg_board_str
482
        movzx   ecx, byte [e3c59x_ver_id]
482
        movzx   ecx, byte [e3c59x_ver_id]
483
        mov     esi, [e3c59x_hw_str+ecx*4]
483
        mov     esi, [e3c59x_hw_str+ecx*4]
484
        call    sys_msg_board_str
484
        call    sys_msg_board_str
485
        mov     esi, e3c59x_boomerang_str
485
        mov     esi, e3c59x_boomerang_str
486
        cmp     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
486
        cmp     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
487
        jz      .boomerang
487
        jz      .boomerang
488
        mov     esi, e3c59x_vortex_str
488
        mov     esi, e3c59x_vortex_str
489
.boomerang:
489
.boomerang:
490
        call    sys_msg_board_str
490
        call    sys_msg_board_str
491
; print device/vendor
491
; print device/vendor
492
        mov     ax, [pci_data+2]
492
        mov     ax, [pci_data+2]
493
        mov     cl, 2
493
        mov     cl, 2
494
        mov     ebx, e3c59x_device_id_str
494
        mov     ebx, e3c59x_device_id_str
495
        call    e3c59x_print_hex
495
        call    e3c59x_print_hex
496
        mov     esi, e3c59x_device_str
496
        mov     esi, e3c59x_device_str
497
        call    sys_msg_board_str
497
        call    sys_msg_board_str
498
        mov     ax, [pci_data]
498
        mov     ax, [pci_data]
499
        mov     cl, 2
499
        mov     cl, 2
500
        mov     ebx, e3c59x_vendor_id_str
500
        mov     ebx, e3c59x_vendor_id_str
501
        call    e3c59x_print_hex
501
        call    e3c59x_print_hex
502
        mov     esi, e3c59x_vendor_str
502
        mov     esi, e3c59x_vendor_str
503
        call    sys_msg_board_str
503
        call    sys_msg_board_str
504
; print io address
504
; print io address
505
        mov     ax, [io_addr]
505
        mov     ax, [io_addr]
506
        mov     ebx, e3c59x_io_addr_str
506
        mov     ebx, e3c59x_io_addr_str
507
        mov     cl, 2
507
        mov     cl, 2
508
        call    e3c59x_print_hex
508
        call    e3c59x_print_hex
509
        mov     esi, e3c59x_io_info_str
509
        mov     esi, e3c59x_io_info_str
510
        call    sys_msg_board_str
510
        call    sys_msg_board_str
511
; print MAC address
511
; print MAC address
512
        mov     ebx, e3c59x_mac_addr_str
512
        mov     ebx, e3c59x_mac_addr_str
513
        xor     ecx, ecx
513
        xor     ecx, ecx
514
.mac_loop:
514
.mac_loop:
515
        push    ecx
515
        push    ecx
516
        mov     al, [node_addr+ecx]
516
        mov     al, [node_addr+ecx]
517
        mov     cl, 1
517
        mov     cl, 1
518
        call    e3c59x_print_hex
518
        call    e3c59x_print_hex
519
        inc     ebx
519
        inc     ebx
520
        pop     ecx
520
        pop     ecx
521
        inc     cl
521
        inc     cl
522
        cmp     cl, 6
522
        cmp     cl, 6
523
        jne     .mac_loop
523
        jne     .mac_loop
524
        mov     esi, e3c59x_mac_info_str
524
        mov     esi, e3c59x_mac_info_str
525
        call    sys_msg_board_str
525
        call    sys_msg_board_str
526
; print link type
526
; print link type
527
        mov     esi, e3c59x_link_type_str
527
        mov     esi, e3c59x_link_type_str
528
        call    sys_msg_board_str
528
        call    sys_msg_board_str
529
        xor     eax, eax
529
        xor     eax, eax
530
        bsr     ax, word [e3c59x_link_type]
530
        bsr     ax, word [e3c59x_link_type]
531
        jz      @f
531
        jz      @f
532
        sub     ax, 4
532
        sub     ax, 4
533
@@:
533
@@:
534
        mov     esi, [e3c59x_link_str+eax*4]
534
        mov     esi, [e3c59x_link_str+eax*4]
535
        call    sys_msg_board_str
535
        call    sys_msg_board_str
536
        mov     esi, e3c59x_new_line_str
536
        mov     esi, e3c59x_new_line_str
537
        call    sys_msg_board_str
537
        call    sys_msg_board_str
538
        popad
538
        popad
539
        ret
539
        ret
540
 
540
 
541
;***************************************************************************
541
;***************************************************************************
542
;   Function
542
;   Function
543
;      e3c59x_print_hex
543
;      e3c59x_print_hex
544
;   Description
544
;   Description
545
;      prints a hexadecimal value
545
;      prints a hexadecimal value
546
;   Parameters
546
;   Parameters
547
;      eax - value to be printed out
547
;      eax - value to be printed out
548
;      ebx - where to print
548
;      ebx - where to print
549
;       cl - value size (1, 2, 4)
549
;       cl - value size (1, 2, 4)
550
;   Return value
550
;   Return value
551
;      ebx - end address after the print
551
;      ebx - end address after the print
552
;   Destroyed registers
552
;   Destroyed registers
553
;      eax, ebx
553
;      eax, ebx
554
;
554
;
555
;***************************************************************************
555
;***************************************************************************
556
        align 4
556
        align 4
557
e3c59x_print_hex:
557
e3c59x_print_hex:
558
        cmp     cl, 1
558
        cmp     cl, 1
559
        je      .print_byte
559
        je      .print_byte
560
        cmp     cl, 2
560
        cmp     cl, 2
561
        jz      .print_word
561
        jz      .print_word
562
.print_dword:
562
.print_dword:
563
        push    eax
563
        push    eax
564
        bswap   eax
564
        bswap   eax
565
        xchg    ah, al
565
        xchg    ah, al
566
        call    .print_word
566
        call    .print_word
567
        pop     eax
567
        pop     eax
568
.print_word:
568
.print_word:
569
        push    eax
569
        push    eax
570
        xchg    ah, al
570
        xchg    ah, al
571
        call    .print_byte
571
        call    .print_byte
572
        pop     eax
572
        pop     eax
573
.print_byte:
573
.print_byte:
574
        movzx   eax, al
574
        movzx   eax, al
575
        push    eax
575
        push    eax
576
        and     al, 0xf0
576
        and     al, 0xf0
577
        shr     al, 4
577
        shr     al, 4
578
        mov     al, byte [eax+e3c59x_charset]
578
        mov     al, byte [eax+e3c59x_charset]
579
        mov     [ebx], al
579
        mov     [ebx], al
580
        inc     ebx
580
        inc     ebx
581
        pop     eax
581
        pop     eax
582
        and     al, 0x0f
582
        and     al, 0x0f
583
        mov     al, byte [eax+e3c59x_charset]
583
        mov     al, byte [eax+e3c59x_charset]
584
        mov     [ebx], al
584
        mov     [ebx], al
585
        inc     ebx
585
        inc     ebx
586
        ret
586
        ret
587
end if ; defined E3C59X_DEBUG
587
end if ; defined E3C59X_DEBUG
588
 
588
 
589
;***************************************************************************
589
;***************************************************************************
590
;   Function
590
;   Function
591
;      e3c59x_try_link_detect
591
;      e3c59x_try_link_detect
592
;   Description
592
;   Description
593
;      e3c59x_try_link_detect checks if link exists
593
;      e3c59x_try_link_detect checks if link exists
594
;   Parameters
594
;   Parameters
595
;      ebp - io_addr
595
;      ebp - io_addr
596
;   Return value
596
;   Return value
597
;      al - 0 ; no link detected
597
;      al - 0 ; no link detected
598
;      al - 1 ; link detected
598
;      al - 1 ; link detected
599
;   Destroyed registers
599
;   Destroyed registers
600
;      eax, ebx, ecx, edx, edi, esi
600
;      eax, ebx, ecx, edx, edi, esi
601
;
601
;
602
;***************************************************************************
602
;***************************************************************************
603
        align 4
603
        align 4
604
e3c59x_try_link_detect:
604
e3c59x_try_link_detect:
605
; download self-directed packet
605
; download self-directed packet
606
        mov     edi, node_addr
606
        mov     edi, node_addr
607
        mov     bx, 0x0608 ; packet type
607
        mov     bx, 0x0608 ; packet type
608
        mov     esi, e3c59x_self_directed_packet
608
        mov     esi, e3c59x_self_directed_packet
609
        mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
609
        mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
610
        call    dword [e3c59x_transmit_function]
610
        call    dword [e3c59x_transmit_function]
611
; switch to register window 5
611
; switch to register window 5
612
        lea     edx, [ebp+E3C59X_REG_COMMAND]
612
        lea     edx, [ebp+E3C59X_REG_COMMAND]
613
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
613
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
614
        out     dx, ax
614
        out     dx, ax
615
; program RxFilter for promiscuous operation
615
; program RxFilter for promiscuous operation
616
        mov     ax, (10000b shl 11)
616
        mov     ax, (10000b shl 11)
617
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
617
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
618
        in      al, dx
618
        in      al, dx
619
        or      al, 1111b
619
        or      al, 1111b
620
        lea     edx, [ebp+E3C59X_REG_COMMAND]
620
        lea     edx, [ebp+E3C59X_REG_COMMAND]
621
        out     dx, ax
621
        out     dx, ax
622
; switch to register window 4
622
; switch to register window 4
623
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
623
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
624
        out     dx, ax
624
        out     dx, ax
625
; check loop
625
; check loop
626
        xor     ebx, ebx
626
        xor     ebx, ebx
627
        mov     ecx, 0xffff ; 65535 tries
627
        mov     ecx, 0xffff ; 65535 tries
628
.loop:
628
.loop:
629
        push    ecx ebx
629
        push    ecx ebx
630
        call    dword [e3c59x_receive_function]
630
        call    dword [e3c59x_receive_function]
631
        pop     ebx ecx
631
        pop     ebx ecx
632
        test    al, al
632
        test    al, al
633
        jnz     .finish
633
        jnz     .finish
634
.no_packet_received:
634
.no_packet_received:
635
; switch to register window 4
635
; switch to register window 4
636
        lea     edx, [ebp+E3C59X_REG_COMMAND]
636
        lea     edx, [ebp+E3C59X_REG_COMMAND]
637
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
637
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
638
        out     dx, ax
638
        out     dx, ax
639
; read linkbeatdetect
639
; read linkbeatdetect
640
        lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
640
        lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
641
        in      ax, dx
641
        in      ax, dx
642
        test    ah, 1000b ; test linkBeatDetect
642
        test    ah, 1000b ; test linkBeatDetect
643
        jnz     .link_detected
643
        jnz     .link_detected
644
        xor     al, al
644
        xor     al, al
645
        jmp     .finish
645
        jmp     .finish
646
.link_detected:
646
.link_detected:
647
; test carrierSense
647
; test carrierSense
648
        test    al, 100000b
648
        test    al, 100000b
649
        jz      .no_carrier_sense
649
        jz      .no_carrier_sense
650
        inc     ebx
650
        inc     ebx
651
.no_carrier_sense:
651
.no_carrier_sense:
652
        dec     ecx
652
        dec     ecx
653
        jns     .loop
653
        jns     .loop
654
; assume the link is good if 0 < ebx < 25 %
654
; assume the link is good if 0 < ebx < 25 %
655
        test    ebx, ebx
655
        test    ebx, ebx
656
        setnz   al
656
        setnz   al
657
        jz      .finish
657
        jz      .finish
658
        cmp     ebx, 16384 ; 25%
658
        cmp     ebx, 16384 ; 25%
659
        setb    al
659
        setb    al
660
.finish:
660
.finish:
661
if defined E3C59X_DEBUG
661
if defined E3C59X_DEBUG
662
        test    al, al
662
        test    al, al
663
        jz      @f
663
        jz      @f
664
        or      byte [e3c59x_link_type+1], 100b
664
        or      byte [e3c59x_link_type+1], 100b
665
@@:
665
@@:
666
end if ; defined E3C59X_DEBUG
666
end if ; defined E3C59X_DEBUG
667
        ret
667
        ret
668
 
668
 
669
;***************************************************************************
669
;***************************************************************************
670
;   Function
670
;   Function
671
;      e3c59x_try_phy
671
;      e3c59x_try_phy
672
;   Description
672
;   Description
673
;      e3c59x_try_phy checks the auto-negotiation function
673
;      e3c59x_try_phy checks the auto-negotiation function
674
;      in the PHY at PHY index. It can also be extended to
674
;      in the PHY at PHY index. It can also be extended to
675
;      include link detection for non-IEEE 802.3u
675
;      include link detection for non-IEEE 802.3u
676
;      auto-negotiation devices, for instance the BCM5000.
676
;      auto-negotiation devices, for instance the BCM5000.
677
;   Parameters
677
;   Parameters
678
;       ah - PHY index
678
;       ah - PHY index
679
;      ebp - io_addr
679
;      ebp - io_addr
680
;   Return value
680
;   Return value
681
;      al - 0 link is auto-negotiated
681
;      al - 0 link is auto-negotiated
682
;      al - 1 no link is auto-negotiated
682
;      al - 1 no link is auto-negotiated
683
;   Destroyed registers
683
;   Destroyed registers
684
;       eax, ebx, ecx, edx, esi
684
;       eax, ebx, ecx, edx, esi
685
;
685
;
686
;***************************************************************************
686
;***************************************************************************
687
        align 4
687
        align 4
688
e3c59x_try_phy:
688
e3c59x_try_phy:
689
        mov     al, E3C59X_REG_MII_BMCR
689
        mov     al, E3C59X_REG_MII_BMCR
690
        push    eax
690
        push    eax
691
        call    e3c59x_mdio_read ; returns with window #4
691
        call    e3c59x_mdio_read ; returns with window #4
692
        or      ah, 0x80 ; software reset
692
        or      ah, 0x80 ; software reset
693
        mov     ebx, eax
693
        mov     ebx, eax
694
        pop     eax
694
        pop     eax
695
        push    eax
695
        push    eax
696
        call    e3c59x_mdio_write ; returns with window #4
696
        call    e3c59x_mdio_write ; returns with window #4
697
; wait for reset to complete
697
; wait for reset to complete
698
        mov     esi, 2000 ; 2000ms = 2s
698
        mov     esi, 2000 ; 2000ms = 2s
699
        call    delay_ms
699
        call    delay_ms
700
        pop     eax
700
        pop     eax
701
        push    eax
701
        push    eax
702
        call    e3c59x_mdio_read ; returns with window #4
702
        call    e3c59x_mdio_read ; returns with window #4
703
        test    ah, 0x80
703
        test    ah, 0x80
704
        jnz     .fail_finish
704
        jnz     .fail_finish
705
        pop     eax
705
        pop     eax
706
        push    eax
706
        push    eax
707
; wait for a while after reset
707
; wait for a while after reset
708
        mov     esi, 20 ; 20ms
708
        mov     esi, 20 ; 20ms
709
        call    delay_ms
709
        call    delay_ms
710
        pop     eax
710
        pop     eax
711
        push    eax
711
        push    eax
712
        mov     al, E3C59X_REG_MII_BMSR
712
        mov     al, E3C59X_REG_MII_BMSR
713
        call    e3c59x_mdio_read ; returns with window #4
713
        call    e3c59x_mdio_read ; returns with window #4
714
        test    al, 1 ; extended capability supported?
714
        test    al, 1 ; extended capability supported?
715
        jz      .no_ext_cap
715
        jz      .no_ext_cap
716
; auto-neg capable?
716
; auto-neg capable?
717
        test    al, 1000b
717
        test    al, 1000b
718
        jz      .fail_finish ; not auto-negotiation capable
718
        jz      .fail_finish ; not auto-negotiation capable
719
; auto-neg complete?
719
; auto-neg complete?
720
        test    al, 100000b
720
        test    al, 100000b
721
        jnz     .auto_neg_ok
721
        jnz     .auto_neg_ok
722
; restart auto-negotiation
722
; restart auto-negotiation
723
        pop     eax
723
        pop     eax
724
        push    eax
724
        push    eax
725
        mov     al, E3C59X_REG_MII_ANAR
725
        mov     al, E3C59X_REG_MII_ANAR
726
        push    eax
726
        push    eax
727
        call    e3c59x_mdio_read ; returns with window #4
727
        call    e3c59x_mdio_read ; returns with window #4
728
        or      ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX
728
        or      ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX
729
        mov     ebx, eax
729
        mov     ebx, eax
730
        pop     eax
730
        pop     eax
731
        call    e3c59x_mdio_write ; returns with window #4
731
        call    e3c59x_mdio_write ; returns with window #4
732
        pop     eax
732
        pop     eax
733
        push    eax
733
        push    eax
734
        call    e3c59x_mdio_read ; returns with window #4
734
        call    e3c59x_mdio_read ; returns with window #4
735
        mov     ebx, eax
735
        mov     ebx, eax
736
        or      bh, 10010b ; restart auto-negotiation
736
        or      bh, 10010b ; restart auto-negotiation
737
        pop     eax
737
        pop     eax
738
        push    eax
738
        push    eax
739
        call    e3c59x_mdio_write ; returns with window #4
739
        call    e3c59x_mdio_write ; returns with window #4
740
        mov     esi, 4000 ; 4000ms = 4 seconds
740
        mov     esi, 4000 ; 4000ms = 4 seconds
741
        call    delay_ms
741
        call    delay_ms
742
        pop     eax
742
        pop     eax
743
        push    eax
743
        push    eax
744
        mov     al, E3C59X_REG_MII_BMSR
744
        mov     al, E3C59X_REG_MII_BMSR
745
        call    e3c59x_mdio_read ; returns with window #4
745
        call    e3c59x_mdio_read ; returns with window #4
746
        test    al, 100000b ; auto-neg complete?
746
        test    al, 100000b ; auto-neg complete?
747
        jnz     .auto_neg_ok
747
        jnz     .auto_neg_ok
748
        jmp     .fail_finish
748
        jmp     .fail_finish
749
.auto_neg_ok:
749
.auto_neg_ok:
750
; compare advertisement and link partner ability registers
750
; compare advertisement and link partner ability registers
751
        pop     eax
751
        pop     eax
752
        push    eax
752
        push    eax
753
        mov     al, E3C59X_REG_MII_ANAR
753
        mov     al, E3C59X_REG_MII_ANAR
754
        call    e3c59x_mdio_read ; returns with window #4
754
        call    e3c59x_mdio_read ; returns with window #4
755
        xchg    eax, [esp]
755
        xchg    eax, [esp]
756
        mov     al, E3C59X_REG_MII_ANLPAR
756
        mov     al, E3C59X_REG_MII_ANLPAR
757
        call    e3c59x_mdio_read ; returns with window #4
757
        call    e3c59x_mdio_read ; returns with window #4
758
        pop     ebx
758
        pop     ebx
759
        and     eax, ebx
759
        and     eax, ebx
760
        and     eax, 1111100000b
760
        and     eax, 1111100000b
761
        push    eax
761
        push    eax
762
if defined E3C59X_DEBUG
762
if defined E3C59X_DEBUG
763
        mov     word [e3c59x_link_type], ax
763
        mov     word [e3c59x_link_type], ax
764
end if ; defined E3C59X_DEBUG
764
end if ; defined E3C59X_DEBUG
765
; switch to register window 3
765
; switch to register window 3
766
        lea     edx, [ebp+E3C59X_REG_COMMAND]
766
        lea     edx, [ebp+E3C59X_REG_COMMAND]
767
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
767
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
768
        out     dx, ax
768
        out     dx, ax
769
; set full-duplex mode
769
; set full-duplex mode
770
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
770
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
771
        in      ax, dx
771
        in      ax, dx
772
        and     ax, not 0x120 ; clear full duplex and flow control
772
        and     ax, not 0x120 ; clear full duplex and flow control
773
        pop     ebx
773
        pop     ebx
774
        test    ebx, (1010b shl 5) ; check for full-duplex
774
        test    ebx, (1010b shl 5) ; check for full-duplex
775
        jz      .half_duplex
775
        jz      .half_duplex
776
        or      ax, 0x120 ; set full duplex and flow control
776
        or      ax, 0x120 ; set full duplex and flow control
777
.half_duplex:
777
.half_duplex:
778
        out     dx, ax
778
        out     dx, ax
779
        mov     al, 1
779
        mov     al, 1
780
        ret
780
        ret
781
.no_ext_cap:
781
.no_ext_cap:
782
; not yet implemented BCM5000
782
; not yet implemented BCM5000
783
.fail_finish:
783
.fail_finish:
784
        pop     eax
784
        pop     eax
785
        xor     al, al
785
        xor     al, al
786
        ret
786
        ret
787
 
787
 
788
;***************************************************************************
788
;***************************************************************************
789
;   Function
789
;   Function
790
;      e3c59x_try_mii
790
;      e3c59x_try_mii
791
;   Description
791
;   Description
792
;      e3c59x_try_MII checks the on-chip auto-negotiation logic
792
;      e3c59x_try_MII checks the on-chip auto-negotiation logic
793
;      or an off-chip MII PHY, depending upon what is set in
793
;      or an off-chip MII PHY, depending upon what is set in
794
;      xcvrSelect by the caller.
794
;      xcvrSelect by the caller.
795
;      It exits when it finds the first device with a good link.
795
;      It exits when it finds the first device with a good link.
796
;   Parameters
796
;   Parameters
797
;      ebp - io_addr
797
;      ebp - io_addr
798
;   Return value
798
;   Return value
799
;      al - 0
799
;      al - 0
800
;      al - 1
800
;      al - 1
801
;   Destroyed registers
801
;   Destroyed registers
802
;      eax, ebx, ecx, edx, esi
802
;      eax, ebx, ecx, edx, esi
803
;
803
;
804
;***************************************************************************
804
;***************************************************************************
805
        align 4
805
        align 4
806
e3c59x_try_mii:
806
e3c59x_try_mii:
807
; switch to register window 3
807
; switch to register window 3
808
        lea     edx, [ebp+E3C59X_REG_COMMAND]
808
        lea     edx, [ebp+E3C59X_REG_COMMAND]
809
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
809
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
810
        out     dx, ax
810
        out     dx, ax
811
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
811
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
812
        in      eax, dx
812
        in      eax, dx
813
        and     eax, (1111b shl 20)
813
        and     eax, (1111b shl 20)
814
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
814
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
815
        jne     .mii_device
815
        jne     .mii_device
816
; auto-negotiation is set
816
; auto-negotiation is set
817
; switch to register window 4
817
; switch to register window 4
818
        lea     edx, [ebp+E3C59X_REG_COMMAND]
818
        lea     edx, [ebp+E3C59X_REG_COMMAND]
819
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
819
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
820
        out     dx, ax
820
        out     dx, ax
821
; PHY==24 is the on-chip auto-negotiation logic
821
; PHY==24 is the on-chip auto-negotiation logic
822
; it supports only 10base-T and 100base-TX
822
; it supports only 10base-T and 100base-TX
823
        mov     ah, 24
823
        mov     ah, 24
824
        call    e3c59x_try_phy
824
        call    e3c59x_try_phy
825
        test    al, al
825
        test    al, al
826
        jz      .fail_finish
826
        jz      .fail_finish
827
        mov     cl, 24
827
        mov     cl, 24
828
        jmp     .check_preamble
828
        jmp     .check_preamble
829
.mii_device:
829
.mii_device:
830
        cmp     eax, (0110b shl 20)
830
        cmp     eax, (0110b shl 20)
831
        jne     .fail_finish
831
        jne     .fail_finish
832
        lea     edx, [ebp+E3C59X_REG_COMMAND]
832
        lea     edx, [ebp+E3C59X_REG_COMMAND]
833
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
833
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
834
        out     dx, ax
834
        out     dx, ax
835
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
835
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
836
        in      ax, dx
836
        in      ax, dx
837
        and     al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA)
837
        and     al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA)
838
        cmp     al, (1 shl E3C59X_BIT_MGMT_DATA)
838
        cmp     al, (1 shl E3C59X_BIT_MGMT_DATA)
839
        je      .serch_for_phy
839
        je      .serch_for_phy
840
        xor     al, al
840
        xor     al, al
841
        ret
841
        ret
842
.serch_for_phy:
842
.serch_for_phy:
843
; search for PHY
843
; search for PHY
844
        mov     cl, 31
844
        mov     cl, 31
845
.search_phy_loop:
845
.search_phy_loop:
846
        cmp     cl, 24
846
        cmp     cl, 24
847
        je      .next_phy
847
        je      .next_phy
848
        mov     ah, cl ; ah = phy
848
        mov     ah, cl ; ah = phy
849
        mov     al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register
849
        mov     al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register
850
        push    ecx
850
        push    ecx
851
        call    e3c59x_mdio_read
851
        call    e3c59x_mdio_read
852
        pop     ecx
852
        pop     ecx
853
        test    ax, ax
853
        test    ax, ax
854
        jz      .next_phy
854
        jz      .next_phy
855
        cmp     ax, 0xffff
855
        cmp     ax, 0xffff
856
        je      .next_phy
856
        je      .next_phy
857
        mov     ah, cl ; ah = phy
857
        mov     ah, cl ; ah = phy
858
        push    ecx
858
        push    ecx
859
        call    e3c59x_try_phy
859
        call    e3c59x_try_phy
860
        pop     ecx
860
        pop     ecx
861
        test    al, al
861
        test    al, al
862
        jnz     .check_preamble
862
        jnz     .check_preamble
863
.next_phy:
863
.next_phy:
864
        dec     cl
864
        dec     cl
865
        jns     .search_phy_loop
865
        jns     .search_phy_loop
866
.fail_finish:
866
.fail_finish:
867
        xor     al, al
867
        xor     al, al
868
        ret
868
        ret
869
; epilog
869
; epilog
870
.check_preamble:
870
.check_preamble:
871
        push    eax ; eax contains the return value of e3c59x_try_phy
871
        push    eax ; eax contains the return value of e3c59x_try_phy
872
; check hard coded preamble forcing
872
; check hard coded preamble forcing
873
        movzx   eax, byte [e3c59x_ver_id]
873
        movzx   eax, byte [e3c59x_ver_id]
874
        test    word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE
874
        test    word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE
875
        setnz   [e3c59x_preamble] ; force preamble
875
        setnz   [e3c59x_preamble] ; force preamble
876
        jnz     .finish
876
        jnz     .finish
877
; check mii for preamble suppression
877
; check mii for preamble suppression
878
        mov     ah, cl
878
        mov     ah, cl
879
        mov     al, E3C59X_REG_MII_BMSR
879
        mov     al, E3C59X_REG_MII_BMSR
880
        call    e3c59x_mdio_read
880
        call    e3c59x_mdio_read
881
        test    al, 1000000b ; preamble suppression?
881
        test    al, 1000000b ; preamble suppression?
882
        setz    [e3c59x_preamble] ; no
882
        setz    [e3c59x_preamble] ; no
883
.finish:
883
.finish:
884
        pop     eax
884
        pop     eax
885
        ret
885
        ret
886
 
886
 
887
;***************************************************************************
887
;***************************************************************************
888
;   Function
888
;   Function
889
;      e3c59x_test_packet
889
;      e3c59x_test_packet
890
;   Description
890
;   Description
891
;      e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port
891
;      e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port
892
;   Parameters
892
;   Parameters
893
;      ebp - io_addr
893
;      ebp - io_addr
894
;   Return value
894
;   Return value
895
;      al - 0
895
;      al - 0
896
;      al - 1
896
;      al - 1
897
;   Destroyed registers
897
;   Destroyed registers
898
;      eax, ebx, ecx, edx, edi, esi
898
;      eax, ebx, ecx, edx, edi, esi
899
;
899
;
900
;***************************************************************************
900
;***************************************************************************
901
        align 4
901
        align 4
902
e3c59x_test_packet:
902
e3c59x_test_packet:
903
; switch to register window 3
903
; switch to register window 3
904
        lea     edx, [ebp+E3C59X_REG_COMMAND]
904
        lea     edx, [ebp+E3C59X_REG_COMMAND]
905
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
905
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
906
        out     dx, ax
906
        out     dx, ax
907
; set fullDuplexEnable in MacControl register
907
; set fullDuplexEnable in MacControl register
908
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
908
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
909
        in      ax, dx
909
        in      ax, dx
910
        or      ax, 0x120
910
        or      ax, 0x120
911
        out     dx, ax
911
        out     dx, ax
912
; switch to register window 5
912
; switch to register window 5
913
        lea     edx, [ebp+E3C59X_REG_COMMAND]
913
        lea     edx, [ebp+E3C59X_REG_COMMAND]
914
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
914
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
915
        out     dx, ax
915
        out     dx, ax
916
; set RxFilter to enable individual address matches
916
; set RxFilter to enable individual address matches
917
        mov     ax, (10000b shl 11)
917
        mov     ax, (10000b shl 11)
918
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
918
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
919
        in      al, dx
919
        in      al, dx
920
        or      al, 1
920
        or      al, 1
921
        lea     edx, [ebp+E3C59X_REG_COMMAND]
921
        lea     edx, [ebp+E3C59X_REG_COMMAND]
922
        out     dx, ax
922
        out     dx, ax
923
; issue RxEnable and TxEnable
923
; issue RxEnable and TxEnable
924
        call    e3c59x_rx_reset
924
        call    e3c59x_rx_reset
925
        call    e3c59x_tx_reset
925
        call    e3c59x_tx_reset
926
; download a self-directed test packet
926
; download a self-directed test packet
927
        mov     edi, node_addr
927
        mov     edi, node_addr
928
        mov     bx, 0x0608 ; packet type
928
        mov     bx, 0x0608 ; packet type
929
        mov     esi, e3c59x_self_directed_packet
929
        mov     esi, e3c59x_self_directed_packet
930
        mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
930
        mov     ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
931
        call    dword [e3c59x_transmit_function]
931
        call    dword [e3c59x_transmit_function]
932
; wait for 2s
932
; wait for 2s
933
        mov     esi, 2000 ; 2000ms = 2s
933
        mov     esi, 2000 ; 2000ms = 2s
934
        call    delay_ms
934
        call    delay_ms
935
; check if self-directed packet is received
935
; check if self-directed packet is received
936
        call    dword [e3c59x_receive_function]
936
        call    dword [e3c59x_receive_function]
937
        test    al, al
937
        test    al, al
938
        jnz     .finish
938
        jnz     .finish
939
; switch to register window 3
939
; switch to register window 3
940
        lea     edx, [ebp+E3C59X_REG_COMMAND]
940
        lea     edx, [ebp+E3C59X_REG_COMMAND]
941
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
941
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
942
        out     dx, ax
942
        out     dx, ax
943
; clear fullDuplexEnable in MacControl register
943
; clear fullDuplexEnable in MacControl register
944
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
944
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
945
        in      ax, dx
945
        in      ax, dx
946
        and     ax, not 0x120
946
        and     ax, not 0x120
947
        out     dx, ax
947
        out     dx, ax
948
        xor     al, al
948
        xor     al, al
949
.finish:
949
.finish:
950
        ret
950
        ret
951
 
951
 
952
;***************************************************************************
952
;***************************************************************************
953
;   Function
953
;   Function
954
;      e3c59x_try_loopback
954
;      e3c59x_try_loopback
955
;   Description
955
;   Description
956
;      tries a loopback packet for 10BASE2 or AUI port
956
;      tries a loopback packet for 10BASE2 or AUI port
957
;   Parameters
957
;   Parameters
958
;      al -  0: 10Mbps AUI connector
958
;      al -  0: 10Mbps AUI connector
959
;            1: 10BASE-2
959
;            1: 10BASE-2
960
;      ebp - io_addr
960
;      ebp - io_addr
961
;   Return value
961
;   Return value
962
;      al - 0
962
;      al - 0
963
;      al - 1
963
;      al - 1
964
;   Destroyed registers
964
;   Destroyed registers
965
;      eax, ebx, ecx, edx, edi, esi
965
;      eax, ebx, ecx, edx, edi, esi
966
;
966
;
967
;***************************************************************************
967
;***************************************************************************
968
        align 4
968
        align 4
969
e3c59x_try_loopback:
969
e3c59x_try_loopback:
970
        push    eax
970
        push    eax
971
; switch to register window 3
971
; switch to register window 3
972
        lea     edx, [ebp+E3C59X_REG_COMMAND]
972
        lea     edx, [ebp+E3C59X_REG_COMMAND]
973
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
973
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
974
        out     dx, ax
974
        out     dx, ax
975
        pop     eax
975
        pop     eax
976
        push    eax
976
        push    eax
977
if defined E3C59X_DEBUG
977
if defined E3C59X_DEBUG
978
        mov     bl, al
978
        mov     bl, al
979
        inc     bl
979
        inc     bl
980
        shl     bl, 3
980
        shl     bl, 3
981
        or      byte [e3c59x_link_type+1], bl
981
        or      byte [e3c59x_link_type+1], bl
982
end if ; defined E3C59X_DEBUG
982
end if ; defined E3C59X_DEBUG
983
        test    al, al ; aui or coax?
983
        test    al, al ; aui or coax?
984
        jz      .complete_loopback
984
        jz      .complete_loopback
985
; enable 100BASE-2 DC-DC converter
985
; enable 100BASE-2 DC-DC converter
986
        mov     ax, (10b shl 11) ; EnableDcConverter
986
        mov     ax, (10b shl 11) ; EnableDcConverter
987
        out     dx, ax
987
        out     dx, ax
988
.complete_loopback:
988
.complete_loopback:
989
        mov     cl, 2 ; give a port 3 chances to complete a loopback
989
        mov     cl, 2 ; give a port 3 chances to complete a loopback
990
.next_try:
990
.next_try:
991
        push    ecx
991
        push    ecx
992
        call    e3c59x_test_packet
992
        call    e3c59x_test_packet
993
        pop     ecx
993
        pop     ecx
994
        test    al, al
994
        test    al, al
995
        jnz     .finish
995
        jnz     .finish
996
        dec     cl
996
        dec     cl
997
        jns     .next_try
997
        jns     .next_try
998
.finish:
998
.finish:
999
        xchg    eax, [esp]
999
        xchg    eax, [esp]
1000
        test    al, al
1000
        test    al, al
1001
        jz      .aui_finish
1001
        jz      .aui_finish
1002
; issue DisableDcConverter command
1002
; issue DisableDcConverter command
1003
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1003
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1004
        mov     ax, (10111b shl 11)
1004
        mov     ax, (10111b shl 11)
1005
        out     dx, ax
1005
        out     dx, ax
1006
.aui_finish:
1006
.aui_finish:
1007
        pop     eax ; al contains the result of operation
1007
        pop     eax ; al contains the result of operation
1008
if defined E3C59X_DEBUG
1008
if defined E3C59X_DEBUG
1009
        test    al, al
1009
        test    al, al
1010
        jnz     @f
1010
        jnz     @f
1011
        and     byte [e3c59x_link_type+1], not 11000b
1011
        and     byte [e3c59x_link_type+1], not 11000b
1012
@@:
1012
@@:
1013
end if ; defined E3C59X_DEBUG
1013
end if ; defined E3C59X_DEBUG
1014
        ret
1014
        ret
1015
 
1015
 
1016
;***************************************************************************
1016
;***************************************************************************
1017
;   Function
1017
;   Function
1018
;      e3c59x_set_available_media
1018
;      e3c59x_set_available_media
1019
;   Description
1019
;   Description
1020
;      sets the first available media
1020
;      sets the first available media
1021
;   Parameters
1021
;   Parameters
1022
;      ebp - io_addr
1022
;      ebp - io_addr
1023
;   Return value
1023
;   Return value
1024
;      al - 0
1024
;      al - 0
1025
;      al - 1
1025
;      al - 1
1026
;   Destroyed registers
1026
;   Destroyed registers
1027
;      eax, edx
1027
;      eax, edx
1028
;
1028
;
1029
;***************************************************************************
1029
;***************************************************************************
1030
        align 4
1030
        align 4
1031
e3c59x_set_available_media:
1031
e3c59x_set_available_media:
1032
; switch to register window 3
1032
; switch to register window 3
1033
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1033
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1034
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1034
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1035
        out     dx, ax
1035
        out     dx, ax
1036
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1036
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1037
        in      eax, dx
1037
        in      eax, dx
1038
        push    eax
1038
        push    eax
1039
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1039
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1040
        in      ax, dx
1040
        in      ax, dx
1041
        test    al, 10b
1041
        test    al, 10b
1042
        jz      @f
1042
        jz      @f
1043
; baseTXAvailable
1043
; baseTXAvailable
1044
        pop     eax
1044
        pop     eax
1045
        and     eax, not (1111b shl 20)
1045
        and     eax, not (1111b shl 20)
1046
        or      eax, (100b shl 20)
1046
        or      eax, (100b shl 20)
1047
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
1047
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
1048
        mov     word [e3c59x_link_type], (1 shl 8)
1048
        mov     word [e3c59x_link_type], (1 shl 8)
1049
else if defined E3C59X_DEBUG
1049
else if defined E3C59X_DEBUG
1050
        mov     word [e3c59x_link_type], (1 shl 7)
1050
        mov     word [e3c59x_link_type], (1 shl 7)
1051
end if
1051
end if
1052
        jmp     .set_media
1052
        jmp     .set_media
1053
@@:
1053
@@:
1054
        test    al, 100b
1054
        test    al, 100b
1055
        jz      @f
1055
        jz      @f
1056
; baseFXAvailable
1056
; baseFXAvailable
1057
        pop     eax
1057
        pop     eax
1058
        and     eax, not (1111b shl 20)
1058
        and     eax, not (1111b shl 20)
1059
        or      eax, (101b shl 20)
1059
        or      eax, (101b shl 20)
1060
if defined E3C59X_DEBUG
1060
if defined E3C59X_DEBUG
1061
        mov     word [e3c59x_link_type], (1 shl 10)
1061
        mov     word [e3c59x_link_type], (1 shl 10)
1062
end if
1062
end if
1063
        jmp     .set_media
1063
        jmp     .set_media
1064
@@:
1064
@@:
1065
        test    al, 1000000b
1065
        test    al, 1000000b
1066
        jz      @f
1066
        jz      @f
1067
; miiDevice
1067
; miiDevice
1068
        pop     eax
1068
        pop     eax
1069
        and     eax, not (1111b shl 20)
1069
        and     eax, not (1111b shl 20)
1070
        or      eax, (0110b shl 20)
1070
        or      eax, (0110b shl 20)
1071
if defined E3C59X_DEBUG
1071
if defined E3C59X_DEBUG
1072
        mov     word [e3c59x_link_type], (1 shl 13)
1072
        mov     word [e3c59x_link_type], (1 shl 13)
1073
end if
1073
end if
1074
        jmp     .set_media
1074
        jmp     .set_media
1075
@@:
1075
@@:
1076
        test    al, 1000b
1076
        test    al, 1000b
1077
        jz      @f
1077
        jz      @f
1078
.set_default:
1078
.set_default:
1079
; 10bTAvailable
1079
; 10bTAvailable
1080
        pop     eax
1080
        pop     eax
1081
        and     eax, not (1111b shl 20)
1081
        and     eax, not (1111b shl 20)
1082
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
1082
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
1083
        mov     word [e3c59x_link_type], (1 shl 6)
1083
        mov     word [e3c59x_link_type], (1 shl 6)
1084
else if defined E3C59X_DEBUG
1084
else if defined E3C59X_DEBUG
1085
        mov     word [e3c59x_link_type], (1 shl 5)
1085
        mov     word [e3c59x_link_type], (1 shl 5)
1086
end if ; E3C59X_FORCE_FD
1086
end if ; E3C59X_FORCE_FD
1087
        jmp     .set_media
1087
        jmp     .set_media
1088
@@:
1088
@@:
1089
        test    al, 10000b
1089
        test    al, 10000b
1090
        jz      @f
1090
        jz      @f
1091
; coaxAvailable
1091
; coaxAvailable
1092
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1092
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1093
        mov     ax, (10b shl 11) ; EnableDcConverter
1093
        mov     ax, (10b shl 11) ; EnableDcConverter
1094
        out     dx, ax
1094
        out     dx, ax
1095
        pop     eax
1095
        pop     eax
1096
        and     eax, not (1111b shl 20)
1096
        and     eax, not (1111b shl 20)
1097
        or      eax, (11b shl 20)
1097
        or      eax, (11b shl 20)
1098
if defined E3C59X_DEBUG
1098
if defined E3C59X_DEBUG
1099
        mov     word [e3c59x_link_type], (1 shl 12)
1099
        mov     word [e3c59x_link_type], (1 shl 12)
1100
end if ; defined E3C59X_DEBUG
1100
end if ; defined E3C59X_DEBUG
1101
        jmp     .set_media
1101
        jmp     .set_media
1102
@@:
1102
@@:
1103
        test    al, 10000b
1103
        test    al, 10000b
1104
        jz      .set_default
1104
        jz      .set_default
1105
; auiAvailable
1105
; auiAvailable
1106
        pop     eax
1106
        pop     eax
1107
        and     eax, not (1111b shl 20)
1107
        and     eax, not (1111b shl 20)
1108
        or      eax, (1 shl 20)
1108
        or      eax, (1 shl 20)
1109
if defined E3C59X_DEBUG
1109
if defined E3C59X_DEBUG
1110
        mov     word [e3c59x_link_type], (1 shl 11)
1110
        mov     word [e3c59x_link_type], (1 shl 11)
1111
end if ; defined E3C59X_DEBUG
1111
end if ; defined E3C59X_DEBUG
1112
.set_media:
1112
.set_media:
1113
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1113
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1114
        out     dx, eax
1114
        out     dx, eax
1115
if defined E3C59X_FORCE_FD
1115
if defined E3C59X_FORCE_FD
1116
; set fullDuplexEnable in MacControl register
1116
; set fullDuplexEnable in MacControl register
1117
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
1117
        lea     edx, [ebp+E3C59X_REG_MAC_CONTROL]
1118
        in      ax, dx
1118
        in      ax, dx
1119
        or      ax, 0x120
1119
        or      ax, 0x120
1120
        out     dx, ax
1120
        out     dx, ax
1121
end if ; E3C59X_FORCE_FD
1121
end if ; E3C59X_FORCE_FD
1122
        mov     al, 1
1122
        mov     al, 1
1123
        ret
1123
        ret
1124
 
1124
 
1125
;***************************************************************************
1125
;***************************************************************************
1126
;   Function
1126
;   Function
1127
;      e3c59x_set_active_port
1127
;      e3c59x_set_active_port
1128
;   Description
1128
;   Description
1129
;      It selects the media port (transceiver) to be used
1129
;      It selects the media port (transceiver) to be used
1130
;   Parameters:
1130
;   Parameters:
1131
;      ebp - io_addr
1131
;      ebp - io_addr
1132
;   Return value:
1132
;   Return value:
1133
;   Destroyed registers
1133
;   Destroyed registers
1134
;      eax, ebx, ecx, edx, edi, esi
1134
;      eax, ebx, ecx, edx, edi, esi
1135
;
1135
;
1136
;***************************************************************************
1136
;***************************************************************************
1137
        align 4
1137
        align 4
1138
e3c59x_set_active_port:
1138
e3c59x_set_active_port:
1139
; switch to register window 3
1139
; switch to register window 3
1140
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1140
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1141
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1141
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1142
        out     dx, ax
1142
        out     dx, ax
1143
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1143
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1144
        in      eax, dx
1144
        in      eax, dx
1145
        test    eax, (1 shl 24) ; check if autoselect enable
1145
        test    eax, (1 shl 24) ; check if autoselect enable
1146
        jz      .set_first_available_media
1146
        jz      .set_first_available_media
1147
; check 100BASE-TX and 10BASE-T
1147
; check 100BASE-TX and 10BASE-T
1148
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1148
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1149
        in      ax, dx
1149
        in      ax, dx
1150
        test    al, 1010b ; check whether 100BASE-TX or 10BASE-T available
1150
        test    al, 1010b ; check whether 100BASE-TX or 10BASE-T available
1151
        jz      .mii_device ; they are not available
1151
        jz      .mii_device ; they are not available
1152
; set auto-negotiation
1152
; set auto-negotiation
1153
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1153
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1154
        in      eax, dx
1154
        in      eax, dx
1155
        and     eax, not (1111b shl 20)
1155
        and     eax, not (1111b shl 20)
1156
        or      eax, (1000b shl 20)
1156
        or      eax, (1000b shl 20)
1157
        out     dx, eax
1157
        out     dx, eax
1158
        call    e3c59x_try_mii
1158
        call    e3c59x_try_mii
1159
        test    al, al
1159
        test    al, al
1160
        jz      .mii_device
1160
        jz      .mii_device
1161
        ret
1161
        ret
1162
.mii_device:
1162
.mii_device:
1163
; switch to register window 3
1163
; switch to register window 3
1164
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1164
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1165
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1165
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1166
        out     dx, ax
1166
        out     dx, ax
1167
; check for off-chip mii device
1167
; check for off-chip mii device
1168
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1168
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1169
        in      ax, dx
1169
        in      ax, dx
1170
        test    al, 1000000b ; check miiDevice
1170
        test    al, 1000000b ; check miiDevice
1171
        jz      .base_fx
1171
        jz      .base_fx
1172
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1172
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1173
        in      eax, dx
1173
        in      eax, dx
1174
        and     eax, not (1111b shl 20)
1174
        and     eax, not (1111b shl 20)
1175
        or      eax, (0110b shl 20) ; set MIIDevice
1175
        or      eax, (0110b shl 20) ; set MIIDevice
1176
        out     dx, eax
1176
        out     dx, eax
1177
        call    e3c59x_try_mii
1177
        call    e3c59x_try_mii
1178
        test    al, al
1178
        test    al, al
1179
        jz      .base_fx
1179
        jz      .base_fx
1180
        ret
1180
        ret
1181
.base_fx:
1181
.base_fx:
1182
; switch to register window 3
1182
; switch to register window 3
1183
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1183
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1184
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1184
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1185
        out     dx, ax
1185
        out     dx, ax
1186
; check for 100BASE-FX
1186
; check for 100BASE-FX
1187
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1187
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1188
        in      ax, dx ; read media option register
1188
        in      ax, dx ; read media option register
1189
        test    al, 100b ; check 100BASE-FX
1189
        test    al, 100b ; check 100BASE-FX
1190
        jz      .aui_enable
1190
        jz      .aui_enable
1191
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1191
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1192
        in      eax, dx
1192
        in      eax, dx
1193
        and     eax, not (1111b shl 20)
1193
        and     eax, not (1111b shl 20)
1194
        or      eax, (0101b shl 20) ; set 100base-FX
1194
        or      eax, (0101b shl 20) ; set 100base-FX
1195
        out     dx, eax
1195
        out     dx, eax
1196
        call    e3c59x_try_link_detect
1196
        call    e3c59x_try_link_detect
1197
        test    al, al
1197
        test    al, al
1198
        jz      .aui_enable
1198
        jz      .aui_enable
1199
        ret
1199
        ret
1200
.aui_enable:
1200
.aui_enable:
1201
; switch to register window 3
1201
; switch to register window 3
1202
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1202
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1203
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1203
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1204
        out     dx, ax
1204
        out     dx, ax
1205
; check for 10Mbps AUI connector
1205
; check for 10Mbps AUI connector
1206
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1206
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1207
        in      ax, dx ; read media option register
1207
        in      ax, dx ; read media option register
1208
        test    al, 100000b ; check 10Mbps AUI connector
1208
        test    al, 100000b ; check 10Mbps AUI connector
1209
        jz      .coax_available
1209
        jz      .coax_available
1210
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1210
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1211
        in      eax, dx
1211
        in      eax, dx
1212
        and     eax, not (1111b shl 20)
1212
        and     eax, not (1111b shl 20)
1213
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1213
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1214
        out     dx, eax
1214
        out     dx, eax
1215
        xor     al, al ; try 10Mbps AUI connector
1215
        xor     al, al ; try 10Mbps AUI connector
1216
        call    e3c59x_try_loopback
1216
        call    e3c59x_try_loopback
1217
        test    al, al
1217
        test    al, al
1218
        jz      .coax_available
1218
        jz      .coax_available
1219
        ret
1219
        ret
1220
.coax_available:
1220
.coax_available:
1221
; switch to register window 3
1221
; switch to register window 3
1222
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1222
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1223
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1223
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+3
1224
        out     dx, ax
1224
        out     dx, ax
1225
; check for coaxial 10BASE-2 port
1225
; check for coaxial 10BASE-2 port
1226
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1226
        lea     edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
1227
        in      ax, dx ; read media option register
1227
        in      ax, dx ; read media option register
1228
        test    al, 10000b ; check 10BASE-2
1228
        test    al, 10000b ; check 10BASE-2
1229
        jz      .set_first_available_media
1229
        jz      .set_first_available_media
1230
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1230
        lea     edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
1231
        in      eax, dx
1231
        in      eax, dx
1232
        and     eax, not (1111b shl 20)
1232
        and     eax, not (1111b shl 20)
1233
        or      eax, (0011b shl 20) ; set 10BASE-2
1233
        or      eax, (0011b shl 20) ; set 10BASE-2
1234
        out     dx, eax
1234
        out     dx, eax
1235
        mov     al, 1
1235
        mov     al, 1
1236
        call    e3c59x_try_loopback
1236
        call    e3c59x_try_loopback
1237
        test    al, al
1237
        test    al, al
1238
        jz      .set_first_available_media
1238
        jz      .set_first_available_media
1239
        ret
1239
        ret
1240
.set_first_available_media:
1240
.set_first_available_media:
1241
        jmp     e3c59x_set_available_media
1241
        jmp     e3c59x_set_available_media
1242
 
1242
 
1243
;***************************************************************************
1243
;***************************************************************************
1244
;   Function
1244
;   Function
1245
;      e3c59x_wake_up
1245
;      e3c59x_wake_up
1246
;   Description
1246
;   Description
1247
;      set the power state to D0
1247
;      set the power state to D0
1248
;   Destroyed registers
1248
;   Destroyed registers
1249
;      eax, ebx, ecx, edx, edi, esi
1249
;      eax, ebx, ecx, edx, edi, esi
1250
;
1250
;
1251
;***************************************************************************
1251
;***************************************************************************
1252
        align 4
1252
        align 4
1253
e3c59x_wake_up:
1253
e3c59x_wake_up:
1254
; wake up - we directly do it by programming PCI
1254
; wake up - we directly do it by programming PCI
1255
; check if the device is power management capable
1255
; check if the device is power management capable
1256
        mov     al, 2
1256
        mov     al, 2
1257
        mov     ah, [pci_bus]
1257
        mov     ah, [pci_bus]
1258
        mov     bl, PCI_REG_STATUS
1258
        mov     bl, PCI_REG_STATUS
1259
        mov     bh, [pci_dev]
1259
        mov     bh, [pci_dev]
1260
        push    eax ebx
1260
        push    eax ebx
1261
        call    pci_read_reg
1261
        call    pci_read_reg
1262
        test    al, 10000b ; is there "new capabilities" linked list?
1262
        test    al, 10000b ; is there "new capabilities" linked list?
1263
        pop     ebx eax
1263
        pop     ebx eax
1264
        jz      .device_awake
1264
        jz      .device_awake
1265
; search for power management register
1265
; search for power management register
1266
        mov     al, 1
1266
        mov     al, 1
1267
        mov     bl, PCI_REG_CAP_PTR
1267
        mov     bl, PCI_REG_CAP_PTR
1268
        push    eax ebx
1268
        push    eax ebx
1269
        call    pci_read_reg
1269
        call    pci_read_reg
1270
        mov     cl, al
1270
        mov     cl, al
1271
        cmp     cl, 0x3f
1271
        cmp     cl, 0x3f
1272
        pop     ebx eax
1272
        pop     ebx eax
1273
        jbe     .device_awake
1273
        jbe     .device_awake
1274
; traverse the list
1274
; traverse the list
1275
        mov     al, 2
1275
        mov     al, 2
1276
.pm_loop:
1276
.pm_loop:
1277
        mov     bl, cl
1277
        mov     bl, cl
1278
        push    eax ebx
1278
        push    eax ebx
1279
        call    pci_read_reg
1279
        call    pci_read_reg
1280
        cmp     al, 1
1280
        cmp     al, 1
1281
        je      .set_pm_state
1281
        je      .set_pm_state
1282
        test    ah, ah
1282
        test    ah, ah
1283
        mov     cl, ah
1283
        mov     cl, ah
1284
        pop     ebx eax
1284
        pop     ebx eax
1285
        jnz     .pm_loop
1285
        jnz     .pm_loop
1286
        jmp     .device_awake
1286
        jmp     .device_awake
1287
; waku up the device if necessary
1287
; waku up the device if necessary
1288
.set_pm_state:
1288
.set_pm_state:
1289
        pop     ebx eax
1289
        pop     ebx eax
1290
        add     bl, PCI_REG_PM_CTRL
1290
        add     bl, PCI_REG_PM_CTRL
1291
        push    eax ebx
1291
        push    eax ebx
1292
        call    pci_read_reg
1292
        call    pci_read_reg
1293
        mov     cx, ax
1293
        mov     cx, ax
1294
        test    cl, 3
1294
        test    cl, 3
1295
        pop     ebx eax
1295
        pop     ebx eax
1296
        jz      .device_awake
1296
        jz      .device_awake
1297
        and     cl, not 11b ; set state to D0
1297
        and     cl, not 11b ; set state to D0
1298
        call    pci_write_reg
1298
        call    pci_write_reg
1299
.device_awake:
1299
.device_awake:
1300
        ret
1300
        ret
1301
 
1301
 
1302
;***************************************************************************
1302
;***************************************************************************
1303
;   Function
1303
;   Function
1304
;      e3c59x_probe
1304
;      e3c59x_probe
1305
;   Description
1305
;   Description
1306
;      Searches for an ethernet card, enables it and clears the rx buffer
1306
;      Searches for an ethernet card, enables it and clears the rx buffer
1307
;      If a card was found, it enables the ethernet -> TCPIP link
1307
;      If a card was found, it enables the ethernet -> TCPIP link
1308
;   Destroyed registers
1308
;   Destroyed registers
1309
;      eax, ebx, ecx, edx, edi, esi
1309
;      eax, ebx, ecx, edx, edi, esi
1310
;
1310
;
1311
;***************************************************************************
1311
;***************************************************************************
1312
        align 4
1312
        align 4
1313
e3c59x_probe:
1313
e3c59x_probe:
1314
        movzx   ebp, word [io_addr]
1314
        movzx   ebp, word [io_addr]
1315
        mov     al, 2
1315
        mov     al, 2
1316
        mov     ah, [pci_bus]
1316
        mov     ah, [pci_bus]
1317
        mov     bh, [pci_dev]
1317
        mov     bh, [pci_dev]
1318
        mov     bl, PCI_REG_COMMAND
1318
        mov     bl, PCI_REG_COMMAND
1319
        push    ebp eax ebx
1319
        push    ebp eax ebx
1320
        call    pci_read_reg
1320
        call    pci_read_reg
1321
        mov     cx, ax
1321
        mov     cx, ax
1322
        or      cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
1322
        or      cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
1323
        and     cl, not (1 shl PCI_BIT_MMIO)
1323
        and     cl, not (1 shl PCI_BIT_MMIO)
1324
        pop     ebx eax
1324
        pop     ebx eax
1325
        call    pci_write_reg
1325
        call    pci_write_reg
1326
; wake up the card
1326
; wake up the card
1327
        call    e3c59x_wake_up
1327
        call    e3c59x_wake_up
1328
        pop     ebp
1328
        pop     ebp
1329
; get chip version
1329
; get chip version
1330
        mov     ax, [pci_data+2]
1330
        mov     ax, [pci_data+2]
1331
        mov     ecx, E3C59X_HW_VERSIONS_SIZE/4-1
1331
        mov     ecx, E3C59X_HW_VERSIONS_SIZE/4-1
1332
.chip_ver_loop:
1332
.chip_ver_loop:
1333
        cmp     ax, [e3c59x_hw_versions+ecx*4]
1333
        cmp     ax, [e3c59x_hw_versions+ecx*4]
1334
        jz      .chip_ver_found
1334
        jz      .chip_ver_found
1335
        dec     ecx
1335
        dec     ecx
1336
        jns     .chip_ver_loop
1336
        jns     .chip_ver_loop
1337
        xor     ecx, ecx
1337
        xor     ecx, ecx
1338
.chip_ver_found:
1338
.chip_ver_found:
1339
        mov     [e3c59x_ver_id], cl
1339
        mov     [e3c59x_ver_id], cl
1340
        test    word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM
1340
        test    word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM
1341
        setnz   [e3c59x_has_hwcksm]
1341
        setnz   [e3c59x_has_hwcksm]
1342
; set pci latency for vortex cards
1342
; set pci latency for vortex cards
1343
        test    word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX
1343
        test    word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX
1344
        jz      .not_vortex
1344
        jz      .not_vortex
1345
        mov     cx, 11111000b ; 248 = max latency
1345
        mov     cx, 11111000b ; 248 = max latency
1346
        mov     al, 1
1346
        mov     al, 1
1347
        mov     ah, [pci_bus]
1347
        mov     ah, [pci_bus]
1348
        mov     bl, PCI_REG_LATENCY
1348
        mov     bl, PCI_REG_LATENCY
1349
        mov     bh, [pci_dev]
1349
        mov     bh, [pci_dev]
1350
        call    pci_write_reg
1350
        call    pci_write_reg
1351
.not_vortex:
1351
.not_vortex:
1352
; set RX/TX functions
1352
; set RX/TX functions
1353
        mov     ax, E3C59X_EEPROM_REG_CAPABILITIES
1353
        mov     ax, E3C59X_EEPROM_REG_CAPABILITIES
1354
        call    e3c59x_read_eeprom
1354
        call    e3c59x_read_eeprom
1355
        test    al, 100000b ; full bus master?
1355
        test    al, 100000b ; full bus master?
1356
        setnz   [e3c59x_full_bus_master]
1356
        setnz   [e3c59x_full_bus_master]
1357
        jnz     .boomerang_func
1357
        jnz     .boomerang_func
1358
        mov     dword [e3c59x_transmit_function], e3c59x_vortex_transmit
1358
        mov     dword [e3c59x_transmit_function], e3c59x_vortex_transmit
1359
        mov     dword [e3c59x_receive_function], e3c59x_vortex_poll
1359
        mov     dword [e3c59x_receive_function], e3c59x_vortex_poll
1360
        jmp     @f
1360
        jmp     @f
1361
.boomerang_func: ; full bus master, so use boomerang functions
1361
.boomerang_func: ; full bus master, so use boomerang functions
1362
        mov     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
1362
        mov     dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
1363
        mov     dword [e3c59x_receive_function], e3c59x_boomerang_poll
1363
        mov     dword [e3c59x_receive_function], e3c59x_boomerang_poll
1364
@@:
1364
@@:
1365
; read MAC from eeprom
1365
; read MAC from eeprom
1366
        mov     ecx, 2
1366
        mov     ecx, 2
1367
.mac_loop:
1367
.mac_loop:
1368
        lea     ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx]
1368
        lea     ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx]
1369
        call    e3c59x_read_eeprom
1369
        call    e3c59x_read_eeprom
1370
        xchg    ah, al ; htons
1370
        xchg    ah, al ; htons
1371
        mov     [node_addr+ecx*2], ax
1371
        mov     [node_addr+ecx*2], ax
1372
        dec     ecx
1372
        dec     ecx
1373
        jns     .mac_loop
1373
        jns     .mac_loop
1374
        test    byte [e3c59x_full_bus_master], 0xff
1374
        test    byte [e3c59x_full_bus_master], 0xff
1375
        jz      .set_preamble
1375
        jz      .set_preamble
1376
; switch to register window 2
1376
; switch to register window 2
1377
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1377
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1378
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
1378
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
1379
        out     dx, ax
1379
        out     dx, ax
1380
; activate xcvr by setting some magic bits
1380
; activate xcvr by setting some magic bits
1381
        lea     edx, [ebp+E3C59X_REG_RESET_OPTIONS]
1381
        lea     edx, [ebp+E3C59X_REG_RESET_OPTIONS]
1382
        in      ax, dx
1382
        in      ax, dx
1383
        and     ax, not 0x4010
1383
        and     ax, not 0x4010
1384
        movzx   ebx, byte [e3c59x_ver_id]
1384
        movzx   ebx, byte [e3c59x_ver_id]
1385
        test    word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR
1385
        test    word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR
1386
        jz      @f
1386
        jz      @f
1387
        or      al, 0x10
1387
        or      al, 0x10
1388
@@:
1388
@@:
1389
        test    word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR
1389
        test    word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR
1390
        jz      @f
1390
        jz      @f
1391
        or      ah, 0x40
1391
        or      ah, 0x40
1392
@@:
1392
@@:
1393
        out     dx, ax
1393
        out     dx, ax
1394
.set_preamble:
1394
.set_preamble:
1395
; use preamble as default
1395
; use preamble as default
1396
        mov     byte [e3c59x_preamble], 1 ; enable preamble
1396
        mov     byte [e3c59x_preamble], 1 ; enable preamble
1397
 
1397
 
1398
;***************************************************************************
1398
;***************************************************************************
1399
;   Function
1399
;   Function
1400
;      e3c59x_reset
1400
;      e3c59x_reset
1401
;   Description
1401
;   Description
1402
;      Place the chip (ie, the ethernet card) into a virgin state
1402
;      Place the chip (ie, the ethernet card) into a virgin state
1403
;   Destroyed registers
1403
;   Destroyed registers
1404
;      eax, ebx, ecx, edx, edi, esi
1404
;      eax, ebx, ecx, edx, edi, esi
1405
;
1405
;
1406
;***************************************************************************
1406
;***************************************************************************
1407
e3c59x_reset:
1407
e3c59x_reset:
1408
; issue global reset
1408
; issue global reset
1409
        call    e3c59x_global_reset
1409
        call    e3c59x_global_reset
1410
; disable interrupts
1410
; disable interrupts
1411
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1411
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1412
        mov     ax, (1110b shl 11)
1412
        mov     ax, (1110b shl 11)
1413
        out     dx, ax
1413
        out     dx, ax
1414
; enable Statistics
1414
; enable Statistics
1415
        mov     ax, (10101b shl 11)
1415
        mov     ax, (10101b shl 11)
1416
        out     dx, ax
1416
        out     dx, ax
1417
; set indication
1417
; set indication
1418
        mov     ax, (1111b shl 11) or 0x6c6
1418
        mov     ax, (1111b shl 11) or 0x6c6
1419
        out     dx, ax
1419
        out     dx, ax
1420
; acknowledge (clear) every interrupt indicator
1420
; acknowledge (clear) every interrupt indicator
1421
        mov     ax, (1101b shl 11) or 0x661
1421
        mov     ax, (1101b shl 11) or 0x661
1422
        out     dx, ax
1422
        out     dx, ax
1423
; switch to register window 2
1423
; switch to register window 2
1424
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
1424
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+2
1425
        out     dx, ax
1425
        out     dx, ax
1426
; write MAC addres back into the station address registers
1426
; write MAC addres back into the station address registers
1427
        lea     edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO]
1427
        lea     edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO]
1428
        mov     esi, node_addr
1428
        mov     esi, node_addr
1429
        cld
1429
        cld
1430
        outsw
1430
        outsw
1431
        add     edx, 2
1431
        add     edx, 2
1432
        outsw
1432
        outsw
1433
        add     edx, 2
1433
        add     edx, 2
1434
        outsw
1434
        outsw
1435
        add     edx, 2
1435
        add     edx, 2
1436
; clear station mask
1436
; clear station mask
1437
        xor     eax, eax
1437
        xor     eax, eax
1438
        out     dx, ax
1438
        out     dx, ax
1439
        add     edx, 2
1439
        add     edx, 2
1440
        out     dx, ax
1440
        out     dx, ax
1441
        add     edx, 2
1441
        add     edx, 2
1442
        out     dx, ax
1442
        out     dx, ax
1443
; switch to register window 6
1443
; switch to register window 6
1444
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1444
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1445
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+6
1445
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+6
1446
        out     dx, ax
1446
        out     dx, ax
1447
; clear all statistics by reading
1447
; clear all statistics by reading
1448
        lea     edx, [ebp+E3C59X_REG_CARRIER_LOST]
1448
        lea     edx, [ebp+E3C59X_REG_CARRIER_LOST]
1449
        mov     cl, 9
1449
        mov     cl, 9
1450
.stat_clearing_loop:
1450
.stat_clearing_loop:
1451
        in      al, dx
1451
        in      al, dx
1452
        inc     edx
1452
        inc     edx
1453
        dec     cl
1453
        dec     cl
1454
        jns     .stat_clearing_loop
1454
        jns     .stat_clearing_loop
1455
        in      ax, dx
1455
        in      ax, dx
1456
        add     dx, 2
1456
        add     dx, 2
1457
        in      ax, dx
1457
        in      ax, dx
1458
; switch to register window 4
1458
; switch to register window 4
1459
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1459
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1460
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1460
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1461
        out     dx, ax
1461
        out     dx, ax
1462
; clear BadSSD
1462
; clear BadSSD
1463
        lea     edx, [ebp+E3C59X_REG_BAD_SSD]
1463
        lea     edx, [ebp+E3C59X_REG_BAD_SSD]
1464
        in      al, dx
1464
        in      al, dx
1465
; clear extra statistics bit in NetworkDiagnostic
1465
; clear extra statistics bit in NetworkDiagnostic
1466
        lea     edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC]
1466
        lea     edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC]
1467
        in      ax, dx
1467
        in      ax, dx
1468
        or      ax, 0x0040
1468
        or      ax, 0x0040
1469
        out     dx, ax
1469
        out     dx, ax
1470
; SetRxEarlyThreshold
1470
; SetRxEarlyThreshold
1471
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1471
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1472
        mov     ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2)
1472
        mov     ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2)
1473
        out     dx, ax
1473
        out     dx, ax
1474
        test    byte [e3c59x_full_bus_master], 0xff
1474
        test    byte [e3c59x_full_bus_master], 0xff
1475
        jz      .skip_boomerang_setting
1475
        jz      .skip_boomerang_setting
1476
; set upRxEarlyEnable
1476
; set upRxEarlyEnable
1477
        lea     edx, [ebp+E3C59X_REG_DMA_CTRL]
1477
        lea     edx, [ebp+E3C59X_REG_DMA_CTRL]
1478
        in      eax, dx
1478
        in      eax, dx
1479
        or      eax, 0x20
1479
        or      eax, 0x20
1480
        out     dx, eax
1480
        out     dx, eax
1481
; TxFreeThreshold
1481
; TxFreeThreshold
1482
        lea     edx, [ebp+E3C59X_REG_TX_FREE_THRESH]
1482
        lea     edx, [ebp+E3C59X_REG_TX_FREE_THRESH]
1483
        mov     al, (E3C59X_MAX_ETH_PKT_SIZE / 256)
1483
        mov     al, (E3C59X_MAX_ETH_PKT_SIZE / 256)
1484
        out     dx, al
1484
        out     dx, al
1485
; program DnListPtr
1485
; program DnListPtr
1486
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
1486
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
1487
        xor     eax, eax
1487
        xor     eax, eax
1488
        out     dx, eax
1488
        out     dx, eax
1489
.skip_boomerang_setting:
1489
.skip_boomerang_setting:
1490
; initialization
1490
; initialization
1491
        call    e3c59x_rx_reset
1491
        call    e3c59x_rx_reset
1492
        call    e3c59x_tx_reset
1492
        call    e3c59x_tx_reset
1493
        call    e3c59x_set_active_port
1493
        call    e3c59x_set_active_port
1494
        call    e3c59x_rx_reset
1494
        call    e3c59x_rx_reset
1495
        call    e3c59x_tx_reset
1495
        call    e3c59x_tx_reset
1496
; switch to register window 5
1496
; switch to register window 5
1497
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1497
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1498
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
1498
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+5
1499
        out     dx, ax
1499
        out     dx, ax
1500
; program RxFilter for promiscuous operation
1500
; program RxFilter for promiscuous operation
1501
        mov     ax, (10000b shl 11)
1501
        mov     ax, (10000b shl 11)
1502
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
1502
        lea     edx, [ebp+E3C59X_REG_RX_FILTER]
1503
        in      al, dx
1503
        in      al, dx
1504
        or      al, 1111b
1504
        or      al, 1111b
1505
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1505
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1506
        out     dx, ax
1506
        out     dx, ax
1507
; switch to register window 4
1507
; switch to register window 4
1508
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1508
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1509
        out     dx, ax
1509
        out     dx, ax
1510
; wait for linkDetect
1510
; wait for linkDetect
1511
        lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
1511
        lea     edx, [ebp+E3C59X_REG_MEDIA_STATUS]
1512
        mov     cl, 20 ; wait for max 2s
1512
        mov     cl, 20 ; wait for max 2s
1513
        mov     esi, 100 ; 100ms
1513
        mov     esi, 100 ; 100ms
1514
.link_detect_loop:
1514
.link_detect_loop:
1515
        call    delay_ms
1515
        call    delay_ms
1516
        in      ax, dx
1516
        in      ax, dx
1517
        test    ah, 1000b ; linkDetect
1517
        test    ah, 1000b ; linkDetect
1518
        jnz     @f
1518
        jnz     @f
1519
        dec     cl
1519
        dec     cl
1520
        jnz     .link_detect_loop
1520
        jnz     .link_detect_loop
1521
@@:
1521
@@:
1522
; Indicate that we have successfully reset the card
1522
; Indicate that we have successfully reset the card
1523
        mov     eax, [pci_data]
1523
        mov     eax, [pci_data]
1524
        mov     [eth_status], eax
1524
        mov     [eth_status], eax
1525
if defined E3C59X_DEBUG
1525
if defined E3C59X_DEBUG
1526
        call    e3c59x_debug
1526
        call    e3c59x_debug
1527
end if ; defined E3C59X_DEBUG
1527
end if ; defined E3C59X_DEBUG
1528
        ret
1528
        ret
1529
 
1529
 
1530
;***************************************************************************
1530
;***************************************************************************
1531
;   Function
1531
;   Function
1532
;      e3c59x_global_reset
1532
;      e3c59x_global_reset
1533
;   Description
1533
;   Description
1534
;      resets the device
1534
;      resets the device
1535
;   Parameters:
1535
;   Parameters:
1536
;      ebp - io_addr
1536
;      ebp - io_addr
1537
;   Return value:
1537
;   Return value:
1538
;   Destroyed registers
1538
;   Destroyed registers
1539
;      ax, ecx, edx, esi
1539
;      ax, ecx, edx, esi
1540
;
1540
;
1541
;***************************************************************************
1541
;***************************************************************************
1542
        align 4
1542
        align 4
1543
e3c59x_global_reset:
1543
e3c59x_global_reset:
1544
; GlobalReset
1544
; GlobalReset
1545
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1545
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1546
        xor     eax, eax
1546
        xor     eax, eax
1547
;       or      al, 0x14
1547
;       or      al, 0x14
1548
        out     dx, ax
1548
        out     dx, ax
1549
; wait for GlobalReset to complete
1549
; wait for GlobalReset to complete
1550
        mov     ecx, 64000
1550
        mov     ecx, 64000
1551
.global_reset_loop:
1551
.global_reset_loop:
1552
        in      ax, dx
1552
        in      ax, dx
1553
        test    ah, 10000b ; check CmdInProgress
1553
        test    ah, 10000b ; check CmdInProgress
1554
        jz      .finish
1554
        jz      .finish
1555
        dec     ecx
1555
        dec     ecx
1556
        jnz     .global_reset_loop
1556
        jnz     .global_reset_loop
1557
.finish:
1557
.finish:
1558
; wait for 2 seconds for NIC to boot
1558
; wait for 2 seconds for NIC to boot
1559
        mov     esi, 2000 ; 2000ms = 2s
1559
        mov     esi, 2000 ; 2000ms = 2s
1560
        push    ebp
1560
        push    ebp
1561
        call    delay_ms
1561
        call    delay_ms
1562
        pop     ebp
1562
        pop     ebp
1563
        ret
1563
        ret
1564
 
1564
 
1565
;***************************************************************************
1565
;***************************************************************************
1566
;   Function
1566
;   Function
1567
;      e3c59x_tx_reset
1567
;      e3c59x_tx_reset
1568
;   Description
1568
;   Description
1569
;      resets and enables transmitter engine
1569
;      resets and enables transmitter engine
1570
;   Parameters:
1570
;   Parameters:
1571
;      ebp - io_addr
1571
;      ebp - io_addr
1572
;   Return value:
1572
;   Return value:
1573
;   Destroyed registers
1573
;   Destroyed registers
1574
;      ax, ecx, edx
1574
;      ax, ecx, edx
1575
;
1575
;
1576
;***************************************************************************
1576
;***************************************************************************
1577
        align 4
1577
        align 4
1578
e3c59x_tx_reset:
1578
e3c59x_tx_reset:
1579
; TxReset
1579
; TxReset
1580
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1580
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1581
        mov     ax, (01011b shl 11)
1581
        mov     ax, (01011b shl 11)
1582
        out     dx, ax
1582
        out     dx, ax
1583
; Wait for TxReset to complete
1583
; Wait for TxReset to complete
1584
        mov     ecx, 200000
1584
        mov     ecx, 200000
1585
.tx_reset_loop:
1585
.tx_reset_loop:
1586
        in      ax, dx
1586
        in      ax, dx
1587
        test    ah, 10000b ; check CmdInProgress
1587
        test    ah, 10000b ; check CmdInProgress
1588
        jz      .tx_set_prev
1588
        jz      .tx_set_prev
1589
        dec     ecx
1589
        dec     ecx
1590
        jns     .tx_reset_loop
1590
        jns     .tx_reset_loop
1591
.tx_set_prev:
1591
.tx_set_prev:
1592
        test    byte [e3c59x_full_bus_master], 0xff
1592
        test    byte [e3c59x_full_bus_master], 0xff
1593
        jz      .tx_enable
1593
        jz      .tx_enable
1594
; init last_dpd
1594
; init last_dpd
1595
        mov     dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
1595
        mov     dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
1596
        mov     dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
1596
        mov     dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
1597
.tx_enable:
1597
.tx_enable:
1598
        mov     ax, (01001b shl 11) ; TxEnable
1598
        mov     ax, (01001b shl 11) ; TxEnable
1599
        out     dx, ax
1599
        out     dx, ax
1600
        ret
1600
        ret
1601
 
1601
 
1602
;***************************************************************************
1602
;***************************************************************************
1603
;   Function
1603
;   Function
1604
;      e3c59x_rx_reset
1604
;      e3c59x_rx_reset
1605
;   Description
1605
;   Description
1606
;      resets and enables receiver engine
1606
;      resets and enables receiver engine
1607
;   Parameters:
1607
;   Parameters:
1608
;      ebp - io_addr
1608
;      ebp - io_addr
1609
;   Return value:
1609
;   Return value:
1610
;   Destroyed registers
1610
;   Destroyed registers
1611
;      eax, ebx, ecx, edx, edi, esi
1611
;      eax, ebx, ecx, edx, edi, esi
1612
;
1612
;
1613
;***************************************************************************
1613
;***************************************************************************
1614
        align 4
1614
        align 4
1615
e3c59x_rx_reset:
1615
e3c59x_rx_reset:
1616
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1616
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1617
        mov     ax, (0101b shl 11) or 0x4 ; RxReset
1617
        mov     ax, (0101b shl 11) or 0x4 ; RxReset
1618
        out     dx, ax
1618
        out     dx, ax
1619
; wait for RxReset to complete
1619
; wait for RxReset to complete
1620
        mov     ecx, 200000
1620
        mov     ecx, 200000
1621
.rx_reset_loop:
1621
.rx_reset_loop:
1622
        in      ax, dx
1622
        in      ax, dx
1623
        test    ah, 10000b ; check CmdInProgress
1623
        test    ah, 10000b ; check CmdInProgress
1624
        jz      .setup_upd
1624
        jz      .setup_upd
1625
        dec     ecx
1625
        dec     ecx
1626
        jns     .rx_reset_loop
1626
        jns     .rx_reset_loop
1627
.setup_upd:
1627
.setup_upd:
1628
; check if full bus mastering
1628
; check if full bus mastering
1629
        test    byte [e3c59x_full_bus_master], 0xff
1629
        test    byte [e3c59x_full_bus_master], 0xff
1630
        jz      .rx_enable
1630
        jz      .rx_enable
1631
; create upd ring
1631
; create upd ring
1632
        mov     eax, e3c59x_upd_buff
1632
        mov     eax, e3c59x_upd_buff
1633
        zero_to_virt eax
1633
        zero_to_virt eax
1634
        mov     [e3c59x_curr_upd], eax
1634
        mov     [e3c59x_curr_upd], eax
1635
        mov     esi, eax
1635
        mov     esi, eax
1636
        virt_to_dma esi
1636
        virt_to_dma esi
1637
        mov     edi, e3c59x_rx_buff
1637
        mov     edi, e3c59x_rx_buff
1638
        zero_to_dma edi
1638
        zero_to_dma edi
1639
        mov     ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
1639
        mov     ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
1640
        zero_to_virt ebx
1640
        zero_to_virt ebx
1641
        mov     cl, E3C59X_NUM_RX_DESC-1
1641
        mov     cl, E3C59X_NUM_RX_DESC-1
1642
.upd_loop:
1642
.upd_loop:
1643
        mov     [ebx+E3C59X_UPD_UP_NEXT_PTR], esi
1643
        mov     [ebx+E3C59X_UPD_UP_NEXT_PTR], esi
1644
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
1644
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
1645
        mov     [eax+E3C59X_UPD_UP_FRAG_ADDR], edi
1645
        mov     [eax+E3C59X_UPD_UP_FRAG_ADDR], edi
1646
        mov     dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31)
1646
        mov     dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31)
1647
        add     edi, E3C59X_MAX_ETH_FRAME_SIZE
1647
        add     edi, E3C59X_MAX_ETH_FRAME_SIZE
1648
        add     esi, E3C59X_UPD_SIZE
1648
        add     esi, E3C59X_UPD_SIZE
1649
        mov     ebx, eax
1649
        mov     ebx, eax
1650
        add     eax, E3C59X_UPD_SIZE
1650
        add     eax, E3C59X_UPD_SIZE
1651
        dec     cl
1651
        dec     cl
1652
        jns     .upd_loop
1652
        jns     .upd_loop
1653
        mov     eax, e3c59x_upd_buff
1653
        mov     eax, e3c59x_upd_buff
1654
        zero_to_dma eax
1654
        zero_to_dma eax
1655
        lea     edx, [ebp+E3C59X_REG_UP_LIST_PTR]
1655
        lea     edx, [ebp+E3C59X_REG_UP_LIST_PTR]
1656
        out     dx, eax ; write E3C59X_REG_UP_LIST_PTR
1656
        out     dx, eax ; write E3C59X_REG_UP_LIST_PTR
1657
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1657
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1658
.rx_enable:
1658
.rx_enable:
1659
        mov     ax, (00100b shl 11) ; RxEnable
1659
        mov     ax, (00100b shl 11) ; RxEnable
1660
        out     dx, ax
1660
        out     dx, ax
1661
        ret
1661
        ret
1662
 
1662
 
1663
;***************************************************************************
1663
;***************************************************************************
1664
;   Function
1664
;   Function
1665
;      e3c59x_write_eeprom
1665
;      e3c59x_write_eeprom
1666
;   Description
1666
;   Description
1667
;      reads eeprom
1667
;      reads eeprom
1668
;      Note : the caller must switch to the register window 0
1668
;      Note : the caller must switch to the register window 0
1669
;             before calling this function
1669
;             before calling this function
1670
;   Parameters:
1670
;   Parameters:
1671
;      ax - register to be read (only the first 63 words can be read)
1671
;      ax - register to be read (only the first 63 words can be read)
1672
;      cx - value to be read into the register
1672
;      cx - value to be read into the register
1673
;   Return value:
1673
;   Return value:
1674
;      ax - word read
1674
;      ax - word read
1675
;   Destroyed registers
1675
;   Destroyed registers
1676
;      ax, ebx, edx
1676
;      ax, ebx, edx
1677
;
1677
;
1678
;***************************************************************************
1678
;***************************************************************************
1679
;       align 4
1679
;       align 4
1680
;e3c59x_write_eeprom:
1680
;e3c59x_write_eeprom:
1681
;       mov     edx, [io_addr]
1681
;       mov     edx, [io_addr]
1682
;       add     edx, E3C59X_REG_EEPROM_COMMAND
1682
;       add     edx, E3C59X_REG_EEPROM_COMMAND
1683
;       cmp     ah, 11b
1683
;       cmp     ah, 11b
1684
;       ja      .finish ; address may have a value of maximal 1023
1684
;       ja      .finish ; address may have a value of maximal 1023
1685
;       shl     ax, 2
1685
;       shl     ax, 2
1686
;       shr     al, 2
1686
;       shr     al, 2
1687
;       push    eax
1687
;       push    eax
1688
;; wait for busy
1688
;; wait for busy
1689
;       mov     ebx, 0xffff
1689
;       mov     ebx, 0xffff
1690
;@@:
1690
;@@:
1691
;       in      ax, dx
1691
;       in      ax, dx
1692
;       test    ah, 0x80
1692
;       test    ah, 0x80
1693
;       jz      .write_enable
1693
;       jz      .write_enable
1694
;       dec     ebx
1694
;       dec     ebx
1695
;       jns     @r
1695
;       jns     @r
1696
;; write enable
1696
;; write enable
1697
;.write_enable:
1697
;.write_enable:
1698
;       xor     eax, eax
1698
;       xor     eax, eax
1699
;       mov     eax, (11b shl 4)
1699
;       mov     eax, (11b shl 4)
1700
;       out     dx, ax
1700
;       out     dx, ax
1701
;; wait for busy
1701
;; wait for busy
1702
;       mov     ebx, 0xffff
1702
;       mov     ebx, 0xffff
1703
;@@:
1703
;@@:
1704
;       in      ax, dx
1704
;       in      ax, dx
1705
;       test    ah, 0x80
1705
;       test    ah, 0x80
1706
;       jz      .erase_loop
1706
;       jz      .erase_loop
1707
;       dec     ebx
1707
;       dec     ebx
1708
;       jns     @r
1708
;       jns     @r
1709
;.erase_loop:
1709
;.erase_loop:
1710
;       pop     eax
1710
;       pop     eax
1711
;       push    eax
1711
;       push    eax
1712
;       or      ax, (11b shl 6) ; erase register
1712
;       or      ax, (11b shl 6) ; erase register
1713
;       out     dx, ax
1713
;       out     dx, ax
1714
;       mov     ebx, 0xffff
1714
;       mov     ebx, 0xffff
1715
;@@:
1715
;@@:
1716
;       in      ax, dx
1716
;       in      ax, dx
1717
;       test    ah, 0x80
1717
;       test    ah, 0x80
1718
;       jz      .write_reg
1718
;       jz      .write_reg
1719
;       dec     ebx
1719
;       dec     ebx
1720
;       jns     @r
1720
;       jns     @r
1721
;.write_reg:
1721
;.write_reg:
1722
;       add     edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND
1722
;       add     edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND
1723
;       mov     eax, ecx
1723
;       mov     eax, ecx
1724
;       out     dx, ax
1724
;       out     dx, ax
1725
;; write enable
1725
;; write enable
1726
;       add     edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA
1726
;       add     edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA
1727
;       xor     eax, eax
1727
;       xor     eax, eax
1728
;       mov     eax, (11b shl 4)
1728
;       mov     eax, (11b shl 4)
1729
;       out     dx, ax
1729
;       out     dx, ax
1730
; wait for busy
1730
; wait for busy
1731
;       mov     ebx, 0xffff
1731
;       mov     ebx, 0xffff
1732
;@@:
1732
;@@:
1733
;       in      ax, dx
1733
;       in      ax, dx
1734
;       test    ah, 0x80
1734
;       test    ah, 0x80
1735
;       jz      .issue_write_reg
1735
;       jz      .issue_write_reg
1736
;       dec     ebx
1736
;       dec     ebx
1737
;       jns     @r
1737
;       jns     @r
1738
;.issue_write_reg:
1738
;.issue_write_reg:
1739
;       pop     eax
1739
;       pop     eax
1740
;       or      ax, 01b shl 6
1740
;       or      ax, 01b shl 6
1741
;       out     dx, ax
1741
;       out     dx, ax
1742
;.finish:
1742
;.finish:
1743
;       ret
1743
;       ret
1744
;***************************************************************************
1744
;***************************************************************************
1745
;   Function
1745
;   Function
1746
;      e3c59x_read_eeprom
1746
;      e3c59x_read_eeprom
1747
;   Description
1747
;   Description
1748
;      reads eeprom
1748
;      reads eeprom
1749
;   Parameters:
1749
;   Parameters:
1750
;       ax - register to be read (only the first 63 words can be read)
1750
;       ax - register to be read (only the first 63 words can be read)
1751
;      ebp - io_addr
1751
;      ebp - io_addr
1752
;   Return value:
1752
;   Return value:
1753
;      ax - word read
1753
;      ax - word read
1754
;   Destroyed registers
1754
;   Destroyed registers
1755
;      ax, ebx, edx, ebp
1755
;      ax, ebx, edx, ebp
1756
;
1756
;
1757
;***************************************************************************
1757
;***************************************************************************
1758
        align 4
1758
        align 4
1759
e3c59x_read_eeprom:
1759
e3c59x_read_eeprom:
1760
        push    eax
1760
        push    eax
1761
; switch to register window 0
1761
; switch to register window 0
1762
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1762
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1763
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+0
1763
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+0
1764
        out     dx, ax
1764
        out     dx, ax
1765
        pop     eax
1765
        pop     eax
1766
        and     ax, 111111b ; take only the first 6 bits into account
1766
        and     ax, 111111b ; take only the first 6 bits into account
1767
        movzx   ebx, byte [e3c59x_ver_id]
1767
        movzx   ebx, byte [e3c59x_ver_id]
1768
        test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT
1768
        test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT
1769
        jz      @f
1769
        jz      @f
1770
        add     ax, 0x230 ; hardware constant
1770
        add     ax, 0x230 ; hardware constant
1771
        jmp     .read
1771
        jmp     .read
1772
@@:
1772
@@:
1773
        add     ax, E3C59X_EEPROM_CMD_READ
1773
        add     ax, E3C59X_EEPROM_CMD_READ
1774
        test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET
1774
        test    word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET
1775
        jz      .read
1775
        jz      .read
1776
        add     ax, 0x30
1776
        add     ax, 0x30
1777
.read:
1777
.read:
1778
        lea     edx, [ebp+E3C59X_REG_EEPROM_COMMAND]
1778
        lea     edx, [ebp+E3C59X_REG_EEPROM_COMMAND]
1779
        out     dx, ax
1779
        out     dx, ax
1780
        mov     ebx, 0xffff ; duration of about 162 us ;-)
1780
        mov     ebx, 0xffff ; duration of about 162 us ;-)
1781
.wait_for_reading:
1781
.wait_for_reading:
1782
        in      ax, dx
1782
        in      ax, dx
1783
        test    ah, 0x80 ; check bit eepromBusy
1783
        test    ah, 0x80 ; check bit eepromBusy
1784
        jz      .read_data
1784
        jz      .read_data
1785
        dec     ebx
1785
        dec     ebx
1786
        jns     .wait_for_reading
1786
        jns     .wait_for_reading
1787
.read_data:
1787
.read_data:
1788
        lea     edx, [ebp+E3C59X_REG_EEPROM_DATA]
1788
        lea     edx, [ebp+E3C59X_REG_EEPROM_DATA]
1789
        in      ax, dx
1789
        in      ax, dx
1790
        ret
1790
        ret
1791
 
1791
 
1792
;***************************************************************************
1792
;***************************************************************************
1793
;   Function
1793
;   Function
1794
;      e3c59x_mdio_sync
1794
;      e3c59x_mdio_sync
1795
;   Description
1795
;   Description
1796
;      initial synchronization
1796
;      initial synchronization
1797
;   Parameters
1797
;   Parameters
1798
;      ebp - io_addr
1798
;      ebp - io_addr
1799
;   Return value
1799
;   Return value
1800
;   Destroyed registers
1800
;   Destroyed registers
1801
;      ax, edx, cl
1801
;      ax, edx, cl
1802
;
1802
;
1803
;***************************************************************************
1803
;***************************************************************************
1804
        align 4
1804
        align 4
1805
e3c59x_mdio_sync:
1805
e3c59x_mdio_sync:
1806
; switch to register window 4
1806
; switch to register window 4
1807
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1807
        lea     edx, [ebp+E3C59X_REG_COMMAND]
1808
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1808
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+4
1809
        out     dx, ax
1809
        out     dx, ax
1810
        cmp     byte [e3c59x_preamble], 0
1810
        cmp     byte [e3c59x_preamble], 0
1811
        je      .no_preamble
1811
        je      .no_preamble
1812
; send 32 logic ones
1812
; send 32 logic ones
1813
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1813
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1814
        mov     cl, 31
1814
        mov     cl, 31
1815
.loop:
1815
.loop:
1816
        mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR)
1816
        mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR)
1817
        out     dx, ax
1817
        out     dx, ax
1818
        in      ax, dx ; delay
1818
        in      ax, dx ; delay
1819
        mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) \
1819
        mov     ax, (1 shl E3C59X_BIT_MGMT_DATA) \
1820
                or (1 shl E3C59X_BIT_MGMT_DIR) \
1820
                or (1 shl E3C59X_BIT_MGMT_DIR) \
1821
                or (1 shl E3C59X_BIT_MGMT_CLK)
1821
                or (1 shl E3C59X_BIT_MGMT_CLK)
1822
        out     dx, ax
1822
        out     dx, ax
1823
        in      ax, dx ; delay
1823
        in      ax, dx ; delay
1824
        dec     cl
1824
        dec     cl
1825
        jns     .loop
1825
        jns     .loop
1826
.no_preamble:
1826
.no_preamble:
1827
        ret
1827
        ret
1828
 
1828
 
1829
;***************************************************************************
1829
;***************************************************************************
1830
;   Function
1830
;   Function
1831
;      e3c59x_mdio_read
1831
;      e3c59x_mdio_read
1832
;   Description
1832
;   Description
1833
;      read MII register
1833
;      read MII register
1834
;      see page 16 in D83840A.pdf
1834
;      see page 16 in D83840A.pdf
1835
;   Parameters
1835
;   Parameters
1836
;       ah - PHY addr
1836
;       ah - PHY addr
1837
;       al - register addr
1837
;       al - register addr
1838
;      ebp - io_addr
1838
;      ebp - io_addr
1839
;   Return value
1839
;   Return value
1840
;      ax - register read
1840
;      ax - register read
1841
;   Destroyed registers
1841
;   Destroyed registers
1842
;      eax, ebx, cx, edx
1842
;      eax, ebx, cx, edx
1843
;
1843
;
1844
;***************************************************************************
1844
;***************************************************************************
1845
        align 4
1845
        align 4
1846
e3c59x_mdio_read:
1846
e3c59x_mdio_read:
1847
        push    eax
1847
        push    eax
1848
        call    e3c59x_mdio_sync ; returns with window #4
1848
        call    e3c59x_mdio_sync ; returns with window #4
1849
        pop     eax
1849
        pop     eax
1850
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1850
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1851
        shl     al, 3
1851
        shl     al, 3
1852
        shr     ax, 3
1852
        shr     ax, 3
1853
        and     ax, not E3C59X_MII_CMD_MASK
1853
        and     ax, not E3C59X_MII_CMD_MASK
1854
        or      ax, E3C59X_MII_CMD_READ
1854
        or      ax, E3C59X_MII_CMD_READ
1855
        mov     ebx, eax
1855
        mov     ebx, eax
1856
        xor     ecx, ecx
1856
        xor     ecx, ecx
1857
        mov     cl, 13
1857
        mov     cl, 13
1858
.cmd_loop:
1858
.cmd_loop:
1859
        mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
1859
        mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
1860
        bt      ebx, ecx
1860
        bt      ebx, ecx
1861
        jnc     .zero_bit
1861
        jnc     .zero_bit
1862
        or      al, (1 shl E3C59X_BIT_MGMT_DATA)
1862
        or      al, (1 shl E3C59X_BIT_MGMT_DATA)
1863
.zero_bit:
1863
.zero_bit:
1864
        out     dx, ax
1864
        out     dx, ax
1865
        push    eax
1865
        push    eax
1866
        in      ax, dx ; delay
1866
        in      ax, dx ; delay
1867
        pop     eax
1867
        pop     eax
1868
        or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
1868
        or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
1869
        out     dx, ax
1869
        out     dx, ax
1870
        in      ax, dx ; delay
1870
        in      ax, dx ; delay
1871
        dec     cl
1871
        dec     cl
1872
        jns     .cmd_loop
1872
        jns     .cmd_loop
1873
; read data (18 bits with the two transition bits)
1873
; read data (18 bits with the two transition bits)
1874
        mov     cl, 17
1874
        mov     cl, 17
1875
        xor     ebx, ebx
1875
        xor     ebx, ebx
1876
.read_loop:
1876
.read_loop:
1877
        shl     ebx, 1
1877
        shl     ebx, 1
1878
        xor     eax, eax ; read comand
1878
        xor     eax, eax ; read comand
1879
        out     dx, ax
1879
        out     dx, ax
1880
        in      ax, dx ; delay
1880
        in      ax, dx ; delay
1881
        in      ax, dx
1881
        in      ax, dx
1882
        test    al, (1 shl E3C59X_BIT_MGMT_DATA)
1882
        test    al, (1 shl E3C59X_BIT_MGMT_DATA)
1883
        jz      .dont_set
1883
        jz      .dont_set
1884
        inc     ebx
1884
        inc     ebx
1885
.dont_set:
1885
.dont_set:
1886
        mov     ax, (1 shl E3C59X_BIT_MGMT_CLK)
1886
        mov     ax, (1 shl E3C59X_BIT_MGMT_CLK)
1887
        out     dx, ax
1887
        out     dx, ax
1888
        in      ax, dx ; delay
1888
        in      ax, dx ; delay
1889
        dec     cl
1889
        dec     cl
1890
        jns     .read_loop
1890
        jns     .read_loop
1891
        mov     eax, ebx
1891
        mov     eax, ebx
1892
        ret
1892
        ret
1893
 
1893
 
1894
;***************************************************************************
1894
;***************************************************************************
1895
;   Function
1895
;   Function
1896
;      e3c59x_mdio_write
1896
;      e3c59x_mdio_write
1897
;   Description
1897
;   Description
1898
;      write MII register
1898
;      write MII register
1899
;      see page 16 in D83840A.pdf
1899
;      see page 16 in D83840A.pdf
1900
;   Parameters
1900
;   Parameters
1901
;       ah - PHY addr
1901
;       ah - PHY addr
1902
;       al - register addr
1902
;       al - register addr
1903
;       bx - word to be written
1903
;       bx - word to be written
1904
;      ebp - io_addr
1904
;      ebp - io_addr
1905
;   Return value
1905
;   Return value
1906
;      ax - register read
1906
;      ax - register read
1907
;   Destroyed registers
1907
;   Destroyed registers
1908
;      eax, ebx, cx, edx
1908
;      eax, ebx, cx, edx
1909
;
1909
;
1910
;***************************************************************************
1910
;***************************************************************************
1911
        align 4
1911
        align 4
1912
e3c59x_mdio_write:
1912
e3c59x_mdio_write:
1913
        push    eax
1913
        push    eax
1914
        call    e3c59x_mdio_sync
1914
        call    e3c59x_mdio_sync
1915
        pop     eax
1915
        pop     eax
1916
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1916
        lea     edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
1917
        shl     al, 3
1917
        shl     al, 3
1918
        shr     ax, 3
1918
        shr     ax, 3
1919
        and     ax, not E3C59X_MII_CMD_MASK
1919
        and     ax, not E3C59X_MII_CMD_MASK
1920
        or      ax, E3C59X_MII_CMD_WRITE
1920
        or      ax, E3C59X_MII_CMD_WRITE
1921
        shl     eax, 2
1921
        shl     eax, 2
1922
        or      eax, 10b ; transition bits
1922
        or      eax, 10b ; transition bits
1923
        shl     eax, 16
1923
        shl     eax, 16
1924
        mov     ax, bx
1924
        mov     ax, bx
1925
        mov     ebx, eax
1925
        mov     ebx, eax
1926
        mov     ecx, 31
1926
        mov     ecx, 31
1927
.cmd_loop:
1927
.cmd_loop:
1928
        mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
1928
        mov     ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
1929
        bt      ebx, ecx
1929
        bt      ebx, ecx
1930
        jnc     .zero_bit
1930
        jnc     .zero_bit
1931
        or      al, (1 shl E3C59X_BIT_MGMT_DATA)
1931
        or      al, (1 shl E3C59X_BIT_MGMT_DATA)
1932
.zero_bit:
1932
.zero_bit:
1933
        out     dx, ax
1933
        out     dx, ax
1934
        push    eax
1934
        push    eax
1935
        in      ax, dx ; delay
1935
        in      ax, dx ; delay
1936
        pop     eax
1936
        pop     eax
1937
        or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
1937
        or      al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
1938
        out     dx, ax
1938
        out     dx, ax
1939
        in      ax, dx ; delay
1939
        in      ax, dx ; delay
1940
        dec     ecx
1940
        dec     ecx
1941
        jns     .cmd_loop
1941
        jns     .cmd_loop
1942
        ret
1942
        ret
1943
 
1943
 
1944
;***************************************************************************
1944
;***************************************************************************
1945
;   Function
1945
;   Function
1946
;      e3c59x_transmit
1946
;      e3c59x_transmit
1947
;   Description
1947
;   Description
1948
;      Transmits a packet of data via the ethernet card
1948
;      Transmits a packet of data via the ethernet card
1949
;         edi - Pointer to 48 bit destination address
1949
;         edi - Pointer to 48 bit destination address
1950
;          bx - Type of packet
1950
;          bx - Type of packet
1951
;         ecx - size of packet
1951
;         ecx - size of packet
1952
;         esi - pointer to packet data
1952
;         esi - pointer to packet data
1953
;         ebp - io_addr
1953
;         ebp - io_addr
1954
;   Destroyed registers
1954
;   Destroyed registers
1955
;      eax, ecx, edx, ebp
1955
;      eax, ecx, edx, ebp
1956
;
1956
;
1957
;***************************************************************************
1957
;***************************************************************************
1958
        align 4
1958
        align 4
1959
e3c59x_transmit:
1959
e3c59x_transmit:
1960
        jmp     dword [e3c59x_transmit_function]
1960
        jmp     dword [e3c59x_transmit_function]
1961
 
1961
 
1962
;***************************************************************************
1962
;***************************************************************************
1963
;   Function
1963
;   Function
1964
;      e3c59x_check_tx_status
1964
;      e3c59x_check_tx_status
1965
;   Description
1965
;   Description
1966
;      Checks TxStatus queue.
1966
;      Checks TxStatus queue.
1967
;   Return value
1967
;   Return value
1968
;      al - 0 no error was found
1968
;      al - 0 no error was found
1969
;      al - 1 error was found TxReset is needed
1969
;      al - 1 error was found TxReset is needed
1970
;   Destroyed registers
1970
;   Destroyed registers
1971
;      eax, ecx, edx, ebp
1971
;      eax, ecx, edx, ebp
1972
;
1972
;
1973
;***************************************************************************
1973
;***************************************************************************
1974
e3c59x_check_tx_status:
1974
e3c59x_check_tx_status:
1975
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
1975
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
1976
; clear TxStatus queue
1976
; clear TxStatus queue
1977
        lea     edx, [ebp+E3C59X_REG_TX_STATUS]
1977
        lea     edx, [ebp+E3C59X_REG_TX_STATUS]
1978
        mov     cl, 31 ; max number of queue entries
1978
        mov     cl, 31 ; max number of queue entries
1979
.tx_status_loop:
1979
.tx_status_loop:
1980
        in      al, dx
1980
        in      al, dx
1981
        test    al, al
1981
        test    al, al
1982
        jz      .finish ; no error
1982
        jz      .finish ; no error
1983
        test    al, 0x3f
1983
        test    al, 0x3f
1984
        jnz     .finish ; error
1984
        jnz     .finish ; error
1985
.no_error_found:
1985
.no_error_found:
1986
; clear current TxStatus entry which advances the next one
1986
; clear current TxStatus entry which advances the next one
1987
        xor     al, al
1987
        xor     al, al
1988
        out     dx, al
1988
        out     dx, al
1989
        dec     cl
1989
        dec     cl
1990
        jns     .tx_status_loop
1990
        jns     .tx_status_loop
1991
.finish:
1991
.finish:
1992
        ret
1992
        ret
1993
 
1993
 
1994
;***************************************************************************
1994
;***************************************************************************
1995
;   Function
1995
;   Function
1996
;      e3c59x_vortex_transmit
1996
;      e3c59x_vortex_transmit
1997
;   Description
1997
;   Description
1998
;      Transmits a packet of data via the ethernet card
1998
;      Transmits a packet of data via the ethernet card
1999
;         edi - Pointer to 48 bit destination address
1999
;         edi - Pointer to 48 bit destination address
2000
;          bx - Type of packet
2000
;          bx - Type of packet
2001
;         ecx - size of packet
2001
;         ecx - size of packet
2002
;         esi - pointer to packet data
2002
;         esi - pointer to packet data
2003
;         ebp - io_addr
2003
;         ebp - io_addr
2004
;   Destroyed registers
2004
;   Destroyed registers
2005
;      eax, edx, ecx, edi, esi, ebp
2005
;      eax, edx, ecx, edi, esi, ebp
2006
;
2006
;
2007
;***************************************************************************
2007
;***************************************************************************
2008
        align 4
2008
        align 4
2009
e3c59x_vortex_transmit:
2009
e3c59x_vortex_transmit:
2010
        push    ecx
2010
        push    ecx
2011
        call    e3c59x_check_tx_status
2011
        call    e3c59x_check_tx_status
2012
        pop     ecx
2012
        pop     ecx
2013
        test    al, al
2013
        test    al, al
2014
        jz      .no_error_found
2014
        jz      .no_error_found
2015
        jmp     e3c59x_tx_reset
2015
        jmp     e3c59x_tx_reset
2016
.no_error_found:
2016
.no_error_found:
2017
; switch to register window 7
2017
; switch to register window 7
2018
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2018
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2019
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
2019
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
2020
        out     dx, ax
2020
        out     dx, ax
2021
; check for master operation in progress
2021
; check for master operation in progress
2022
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2022
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2023
        in      ax, dx
2023
        in      ax, dx
2024
        test    ah, 0x80
2024
        test    ah, 0x80
2025
        jnz     .finish ; no DMA for sending
2025
        jnz     .finish ; no DMA for sending
2026
; dword boundary correction
2026
; dword boundary correction
2027
        cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
2027
        cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
2028
        ja      .finish ; packet is too long
2028
        ja      .finish ; packet is too long
2029
; write Frame Start Header
2029
; write Frame Start Header
2030
        mov     eax, ecx
2030
        mov     eax, ecx
2031
; add header length and extend the complete length to dword boundary
2031
; add header length and extend the complete length to dword boundary
2032
        add     eax, ETH_HLEN+3
2032
        add     eax, ETH_HLEN+3
2033
        and     eax, not 3
2033
        and     eax, not 3
2034
        lea     edx, [ebp+E3C59X_REG_TX_DATA]
2034
        lea     edx, [ebp+E3C59X_REG_TX_DATA]
2035
        out     dx, eax
2035
        out     dx, eax
2036
; prepare the complete frame
2036
; prepare the complete frame
2037
        push    esi
2037
        push    esi
2038
        mov     esi, edi
2038
        mov     esi, edi
2039
        mov     edi, e3c59x_tx_buff
2039
        mov     edi, e3c59x_tx_buff
2040
        zero_to_virt edi
2040
        zero_to_virt edi
2041
        cld
2041
        cld
2042
; copy destination address
2042
; copy destination address
2043
        movsd
2043
        movsd
2044
        movsw
2044
        movsw
2045
; copy source address
2045
; copy source address
2046
        mov     esi, node_addr
2046
        mov     esi, node_addr
2047
        movsd
2047
        movsd
2048
        movsw
2048
        movsw
2049
; copy packet type
2049
; copy packet type
2050
        mov     [edi], bx
2050
        mov     [edi], bx
2051
        add     edi, 2
2051
        add     edi, 2
2052
; copy packet data
2052
; copy packet data
2053
        pop     esi
2053
        pop     esi
2054
        push    ecx
2054
        push    ecx
2055
        shr     ecx, 2
2055
        shr     ecx, 2
2056
        rep movsd
2056
        rep movsd
2057
        pop     ecx
2057
        pop     ecx
2058
        and     ecx, 3
2058
        and     ecx, 3
2059
        rep movsb
2059
        rep movsb
2060
        mov     ecx, eax
2060
        mov     ecx, eax
2061
; program frame address to be sent
2061
; program frame address to be sent
2062
        lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
2062
        lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
2063
        mov     eax, e3c59x_tx_buff
2063
        mov     eax, e3c59x_tx_buff
2064
        zero_to_dma eax
2064
        zero_to_dma eax
2065
        out     dx, eax
2065
        out     dx, eax
2066
; program frame length
2066
; program frame length
2067
        lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
2067
        lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
2068
        mov     eax, ecx
2068
        mov     eax, ecx
2069
        out     dx, ax
2069
        out     dx, ax
2070
; start DMA Down
2070
; start DMA Down
2071
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2071
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2072
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2072
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2073
        out     dx, ax
2073
        out     dx, ax
2074
.finish:
2074
.finish:
2075
        ret
2075
        ret
2076
 
2076
 
2077
;***************************************************************************
2077
;***************************************************************************
2078
;   Function
2078
;   Function
2079
;      e3c59x_boomerang_transmit
2079
;      e3c59x_boomerang_transmit
2080
;   Description
2080
;   Description
2081
;      Transmits a packet of data via the ethernet card
2081
;      Transmits a packet of data via the ethernet card
2082
;         edi - Pointer to 48 bit destination address
2082
;         edi - Pointer to 48 bit destination address
2083
;          bx - Type of packet
2083
;          bx - Type of packet
2084
;         ecx - size of packet
2084
;         ecx - size of packet
2085
;         esi - pointer to packet data
2085
;         esi - pointer to packet data
2086
;         ebp - io_addr
2086
;         ebp - io_addr
2087
;   Destroyed registers
2087
;   Destroyed registers
2088
;      eax, ebx, ecx, edx, esi, edi, ebp
2088
;      eax, ebx, ecx, edx, esi, edi, ebp
2089
;
2089
;
2090
;***************************************************************************
2090
;***************************************************************************
2091
        align 4
2091
        align 4
2092
e3c59x_boomerang_transmit:
2092
e3c59x_boomerang_transmit:
2093
        push    ecx
2093
        push    ecx
2094
        call    e3c59x_check_tx_status
2094
        call    e3c59x_check_tx_status
2095
        pop     ecx
2095
        pop     ecx
2096
        test    al, al
2096
        test    al, al
2097
        jz      .no_error_found
2097
        jz      .no_error_found
2098
        jmp     e3c59x_tx_reset
2098
        jmp     e3c59x_tx_reset
2099
.no_error_found:
2099
.no_error_found:
2100
        cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
2100
        cmp     ecx, E3C59X_MAX_ETH_FRAME_SIZE
2101
        ja      .finish ; packet is too long
2101
        ja      .finish ; packet is too long
2102
; calculate descriptor address
2102
; calculate descriptor address
2103
        mov     eax, [e3c59x_prev_dpd]
2103
        mov     eax, [e3c59x_prev_dpd]
2104
        cmp     eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
2104
        cmp     eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
2105
        jb      @f
2105
        jb      @f
2106
; wrap around
2106
; wrap around
2107
        mov     eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE
2107
        mov     eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE
2108
@@:
2108
@@:
2109
        add     eax, E3C59X_DPD_SIZE
2109
        add     eax, E3C59X_DPD_SIZE
2110
        zero_to_virt eax
2110
        zero_to_virt eax
2111
        push    eax
2111
        push    eax
2112
; check DnListPtr
2112
; check DnListPtr
2113
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
2113
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
2114
        in      eax, dx
2114
        in      eax, dx
2115
; mark if Dn_List_Ptr is cleared
2115
; mark if Dn_List_Ptr is cleared
2116
        test    eax, eax
2116
        test    eax, eax
2117
        setz    [e3c59x_dn_list_ptr_cleared]
2117
        setz    [e3c59x_dn_list_ptr_cleared]
2118
; finish if no more free descriptor is available - FIXME!
2118
; finish if no more free descriptor is available - FIXME!
2119
        cmp     eax, [esp]
2119
        cmp     eax, [esp]
2120
        pop     eax
2120
        pop     eax
2121
        jz      .finish
2121
        jz      .finish
2122
        push    eax esi
2122
        push    eax esi
2123
        mov     esi, edi
2123
        mov     esi, edi
2124
; calculate tx_buffer address
2124
; calculate tx_buffer address
2125
        mov     edi, [e3c59x_prev_tx_frame]
2125
        mov     edi, [e3c59x_prev_tx_frame]
2126
        cmp     edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
2126
        cmp     edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
2127
        jb      @f
2127
        jb      @f
2128
; wrap around
2128
; wrap around
2129
        mov     edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE
2129
        mov     edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE
2130
@@:
2130
@@:
2131
        add     edi, E3C59X_MAX_ETH_FRAME_SIZE
2131
        add     edi, E3C59X_MAX_ETH_FRAME_SIZE
2132
        zero_to_virt edi
2132
        zero_to_virt edi
2133
        mov     eax, edi
2133
        mov     eax, edi
2134
        cld
2134
        cld
2135
; copy destination address
2135
; copy destination address
2136
        movsd
2136
        movsd
2137
        movsw
2137
        movsw
2138
; copy source address
2138
; copy source address
2139
        mov     esi, node_addr
2139
        mov     esi, node_addr
2140
        movsd
2140
        movsd
2141
        movsw
2141
        movsw
2142
; copy packet type
2142
; copy packet type
2143
        mov     [edi], bx
2143
        mov     [edi], bx
2144
        add     edi, 2
2144
        add     edi, 2
2145
; copy packet data
2145
; copy packet data
2146
        pop     esi
2146
        pop     esi
2147
        push    ecx
2147
        push    ecx
2148
        shr     ecx, 2
2148
        shr     ecx, 2
2149
        rep movsd
2149
        rep movsd
2150
        pop     ecx
2150
        pop     ecx
2151
        push    ecx
2151
        push    ecx
2152
        and     ecx, 3
2152
        and     ecx, 3
2153
        rep movsb
2153
        rep movsb
2154
; padding, do we really need it?
2154
; padding, do we really need it?
2155
        pop     ecx
2155
        pop     ecx
2156
        add     ecx, ETH_HLEN
2156
        add     ecx, ETH_HLEN
2157
        cmp     ecx, ETH_ZLEN
2157
        cmp     ecx, ETH_ZLEN
2158
        jae     @f
2158
        jae     @f
2159
        mov     ecx, ETH_ZLEN
2159
        mov     ecx, ETH_ZLEN
2160
@@:
2160
@@:
2161
; calculate
2161
; calculate
2162
        mov     ebx, ecx
2162
        mov     ebx, ecx
2163
        ;test   byte [e3c59x_has_hwcksm], 0xff
2163
        ;test   byte [e3c59x_has_hwcksm], 0xff
2164
        ;jz     @f
2164
        ;jz     @f
2165
        ;or      ebx, (1 shl 26) ; set AddTcpChecksum
2165
        ;or      ebx, (1 shl 26) ; set AddTcpChecksum
2166
;@@:
2166
;@@:
2167
        or      ebx, 0x8000 ; transmission complete notification
2167
        or      ebx, 0x8000 ; transmission complete notification
2168
        or      ecx, 0x80000000 ; last fragment
2168
        or      ecx, 0x80000000 ; last fragment
2169
; program DPD
2169
; program DPD
2170
        mov     edi, eax
2170
        mov     edi, eax
2171
        pop     eax
2171
        pop     eax
2172
        and     dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0
2172
        and     dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0
2173
        mov     dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx
2173
        mov     dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx
2174
        virt_to_dma edi
2174
        virt_to_dma edi
2175
        mov     dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi
2175
        mov     dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi
2176
        mov     [eax+E3C59X_DPD_DN_FRAG_LEN], ecx
2176
        mov     [eax+E3C59X_DPD_DN_FRAG_LEN], ecx
2177
; calculate physical address
2177
; calculate physical address
2178
        virt_to_dma eax
2178
        virt_to_dma eax
2179
        push    eax
2179
        push    eax
2180
        cmp     byte [e3c59x_dn_list_ptr_cleared], 0
2180
        cmp     byte [e3c59x_dn_list_ptr_cleared], 0
2181
        jz      .add_to_list
2181
        jz      .add_to_list
2182
; write Dn_List_Ptr
2182
; write Dn_List_Ptr
2183
        out     dx, eax
2183
        out     dx, eax
2184
        jmp     .finish
2184
        jmp     .finish
2185
.add_to_list:
2185
.add_to_list:
2186
; DnStall
2186
; DnStall
2187
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2187
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2188
        mov     ax, ((110b shl 11)+2)
2188
        mov     ax, ((110b shl 11)+2)
2189
        out     dx, ax
2189
        out     dx, ax
2190
; wait for DnStall to complete
2190
; wait for DnStall to complete
2191
        mov     ecx, 6000
2191
        mov     ecx, 6000
2192
.wait_for_stall:
2192
.wait_for_stall:
2193
        in      ax, dx ; read E3C59X_REG_INT_STATUS
2193
        in      ax, dx ; read E3C59X_REG_INT_STATUS
2194
        test    ah, 10000b
2194
        test    ah, 10000b
2195
        jz      .dnstall_ok
2195
        jz      .dnstall_ok
2196
        dec     ecx
2196
        dec     ecx
2197
        jnz     .wait_for_stall
2197
        jnz     .wait_for_stall
2198
.dnstall_ok:
2198
.dnstall_ok:
2199
        pop     eax
2199
        pop     eax
2200
        push    eax
2200
        push    eax
2201
        mov     ebx, [e3c59x_prev_dpd]
2201
        mov     ebx, [e3c59x_prev_dpd]
2202
        zero_to_virt ebx
2202
        zero_to_virt ebx
2203
        mov     [ebx], eax
2203
        mov     [ebx], eax
2204
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
2204
        lea     edx, [ebp+E3C59X_REG_DN_LIST_PTR]
2205
        in      eax, dx
2205
        in      eax, dx
2206
        test    eax, eax
2206
        test    eax, eax
2207
        jnz     .dnunstall
2207
        jnz     .dnunstall
2208
; if Dn_List_Ptr has been cleared fill it up
2208
; if Dn_List_Ptr has been cleared fill it up
2209
        pop     eax
2209
        pop     eax
2210
        push    eax
2210
        push    eax
2211
        out     dx, eax
2211
        out     dx, eax
2212
.dnunstall:
2212
.dnunstall:
2213
; DnUnStall
2213
; DnUnStall
2214
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2214
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2215
        mov     ax, ((110b shl 11)+3)
2215
        mov     ax, ((110b shl 11)+3)
2216
        out     dx, ax
2216
        out     dx, ax
2217
.finish:
2217
.finish:
2218
        pop     eax
2218
        pop     eax
2219
        dma_to_zero eax
2219
        dma_to_zero eax
2220
        mov     [e3c59x_prev_dpd], eax
2220
        mov     [e3c59x_prev_dpd], eax
2221
        dma_to_zero edi
2221
        dma_to_zero edi
2222
        mov     [e3c59x_prev_tx_frame], edi
2222
        mov     [e3c59x_prev_tx_frame], edi
2223
        ret
2223
        ret
2224
 
2224
 
2225
;***************************************************************************
2225
;***************************************************************************
2226
; Function
2226
; Function
2227
;    e3c59x_poll
2227
;    e3c59x_poll
2228
; Description
2228
; Description
2229
;    Polls the ethernet card for a received packet
2229
;    Polls the ethernet card for a received packet
2230
;    Received data, if any, ends up in Ether_buffer
2230
;    Received data, if any, ends up in Ether_buffer
2231
; Destroyed registers
2231
; Destroyed registers
2232
;    eax, ebx, edx, ecx, edi, esi, ebp
2232
;    eax, ebx, edx, ecx, edi, esi, ebp
2233
;
2233
;
2234
;***************************************************************************
2234
;***************************************************************************
2235
        align 4
2235
        align 4
2236
e3c59x_poll:
2236
e3c59x_poll:
2237
        jmp     dword [e3c59x_receive_function]
2237
        jmp     dword [e3c59x_receive_function]
2238
 
2238
 
2239
;***************************************************************************
2239
;***************************************************************************
2240
; Function
2240
; Function
2241
;    e3c59x_vortex_poll
2241
;    e3c59x_vortex_poll
2242
; Description
2242
; Description
2243
;    Polls the ethernet card for a received packet
2243
;    Polls the ethernet card for a received packet
2244
;    Received data, if any, ends up in Ether_buffer
2244
;    Received data, if any, ends up in Ether_buffer
2245
; Parameters
2245
; Parameters
2246
;    ebp - io_addr
2246
;    ebp - io_addr
2247
; Return value
2247
; Return value
2248
;    al - 0 ; no packet received
2248
;    al - 0 ; no packet received
2249
;    al - 1 ; packet received
2249
;    al - 1 ; packet received
2250
; Destroyed registers
2250
; Destroyed registers
2251
;    eax, ebx, edx, ecx, edi, esi, ebp
2251
;    eax, ebx, edx, ecx, edi, esi, ebp
2252
;
2252
;
2253
;***************************************************************************
2253
;***************************************************************************
2254
        align 4
2254
        align 4
2255
e3c59x_vortex_poll:
2255
e3c59x_vortex_poll:
2256
        and     word [eth_rx_data_len], 0 ; assume no packet received
2256
        and     word [eth_rx_data_len], 0 ; assume no packet received
2257
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
2257
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
2258
.rx_status_loop:
2258
.rx_status_loop:
2259
; examine RxStatus
2259
; examine RxStatus
2260
        lea     edx, [ebp+E3C59X_REG_RX_STATUS]
2260
        lea     edx, [ebp+E3C59X_REG_RX_STATUS]
2261
        in      ax, dx
2261
        in      ax, dx
2262
        test    ax, ax
2262
        test    ax, ax
2263
        jz      .finish
2263
        jz      .finish
2264
        test    ah, 0x80 ; rxIncomplete
2264
        test    ah, 0x80 ; rxIncomplete
2265
        jz      .check_error
2265
        jz      .check_error
2266
        jmp     .finish
2266
        jmp     .finish
2267
.check_error:
2267
.check_error:
2268
        test    ah, 0x40
2268
        test    ah, 0x40
2269
        jz      .check_length
2269
        jz      .check_length
2270
; discard the top frame received advancing the next one
2270
; discard the top frame received advancing the next one
2271
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2271
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2272
        mov     ax, (01000b shl 11)
2272
        mov     ax, (01000b shl 11)
2273
        out     dx, ax
2273
        out     dx, ax
2274
        jmp     .rx_status_loop
2274
        jmp     .rx_status_loop
2275
.check_length:
2275
.check_length:
2276
        and     eax, 0x1fff
2276
        and     eax, 0x1fff
2277
        cmp     eax, E3C59X_MAX_ETH_PKT_SIZE
2277
        cmp     eax, E3C59X_MAX_ETH_PKT_SIZE
2278
        ja      .discard_frame ; frame is too long discard it
2278
        ja      .discard_frame ; frame is too long discard it
2279
.check_dma:
2279
.check_dma:
2280
        push    eax
2280
        push    eax
2281
; switch to register window 7
2281
; switch to register window 7
2282
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2282
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2283
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
2283
        mov     ax, E3C59X_SELECT_REGISTER_WINDOW+7
2284
        out     dx, ax
2284
        out     dx, ax
2285
; check for master operation in progress
2285
; check for master operation in progress
2286
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2286
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2287
        in      ax, dx
2287
        in      ax, dx
2288
        test    ah, 0x80
2288
        test    ah, 0x80
2289
        jz      .read_frame ; no DMA for receiving
2289
        jz      .read_frame ; no DMA for receiving
2290
        pop     eax
2290
        pop     eax
2291
        jmp     .finish
2291
        jmp     .finish
2292
.read_frame:
2292
.read_frame:
2293
; program buffer address to read in
2293
; program buffer address to read in
2294
        lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
2294
        lea     edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
2295
if defined E3C59X_LINUX
2295
if defined E3C59X_LINUX
2296
        mov     eax, e3c59x_rx_buff
2296
        mov     eax, e3c59x_rx_buff
2297
        zero_to_dma eax
2297
        zero_to_dma eax
2298
else
2298
else
2299
        mov     eax, Ether_buffer
2299
        mov     eax, Ether_buffer
2300
end if
2300
end if
2301
        out     dx, eax
2301
        out     dx, eax
2302
; program frame length
2302
; program frame length
2303
        lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
2303
        lea     edx, [ebp+E3C59X_REG_MASTER_LEN]
2304
        mov     ax, 1560
2304
        mov     ax, 1560
2305
        out     dx, ax
2305
        out     dx, ax
2306
; start DMA Up
2306
; start DMA Up
2307
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2307
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2308
        mov     ax, (10100b shl 11) ; StartDMAUp
2308
        mov     ax, (10100b shl 11) ; StartDMAUp
2309
        out     dx, ax
2309
        out     dx, ax
2310
; check for master operation in progress
2310
; check for master operation in progress
2311
.dma_loop:
2311
.dma_loop:
2312
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2312
        lea     edx, [ebp+E3C59X_REG_MASTER_STATUS]
2313
        in      ax, dx
2313
        in      ax, dx
2314
        test    ah, 0x80
2314
        test    ah, 0x80
2315
        jnz     .dma_loop
2315
        jnz     .dma_loop
2316
; registrate the received packet length
2316
; registrate the received packet length
2317
        pop     eax
2317
        pop     eax
2318
        mov     word [eth_rx_data_len], ax
2318
        mov     word [eth_rx_data_len], ax
2319
; discard the top frame received
2319
; discard the top frame received
2320
.discard_frame:
2320
.discard_frame:
2321
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2321
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2322
        mov     ax, (01000b shl 11)
2322
        mov     ax, (01000b shl 11)
2323
        out     dx, ax
2323
        out     dx, ax
2324
.finish:
2324
.finish:
2325
; set return value
2325
; set return value
2326
        cmp     word [eth_rx_data_len], 0
2326
        cmp     word [eth_rx_data_len], 0
2327
        setne   al
2327
        setne   al
2328
        ret
2328
        ret
2329
 
2329
 
2330
;***************************************************************************
2330
;***************************************************************************
2331
; Function
2331
; Function
2332
;    e3c59x_boomerang_poll
2332
;    e3c59x_boomerang_poll
2333
; Description
2333
; Description
2334
;    Polls the ethernet card for a received packet
2334
;    Polls the ethernet card for a received packet
2335
;    Received data, if any, ends up in Ether_buffer
2335
;    Received data, if any, ends up in Ether_buffer
2336
; Parameters
2336
; Parameters
2337
;    ebp - io_addr
2337
;    ebp - io_addr
2338
; Return value
2338
; Return value
2339
;    al - 0 ; no packet received
2339
;    al - 0 ; no packet received
2340
;    al - 1 ; packet received
2340
;    al - 1 ; packet received
2341
; Destroyed registers
2341
; Destroyed registers
2342
;    eax, edx, ecx, edi, esi, ebp
2342
;    eax, edx, ecx, edi, esi, ebp
2343
;
2343
;
2344
;***************************************************************************
2344
;***************************************************************************
2345
        align 4
2345
        align 4
2346
e3c59x_boomerang_poll:
2346
e3c59x_boomerang_poll:
2347
        and     word [eth_rx_data_len], 0 ; assume no packet received
2347
        and     word [eth_rx_data_len], 0 ; assume no packet received
2348
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
2348
        movzx   ebp, word [io_addr] ; to be implemented in ETHERNET.INC
2349
; check if packet is uploaded
2349
; check if packet is uploaded
2350
        mov     eax, [e3c59x_curr_upd]
2350
        mov     eax, [e3c59x_curr_upd]
2351
        test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete
2351
        test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete
2352
        jnz     .check_error
2352
        jnz     .check_error
2353
        jmp     .finish
2353
        jmp     .finish
2354
; packet is uploaded check for any error
2354
; packet is uploaded check for any error
2355
.check_error:
2355
.check_error:
2356
        test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError
2356
        test    byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError
2357
        jz      .copy_packet_length
2357
        jz      .copy_packet_length
2358
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2358
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2359
        jmp     .finish
2359
        jmp     .finish
2360
.copy_packet_length:
2360
.copy_packet_length:
2361
        mov     ecx, [eax+E3C59X_UPD_PKT_STATUS]
2361
        mov     ecx, [eax+E3C59X_UPD_PKT_STATUS]
2362
        and     ecx, 0x1fff
2362
        and     ecx, 0x1fff
2363
        cmp     ecx, E3C59X_MAX_ETH_PKT_SIZE
2363
        cmp     ecx, E3C59X_MAX_ETH_PKT_SIZE
2364
        jbe     .copy_packet
2364
        jbe     .copy_packet
2365
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2365
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2366
        jmp     .finish
2366
        jmp     .finish
2367
.copy_packet:
2367
.copy_packet:
2368
        push    ecx
2368
        push    ecx
2369
        mov     word [eth_rx_data_len], cx
2369
        mov     word [eth_rx_data_len], cx
2370
        mov     esi, [eax+E3C59X_UPD_UP_FRAG_ADDR]
2370
        mov     esi, [eax+E3C59X_UPD_UP_FRAG_ADDR]
2371
        dma_to_virt esi
2371
        dma_to_virt esi
2372
        mov     edi, Ether_buffer
2372
        mov     edi, Ether_buffer
2373
        shr     ecx, 2 ; first copy dword-wise
2373
        shr     ecx, 2 ; first copy dword-wise
2374
        cld
2374
        cld
2375
        rep movsd     ; copy the dwords
2375
        rep movsd     ; copy the dwords
2376
        pop     ecx
2376
        pop     ecx
2377
        and     ecx, 3
2377
        and     ecx, 3
2378
        rep movsb     ; copy the rest bytes
2378
        rep movsb     ; copy the rest bytes
2379
        mov     eax, [e3c59x_curr_upd]
2379
        mov     eax, [e3c59x_curr_upd]
2380
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2380
        and     dword [eax+E3C59X_UPD_PKT_STATUS], 0
2381
        virt_to_zero eax
2381
        virt_to_zero eax
2382
        cmp     eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
2382
        cmp     eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
2383
        jb      .no_wrap
2383
        jb      .no_wrap
2384
; wrap around
2384
; wrap around
2385
        mov     eax, e3c59x_upd_buff-E3C59X_UPD_SIZE
2385
        mov     eax, e3c59x_upd_buff-E3C59X_UPD_SIZE
2386
.no_wrap:
2386
.no_wrap:
2387
        add     eax, E3C59X_UPD_SIZE
2387
        add     eax, E3C59X_UPD_SIZE
2388
        zero_to_virt eax
2388
        zero_to_virt eax
2389
        mov     [e3c59x_curr_upd], eax
2389
        mov     [e3c59x_curr_upd], eax
2390
.finish:
2390
.finish:
2391
; check if the NIC is in the upStall state
2391
; check if the NIC is in the upStall state
2392
        lea     edx, [ebp+E3C59X_REG_UP_PKT_STATUS]
2392
        lea     edx, [ebp+E3C59X_REG_UP_PKT_STATUS]
2393
        in      eax, dx
2393
        in      eax, dx
2394
        test    ah, 0x20 ; UpStalled
2394
        test    ah, 0x20 ; UpStalled
2395
        jz      .noUpUnStall
2395
        jz      .noUpUnStall
2396
; issue upUnStall command
2396
; issue upUnStall command
2397
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2397
        lea     edx, [ebp+E3C59X_REG_COMMAND]
2398
        mov     ax, ((110b shl 11)+1) ; upUnStall
2398
        mov     ax, ((110b shl 11)+1) ; upUnStall
2399
        out     dx, ax
2399
        out     dx, ax
2400
.noUpUnStall:
2400
.noUpUnStall:
2401
; set return value
2401
; set return value
2402
        cmp     word [eth_rx_data_len], 0
2402
        cmp     word [eth_rx_data_len], 0
2403
        setnz   al
2403
        setnz   al
2404
        ret
2404
        ret