Subversion Repositories Kolibri OS

Rev

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

Rev 5194 Rev 5247
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;; i8255x (Intel eepro 100) driver for KolibriOS                   ;;
6
;; i8255x (Intel eepro 100) driver for KolibriOS                   ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;    Written by hidnplayr@kolibrios.org                           ;;
8
;;    Written by hidnplayr@kolibrios.org                           ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;; Some parts of this driver are based on the code of eepro100.c   ;;
13
;; Some parts of this driver are based on the code of eepro100.c   ;;
14
;;  from linux.                                                    ;;
14
;;  from linux.                                                    ;;
15
;;                                                                 ;;
15
;;                                                                 ;;
16
;; Intel's programming manual for i8255x:                          ;;
16
;; Intel's programming manual for i8255x:                          ;;
17
;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
17
;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
18
;;                                                                 ;;
18
;;                                                                 ;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
 
20
 
21
; TODO: use separate descriptors in memory instead of placing them in front of packets!
21
; TODO: use separate descriptors in memory instead of placing them in front of packets!
22
 
22
 
23
 
23
 
24
format PE DLL native
24
format PE DLL native
25
entry START
25
entry START
26
 
26
 
27
        CURRENT_API             = 0x0200
27
        CURRENT_API             = 0x0200
28
        COMPATIBLE_API          = 0x0100
28
        COMPATIBLE_API          = 0x0100
29
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
29
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
30
 
30
 
31
        MAX_DEVICES             = 16
31
        MAX_DEVICES             = 16
32
 
32
 
33
        DEBUG                   = 1
33
        DEBUG                   = 1
34
        __DEBUG__               = 1
34
        __DEBUG__               = 1
35
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
35
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
36
 
36
 
37
section '.flat' readable writable executable
37
section '.flat' readable writable executable
38
 
38
 
39
include '../proc32.inc'
39
include '../proc32.inc'
40
include '../struct.inc'
40
include '../struct.inc'
41
include '../macros.inc'
41
include '../macros.inc'
42
include '../fdo.inc'
42
include '../fdo.inc'
43
include '../netdrv.inc'
43
include '../netdrv.inc'
44
 
44
 
45
; Serial EEPROM
45
; Serial EEPROM
46
 
46
 
47
EE_SK           = 1 shl 0      ; serial clock
47
EE_SK           = 1 shl 0      ; serial clock
48
EE_CS           = 1 shl 1      ; chip select
48
EE_CS           = 1 shl 1      ; chip select
49
EE_DI           = 1 shl 2      ; data in
49
EE_DI           = 1 shl 2      ; data in
50
EE_DO           = 1 shl 3      ; data out
50
EE_DO           = 1 shl 3      ; data out
51
EE_MASK         = EE_SK + EE_CS + EE_DI + EE_DO
51
EE_MASK         = EE_SK + EE_CS + EE_DI + EE_DO
52
 
52
 
53
; opcodes, first bit is start bit and must be 1
53
; opcodes, first bit is start bit and must be 1
54
EE_READ         = 110b
54
EE_READ         = 110b
55
EE_WRITE        = 101b
55
EE_WRITE        = 101b
56
EE_ERASE        = 111b
56
EE_ERASE        = 111b
57
 
57
 
58
; The SCB accepts the following controls for the Tx and Rx units:
58
; The SCB accepts the following controls for the Tx and Rx units:
59
 
59
 
60
CU_START        = 0x0010
60
CU_START        = 0x0010
61
CU_RESUME       = 0x0020
61
CU_RESUME       = 0x0020
62
CU_STATSADDR    = 0x0040
62
CU_STATSADDR    = 0x0040
63
CU_SHOWSTATS    = 0x0050        ; Dump statistics counters.
63
CU_SHOWSTATS    = 0x0050        ; Dump statistics counters.
64
CU_CMD_BASE     = 0x0060        ; Base address to add CU commands.
64
CU_CMD_BASE     = 0x0060        ; Base address to add CU commands.
65
CU_DUMPSTATS    = 0x0070        ; Dump then reset stats counters.
65
CU_DUMPSTATS    = 0x0070        ; Dump then reset stats counters.
66
 
66
 
67
RX_START        = 0x0001
67
RX_START        = 0x0001
68
RX_RESUME       = 0x0002
68
RX_RESUME       = 0x0002
69
RX_ABORT        = 0x0004
69
RX_ABORT        = 0x0004
70
RX_ADDR_LOAD    = 0x0006
70
RX_ADDR_LOAD    = 0x0006
71
RX_RESUMENR     = 0x0007
71
RX_RESUMENR     = 0x0007
72
INT_MASK        = 0x0100
72
INT_MASK        = 0x0100
73
DRVR_INT        = 0x0200        ; Driver generated interrupt
73
DRVR_INT        = 0x0200        ; Driver generated interrupt
74
 
74
 
75
CmdIASetup      = 0x0001
75
CmdIASetup      = 0x0001
76
CmdConfigure    = 0x0002
76
CmdConfigure    = 0x0002
77
CmdTx           = 0x0004
77
CmdTx           = 0x0004
78
CmdTxFlex       = 0x0008
78
CmdTxFlex       = 0x0008
79
Cmdsuspend      = 0x4000
79
Cmdsuspend      = 0x4000
80
 
80
 
81
reg_scb_status  = 0
81
reg_scb_status  = 0
82
reg_scb_cmd     = 2
82
reg_scb_cmd     = 2
83
reg_scb_ptr     = 4
83
reg_scb_ptr     = 4
84
reg_port        = 8
84
reg_port        = 8
85
reg_eeprom      = 14
85
reg_eeprom      = 14
86
reg_mdi_ctrl    = 16
86
reg_mdi_ctrl    = 16
87
 
87
 
88
phy_100a        = 0x000003E0
88
phy_100a        = 0x000003E0
89
phy_100c        = 0x035002A8
89
phy_100c        = 0x035002A8
90
phy_82555_tx    = 0x015002A8
90
phy_82555_tx    = 0x015002A8
91
phy_nsc_tx      = 0x5C002000
91
phy_nsc_tx      = 0x5C002000
92
phy_82562_et    = 0x033002A8
92
phy_82562_et    = 0x033002A8
93
phy_82562_em    = 0x032002A8
93
phy_82562_em    = 0x032002A8
94
phy_82562_ek    = 0x031002A8
94
phy_82562_ek    = 0x031002A8
95
phy_82562_eh    = 0x017002A8
95
phy_82562_eh    = 0x017002A8
96
phy_82552_v     = 0xd061004d
96
phy_82552_v     = 0xd061004d
97
phy_unknown     = 0xFFFFFFFF
97
phy_unknown     = 0xFFFFFFFF
98
 
98
 
99
mac_82557_D100_A        = 0
99
mac_82557_D100_A        = 0
100
mac_82557_D100_B        = 1     
100
mac_82557_D100_B        = 1     
101
mac_82557_D100_C        = 2     
101
mac_82557_D100_C        = 2     
102
mac_82558_D101_A4       = 4     
102
mac_82558_D101_A4       = 4     
103
mac_82558_D101_B0       = 5     
103
mac_82558_D101_B0       = 5     
104
mac_82559_D101M         = 8     
104
mac_82559_D101M         = 8     
105
mac_82559_D101S         = 9     
105
mac_82559_D101S         = 9     
106
mac_82550_D102          = 12    
106
mac_82550_D102          = 12    
107
mac_82550_D102_C        = 13    
107
mac_82550_D102_C        = 13    
108
mac_82551_E             = 14    
108
mac_82551_E             = 14    
109
mac_82551_F             = 15    
109
mac_82551_F             = 15    
110
mac_82551_10            = 16    
110
mac_82551_10            = 16    
111
mac_unknown             = 0xFF
111
mac_unknown             = 0xFF
112
 
112
 
113
struct  rxfd
113
struct  rxfd
114
 
114
 
115
        status          dw ?
115
        status          dw ?
116
        command         dw ?
116
        command         dw ?
117
        link            dd ?
117
        link            dd ?
118
        rx_buf_addr     dd ?
118
        rx_buf_addr     dd ?
119
        count           dw ?
119
        count           dw ?
120
        size            dw ?
120
        size            dw ?
121
        packet          rb 1500
121
        packet          rb 1500
122
 
122
 
123
ends
123
ends
124
 
124
 
125
struc   txfd {
125
struc   txfd {
126
 
126
 
127
        .status         dw ?
127
        .status         dw ?
128
        .command        dw ?
128
        .command        dw ?
129
        .link           dd ?
129
        .link           dd ?
130
        .desc_addr      dd ?
130
        .desc_addr      dd ?
131
        .count          dd ?
131
        .count          dd ?
132
 
132
 
133
        .buf_addr0      dd ?
133
        .buf_addr0      dd ?
134
        .buf_size0      dd ?
134
        .buf_size0      dd ?
135
 
135
 
136
}
136
}
137
 
137
 
138
struc   confcmd {
138
struc   confcmd {
139
 
139
 
140
        .status         dw ?
140
        .status         dw ?
141
        .command        dw ?
141
        .command        dw ?
142
        .link           dd ?
142
        .link           dd ?
143
        .data           rb 64
143
        .data           rb 64
144
 
144
 
145
}
145
}
146
 
146
 
147
struc   lstats {
147
struc   lstats {
148
 
148
 
149
        .tx_good_frames         dd ?
149
        .tx_good_frames         dd ?
150
        .tx_coll16_errs         dd ?
150
        .tx_coll16_errs         dd ?
151
        .tx_late_colls          dd ?
151
        .tx_late_colls          dd ?
152
        .tx_underruns           dd ?
152
        .tx_underruns           dd ?
153
        .tx_lost_carrier        dd ?
153
        .tx_lost_carrier        dd ?
154
        .tx_deferred            dd ?
154
        .tx_deferred            dd ?
155
        .tx_one_colls           dd ?
155
        .tx_one_colls           dd ?
156
        .tx_multi_colls         dd ?
156
        .tx_multi_colls         dd ?
157
        .tx_total_colls         dd ?
157
        .tx_total_colls         dd ?
158
 
158
 
159
        .rx_good_frames         dd ?
159
        .rx_good_frames         dd ?
160
        .rx_crc_errs            dd ?
160
        .rx_crc_errs            dd ?
161
        .rx_align_errs          dd ?
161
        .rx_align_errs          dd ?
162
        .rx_resource_errs       dd ?
162
        .rx_resource_errs       dd ?
163
        .rx_overrun_errs        dd ?
163
        .rx_overrun_errs        dd ?
164
        .rx_colls_errs          dd ?
164
        .rx_colls_errs          dd ?
165
        .rx_runt_errs           dd ?
165
        .rx_runt_errs           dd ?
166
 
166
 
167
}
167
}
168
 
168
 
169
struct  device          ETH_DEVICE
169
struct  device          ETH_DEVICE
170
 
170
 
171
        io_addr         dd ?
171
        io_addr         dd ?
172
        pci_bus         dd ?
172
        pci_bus         dd ?
173
        pci_dev         dd ?
173
        pci_dev         dd ?
174
        rx_desc         dd ?
174
        rx_desc         dd ?
175
        last_tx_buffer  dd ?
175
        last_tx_buffer  dd ?
176
        ee_bus_width    db ?
176
        ee_bus_width    db ?
177
        irq_line        db ?
177
        irq_line        db ?
178
 
178
 
179
        rb 0x100 - ($ and 0xff) ; align 256
179
        rb 0x100 - ($ and 0xff) ; align 256
180
        txfd            txfd
180
        txfd            txfd
181
 
181
 
182
        rb 0x100 - ($ and 0xff) ; align 256
182
        rb 0x100 - ($ and 0xff) ; align 256
183
        confcmd         confcmd
183
        confcmd         confcmd
184
 
184
 
185
        rb 0x100 - ($ and 0xff) ; align 256
185
        rb 0x100 - ($ and 0xff) ; align 256
186
        lstats          lstats
186
        lstats          lstats
187
 
187
 
188
ends
188
ends
189
 
-
 
190
macro delay {
-
 
191
        push    eax
-
 
192
        in      ax, dx
-
 
193
        in      ax, dx
-
 
194
        in      ax, dx
-
 
195
        in      ax, dx
-
 
196
        in      ax, dx
-
 
197
        in      ax, dx
-
 
198
        in      ax, dx
-
 
199
        in      ax, dx
-
 
200
        in      ax, dx
-
 
201
        in      ax, dx
-
 
202
        pop     eax
-
 
203
}
-
 
204
 
189
 
205
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
206
;;                        ;;
191
;;                        ;;
207
;; proc START             ;;
192
;; proc START             ;;
208
;;                        ;;
193
;;                        ;;
209
;; (standard driver proc) ;;
194
;; (standard driver proc) ;;
210
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
195
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
211
 
196
 
212
proc START c, state:dword
197
proc START c, state:dword
213
 
198
 
214
        cmp [state], 1
199
        cmp [state], 1
215
        jne .exit
200
        jne .exit
216
 
201
 
217
  .entry:
202
  .entry:
218
 
203
 
219
        DEBUGF 1,"Loading driver\n"
204
        DEBUGF 1,"Loading driver\n"
220
        invoke  RegService, my_service, service_proc
205
        invoke  RegService, my_service, service_proc
221
        ret
206
        ret
222
 
207
 
223
  .fail:
208
  .fail:
224
  .exit:
209
  .exit:
225
        xor eax, eax
210
        xor eax, eax
226
        ret
211
        ret
227
 
212
 
228
endp
213
endp
229
 
214
 
230
 
215
 
231
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
216
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
232
;;                        ;;
217
;;                        ;;
233
;; proc SERVICE_PROC      ;;
218
;; proc SERVICE_PROC      ;;
234
;;                        ;;
219
;;                        ;;
235
;; (standard driver proc) ;;
220
;; (standard driver proc) ;;
236
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
221
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
237
 
222
 
238
align 4
223
align 4
239
proc service_proc stdcall, ioctl:dword
224
proc service_proc stdcall, ioctl:dword
240
 
225
 
241
        mov     edx, [ioctl]
226
        mov     edx, [ioctl]
242
        mov     eax, [edx + IOCTL.io_code]
227
        mov     eax, [edx + IOCTL.io_code]
243
 
228
 
244
;------------------------------------------------------
229
;------------------------------------------------------
245
 
230
 
246
        cmp     eax, 0 ;SRV_GETVERSION
231
        cmp     eax, 0 ;SRV_GETVERSION
247
        jne     @F
232
        jne     @F
248
 
233
 
249
        cmp     [edx + IOCTL.out_size], 4
234
        cmp     [edx + IOCTL.out_size], 4
250
        jb      .fail
235
        jb      .fail
251
        mov     eax, [edx + IOCTL.output]
236
        mov     eax, [edx + IOCTL.output]
252
        mov     [eax], dword API_VERSION
237
        mov     [eax], dword API_VERSION
253
 
238
 
254
        xor     eax, eax
239
        xor     eax, eax
255
        ret
240
        ret
256
 
241
 
257
;------------------------------------------------------
242
;------------------------------------------------------
258
  @@:
243
  @@:
259
        cmp     eax, 1 ;SRV_HOOK
244
        cmp     eax, 1 ;SRV_HOOK
260
        jne     .fail
245
        jne     .fail
261
 
246
 
262
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
247
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
263
        jb      .fail
248
        jb      .fail
264
 
249
 
265
        mov     eax, [edx + IOCTL.input]
250
        mov     eax, [edx + IOCTL.input]
266
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
251
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
267
        jne     .fail                                   ; other types arent supported for this card yet
252
        jne     .fail                                   ; other types arent supported for this card yet
268
 
253
 
269
; check if the device is already listed
254
; check if the device is already listed
270
 
255
 
271
        mov     esi, device_list
256
        mov     esi, device_list
272
        mov     ecx, [devices]
257
        mov     ecx, [devices]
273
        test    ecx, ecx
258
        test    ecx, ecx
274
        jz      .firstdevice
259
        jz      .firstdevice
275
 
260
 
276
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
261
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
277
        mov     ax , [eax+1]                            ;
262
        mov     ax , [eax+1]                            ;
278
  .nextdevice:
263
  .nextdevice:
279
        mov     ebx, [esi]
264
        mov     ebx, [esi]
280
        cmp     al, byte[ebx + device.pci_bus]
265
        cmp     al, byte[ebx + device.pci_bus]
281
        jne     @f
266
        jne     @f
282
        cmp     ah, byte[ebx + device.pci_dev]
267
        cmp     ah, byte[ebx + device.pci_dev]
283
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
268
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
284
       @@:
269
       @@:
285
        add     esi, 4
270
        add     esi, 4
286
        loop    .nextdevice
271
        loop    .nextdevice
287
 
272
 
288
 
273
 
289
; This device doesnt have its own eth_device structure yet, lets create one
274
; This device doesnt have its own eth_device structure yet, lets create one
290
  .firstdevice:
275
  .firstdevice:
291
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
276
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
292
        jae     .fail
277
        jae     .fail
293
 
278
 
294
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
279
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
295
 
280
 
296
; Fill in the direct call addresses into the struct
281
; Fill in the direct call addresses into the struct
297
 
282
 
298
        mov     [ebx + device.reset], reset
283
        mov     [ebx + device.reset], reset
299
        mov     [ebx + device.transmit], transmit
284
        mov     [ebx + device.transmit], transmit
300
        mov     [ebx + device.unload], unload
285
        mov     [ebx + device.unload], unload
301
        mov     [ebx + device.name], my_service
286
        mov     [ebx + device.name], my_service
302
 
287
 
303
; save the pci bus and device numbers
288
; save the pci bus and device numbers
304
 
289
 
305
        mov     eax, [edx + IOCTL.input]
290
        mov     eax, [edx + IOCTL.input]
306
        movzx   ecx, byte[eax+1]
291
        movzx   ecx, byte[eax+1]
307
        mov     [ebx + device.pci_bus], ecx
292
        mov     [ebx + device.pci_bus], ecx
308
        movzx   ecx, byte[eax+2]
293
        movzx   ecx, byte[eax+2]
309
        mov     [ebx + device.pci_dev], ecx
294
        mov     [ebx + device.pci_dev], ecx
310
 
295
 
311
; Now, it's time to find the base io addres of the PCI device
296
; Now, it's time to find the base io addres of the PCI device
312
 
297
 
313
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
298
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
314
        mov     [ebx + device.io_addr], eax
299
        mov     [ebx + device.io_addr], eax
315
 
300
 
316
; We've found the io address, find IRQ now
301
; We've found the io address, find IRQ now
317
 
302
 
318
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
303
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
319
        mov     [ebx + device.irq_line], al
304
        mov     [ebx + device.irq_line], al
320
 
305
 
321
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
306
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
322
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
307
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
323
 
308
 
324
; Ok, the eth_device structure is ready, let's probe the device
309
; Ok, the eth_device structure is ready, let's probe the device
325
 
310
 
326
        pushf
311
        pushf
327
        cli                     ; disable ints untilm initialisation is done
312
        cli                     ; disable ints untilm initialisation is done
328
 
313
 
329
        call    probe                                                   ; this function will output in eax
314
        call    probe                                                   ; this function will output in eax
330
        test    eax, eax
315
        test    eax, eax
331
        jnz     .err                                                    ; If an error occured, exit
316
        jnz     .err                                                    ; If an error occured, exit
332
 
317
 
333
        mov     eax, [devices]                                          ; Add the device structure to our device list
318
        mov     eax, [devices]                                          ; Add the device structure to our device list
334
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
319
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
335
        inc     [devices]                                               ;
320
        inc     [devices]                                               ;
336
 
321
 
337
        popf
322
        popf
338
 
323
 
339
        mov     [ebx + device.type], NET_TYPE_ETH
324
        mov     [ebx + device.type], NET_TYPE_ETH
340
        invoke  NetRegDev
325
        invoke  NetRegDev
341
 
326
 
342
        cmp     eax, -1
327
        cmp     eax, -1
343
        je      .err
328
        je      .err
344
 
329
 
345
        ret
330
        ret
346
 
331
 
347
; If the device was already loaded, find the device number and return it in eax
332
; If the device was already loaded, find the device number and return it in eax
348
 
333
 
349
  .find_devicenum:
334
  .find_devicenum:
350
        DEBUGF  2,"Trying to find device number of already registered device\n"
335
        DEBUGF  2,"Trying to find device number of already registered device\n"
351
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
336
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
352
                                                                        ; into a device number in edi
337
                                                                        ; into a device number in edi
353
        mov     eax, edi                                                ; Application wants it in eax instead
338
        mov     eax, edi                                                ; Application wants it in eax instead
354
        DEBUGF  2,"Kernel says: %u\n", eax
339
        DEBUGF  2,"Kernel says: %u\n", eax
355
        ret
340
        ret
356
 
341
 
357
; If an error occured, remove all allocated data and exit (returning -1 in eax)
342
; If an error occured, remove all allocated data and exit (returning -1 in eax)
358
 
343
 
359
  .err:
344
  .err:
360
        invoke  KernelFree, ebx
345
        invoke  KernelFree, ebx
361
 
346
 
362
  .fail:
347
  .fail:
363
        or      eax, -1
348
        or      eax, -1
364
        ret
349
        ret
365
 
350
 
366
;------------------------------------------------------
351
;------------------------------------------------------
367
endp
352
endp
368
 
353
 
369
 
354
 
370
 
355
 
371
 
356
 
372
 
357
 
373
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
358
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
374
;;                                                                        ;;
359
;;                                                                        ;;
375
;;        Actual Hardware dependent code starts here                      ;;
360
;;        Actual Hardware dependent code starts here                      ;;
376
;;                                                                        ;;
361
;;                                                                        ;;
377
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
362
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
378
 
363
 
379
 
364
 
380
unload:
365
unload:
381
        ; TODO: (in this particular order)
366
        ; TODO: (in this particular order)
382
        ;
367
        ;
383
        ; - Stop the device
368
        ; - Stop the device
384
        ; - Detach int handler
369
        ; - Detach int handler
385
        ; - Remove device from local list (device_list)
370
        ; - Remove device from local list (device_list)
386
        ; - call unregister function in kernel
371
        ; - call unregister function in kernel
387
        ; - Remove all allocated structures and buffers the card used
372
        ; - Remove all allocated structures and buffers the card used
388
 
373
 
389
        or      eax,-1
374
        or      eax,-1
390
 
375
 
391
ret
376
ret
392
 
377
 
393
 
378
 
394
;-------------
379
;-------------
395
;
380
;
396
; Probe
381
; Probe
397
;
382
;
398
;-------------
383
;-------------
399
 
384
 
400
align 4
385
align 4
401
probe:
386
probe:
402
 
387
 
403
        DEBUGF  1,"Probing\n"
388
        DEBUGF  1,"Probing\n"
404
 
389
 
405
; Make the device a bus master
390
; Make the device a bus master
406
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
391
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
407
        or      al, PCI_CMD_MASTER
392
        or      al, PCI_CMD_MASTER
408
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
393
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
409
 
394
 
410
;---------------------------
395
;---------------------------
411
; First, identify the device
396
; First, identify the device
412
 
397
 
413
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.vendor_id ; get device/vendor id
398
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.vendor_id ; get device/vendor id
414
 
399
 
415
        DEBUGF  1,"Vendor_id=0x%x\n", ax
400
        DEBUGF  1,"Vendor_id=0x%x\n", ax
416
 
401
 
417
        cmp     ax, 0x8086
402
        cmp     ax, 0x8086
418
        jne     .notfound
403
        jne     .notfound
419
        shr     eax, 16
404
        shr     eax, 16
420
 
405
 
421
        DEBUGF  1,"Device_id=0x%x\n", ax
406
        DEBUGF  1,"Device_id=0x%x\n", ax
422
 
407
 
423
        mov     ecx, DEVICE_IDs
408
        mov     ecx, DEVICE_IDs
424
        mov     edi, device_id_list
409
        mov     edi, device_id_list
425
        repne   scasw
410
        repne   scasw
426
        jne     .notfound
411
        jne     .notfound
427
        jmp     .found
412
        jmp     .found
428
 
413
 
429
  .notfound:
414
  .notfound:
430
        DEBUGF  2,"Unsupported device!\n"
415
        DEBUGF  2,"Unsupported device!\n"
431
        or      eax, -1
416
        or      eax, -1
432
        ret
417
        ret
433
 
418
 
434
  .found:
419
  .found:
435
 
420
 
436
        call    ee_get_width
421
        call    ee_get_width
437
        call    MAC_read_eeprom
422
        call    MAC_read_eeprom
438
 
423
 
439
        ;;; TODO: detect phy
424
        ;;; TODO: detect phy
440
 
425
 
441
 
426
 
442
 
427
 
443
;----------
428
;----------
444
;
429
;
445
;  Reset
430
;  Reset
446
;
431
;
447
;----------
432
;----------
448
 
433
 
449
align 4
434
align 4
450
reset:
435
reset:
451
 
436
 
452
        movzx   eax, [ebx + device.irq_line]
437
        movzx   eax, [ebx + device.irq_line]
453
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
438
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
454
        invoke  AttachIntHandler, eax, int_handler, ebx
439
        invoke  AttachIntHandler, eax, int_handler, ebx
455
        test    eax, eax
440
        test    eax, eax
456
        jnz     @f
441
        jnz     @f
457
        DEBUGF  2,"Could not attach int handler!\n"
442
        DEBUGF  2,"Could not attach int handler!\n"
458
        or      eax, -1
443
        or      eax, -1
459
        ret
444
        ret
460
  @@:
445
  @@:
461
 
446
 
462
        DEBUGF  1,"Resetting\n"
447
        DEBUGF  1,"Resetting\n"
463
 
448
 
464
;---------------
449
;---------------
465
; reset the card
450
; reset the card
466
 
451
 
467
        set_io  [ebx + device.io_addr], 0
452
        set_io  [ebx + device.io_addr], 0
468
        set_io  [ebx + device.io_addr], reg_port
453
        set_io  [ebx + device.io_addr], reg_port
469
        xor     eax, eax        ; Software Reset
454
        xor     eax, eax        ; Software Reset
470
        out     dx, eax
455
        out     dx, eax
471
 
456
 
472
        mov     esi, 10
457
        mov     esi, 10
473
        invoke  Sleep           ; Give the card time to warm up.
458
        invoke  Sleep           ; Give the card time to warm up.
474
 
459
 
475
;---------------------------------
460
;---------------------------------
476
; Tell device where to store stats
461
; Tell device where to store stats
477
 
462
 
478
        lea     eax, [ebx + device.lstats.tx_good_frames]      ; lstats
463
        lea     eax, [ebx + device.lstats.tx_good_frames]      ; lstats
479
        invoke  GetPhysAddr
464
        invoke  GetPhysAddr
480
        set_io  [ebx + device.io_addr], 0
465
        set_io  [ebx + device.io_addr], 0
481
        set_io  [ebx + device.io_addr], reg_scb_ptr
466
        set_io  [ebx + device.io_addr], reg_scb_ptr
482
        out     dx, eax
467
        out     dx, eax
483
 
468
 
484
        mov     ax, INT_MASK + CU_STATSADDR
469
        mov     ax, INT_MASK + CU_STATSADDR
485
        set_io  [ebx + device.io_addr], reg_scb_cmd
470
        set_io  [ebx + device.io_addr], reg_scb_cmd
486
        out     dx, ax
471
        out     dx, ax
487
        call    cmd_wait
472
        call    cmd_wait
488
 
473
 
489
;-----------------
474
;-----------------
490
; setup RX
475
; setup RX
491
 
476
 
492
        set_io  [ebx + device.io_addr], reg_scb_ptr
477
        set_io  [ebx + device.io_addr], reg_scb_ptr
493
        xor     eax, eax
478
        xor     eax, eax
494
        out     dx, eax
479
        out     dx, eax
495
 
480
 
496
        set_io  [ebx + device.io_addr], reg_scb_cmd
481
        set_io  [ebx + device.io_addr], reg_scb_cmd
497
        mov     ax, INT_MASK + RX_ADDR_LOAD
482
        mov     ax, INT_MASK + RX_ADDR_LOAD
498
        out     dx, ax
483
        out     dx, ax
499
        call    cmd_wait
484
        call    cmd_wait
500
 
485
 
501
;-----------------------------
486
;-----------------------------
502
; Create RX and TX descriptors
487
; Create RX and TX descriptors
503
 
488
 
504
        call    create_ring
489
        call    create_ring
505
 
490
 
506
; RX start
491
; RX start
507
 
492
 
508
        set_io  [ebx + device.io_addr], 0
493
        set_io  [ebx + device.io_addr], 0
509
        set_io  [ebx + device.io_addr], reg_scb_ptr
494
        set_io  [ebx + device.io_addr], reg_scb_ptr
510
        mov     eax, [ebx + device.rx_desc]
495
        mov     eax, [ebx + device.rx_desc]
511
        invoke  GetPhysAddr
496
        invoke  GetPhysAddr
512
        out     dx, eax
497
        out     dx, eax
513
 
498
 
514
        mov     ax, INT_MASK + RX_START
499
        mov     ax, INT_MASK + RX_START
515
        set_io  [ebx + device.io_addr], reg_scb_cmd
500
        set_io  [ebx + device.io_addr], reg_scb_cmd
516
        out     dx, ax
501
        out     dx, ax
517
        call    cmd_wait
502
        call    cmd_wait
518
 
503
 
519
; Set-up TX
504
; Set-up TX
520
 
505
 
521
        set_io  [ebx + device.io_addr], reg_scb_ptr
506
        set_io  [ebx + device.io_addr], reg_scb_ptr
522
        xor     eax, eax
507
        xor     eax, eax
523
        out     dx, eax
508
        out     dx, eax
524
 
509
 
525
        set_io  [ebx + device.io_addr], reg_scb_cmd
510
        set_io  [ebx + device.io_addr], reg_scb_cmd
526
        mov     ax, INT_MASK + CU_CMD_BASE
511
        mov     ax, INT_MASK + CU_CMD_BASE
527
        out     dx, ax
512
        out     dx, ax
528
        call    cmd_wait
513
        call    cmd_wait
529
 
514
 
530
;  --------------------
515
;  --------------------
531
 
516
 
532
        mov     [ebx + device.confcmd.command], CmdConfigure + Cmdsuspend
517
        mov     [ebx + device.confcmd.command], CmdConfigure + Cmdsuspend
533
        mov     [ebx + device.confcmd.status], 0
518
        mov     [ebx + device.confcmd.status], 0
534
        lea     eax, [ebx + device.txfd.status]
519
        lea     eax, [ebx + device.txfd.status]
535
        invoke  GetPhysAddr
520
        invoke  GetPhysAddr
536
        mov     [ebx + device.confcmd.link], eax
521
        mov     [ebx + device.confcmd.link], eax
537
 
522
 
538
        mov     esi, confcmd_data
523
        mov     esi, confcmd_data
539
        lea     edi, [ebx + device.confcmd.data]
524
        lea     edi, [ebx + device.confcmd.data]
540
        mov     ecx, 22
525
        mov     ecx, 22
541
        rep     movsb
526
        rep     movsb
542
 
527
 
543
        mov     byte[ebx + device.confcmd.data + 1], 0x88  ; fifo of 8 each
528
        mov     byte[ebx + device.confcmd.data + 1], 0x88  ; fifo of 8 each
544
        mov     byte[ebx + device.confcmd.data + 4], 0
529
        mov     byte[ebx + device.confcmd.data + 4], 0
545
        mov     byte[ebx + device.confcmd.data + 5], 0x80
530
        mov     byte[ebx + device.confcmd.data + 5], 0x80
546
        mov     byte[ebx + device.confcmd.data + 15], 0x48
531
        mov     byte[ebx + device.confcmd.data + 15], 0x48
547
        mov     byte[ebx + device.confcmd.data + 19], 0x80
532
        mov     byte[ebx + device.confcmd.data + 19], 0x80
548
        mov     byte[ebx + device.confcmd.data + 21], 0x05
533
        mov     byte[ebx + device.confcmd.data + 21], 0x05
549
 
534
 
550
        mov     [ebx + device.txfd.command], CmdIASetup
535
        mov     [ebx + device.txfd.command], CmdIASetup
551
        mov     [ebx + device.txfd.status], 0
536
        mov     [ebx + device.txfd.status], 0
552
        lea     eax, [ebx + device.confcmd.status]
537
        lea     eax, [ebx + device.confcmd.status]
553
        invoke  GetPhysAddr
538
        invoke  GetPhysAddr
554
        mov     [ebx + device.txfd.link], eax
539
        mov     [ebx + device.txfd.link], eax
555
 
540
 
556
;;; copy in our MAC
541
;;; copy in our MAC
557
 
542
 
558
        lea     edi, [ebx + device.txfd.desc_addr]
543
        lea     edi, [ebx + device.txfd.desc_addr]
559
        lea     esi, [ebx + device.mac]
544
        lea     esi, [ebx + device.mac]
560
        movsd
545
        movsd
561
        movsw
546
        movsw
562
 
547
 
563
        set_io  [ebx + device.io_addr], reg_scb_ptr
548
        set_io  [ebx + device.io_addr], reg_scb_ptr
564
        lea     eax, [ebx + device.txfd.status]
549
        lea     eax, [ebx + device.txfd.status]
565
        invoke  GetPhysAddr
550
        invoke  GetPhysAddr
566
        out     dx, eax
551
        out     dx, eax
567
 
552
 
568
; Start CU & enable ints
553
; Start CU & enable ints
569
 
554
 
570
        set_io  [ebx + device.io_addr], reg_scb_cmd
555
        set_io  [ebx + device.io_addr], reg_scb_cmd
571
        mov     ax, CU_START
556
        mov     ax, CU_START
572
        out     dx, ax
557
        out     dx, ax
573
        call    cmd_wait
558
        call    cmd_wait
574
 
559
 
575
;-----------------------
560
;-----------------------
576
; build txfd structure (again!)
561
; build txfd structure (again!)
577
 
562
 
578
        lea     eax, [ebx + device.txfd.status]
563
        lea     eax, [ebx + device.txfd.status]
579
        invoke  GetPhysAddr
564
        invoke  GetPhysAddr
580
        mov     [ebx + device.txfd.link], eax
565
        mov     [ebx + device.txfd.link], eax
581
        mov     [ebx + device.txfd.count], 0x02208000
566
        mov     [ebx + device.txfd.count], 0x02208000
582
        lea     eax, [ebx + device.txfd.buf_addr0]
567
        lea     eax, [ebx + device.txfd.buf_addr0]
583
        invoke  GetPhysAddr
568
        invoke  GetPhysAddr
584
        mov     [ebx + device.txfd.desc_addr], eax
569
        mov     [ebx + device.txfd.desc_addr], eax
585
 
570
 
586
; Indicate that we have successfully reset the card
571
; Indicate that we have successfully reset the card
587
 
572
 
588
        DEBUGF  1,"Reset complete\n"
573
        DEBUGF  1,"Reset complete\n"
589
 
574
 
590
        mov     [ebx + device.mtu], 1514
575
        mov     [ebx + device.mtu], 1514
591
 
576
 
592
; Set link state to unknown
577
; Set link state to unknown
593
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
578
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
594
 
579
 
595
        xor     eax, eax        ; indicate that we have successfully reset the card
580
        xor     eax, eax        ; indicate that we have successfully reset the card
596
        ret
581
        ret
597
 
582
 
598
 
583
 
599
align 4
584
align 4
600
create_ring:
585
create_ring:
601
 
586
 
602
        DEBUGF  1,"Creating ring\n"
587
        DEBUGF  1,"Creating ring\n"
603
 
588
 
604
;---------------------
589
;---------------------
605
; build rxfd structure
590
; build rxfd structure
606
 
591
 
607
        invoke  KernelAlloc, 2000
592
        invoke  KernelAlloc, 2000
608
        mov     [ebx + device.rx_desc], eax
593
        mov     [ebx + device.rx_desc], eax
609
        mov     esi, eax
594
        mov     esi, eax
610
        invoke  GetPhysAddr
595
        invoke  GetPhysAddr
611
        mov     [esi + rxfd.status], 0x0000
596
        mov     [esi + rxfd.status], 0x0000
612
        mov     [esi + rxfd.command], 0x0000
597
        mov     [esi + rxfd.command], 0x0000
613
        mov     [esi + rxfd.link], eax
598
        mov     [esi + rxfd.link], eax
614
        mov     [esi + rxfd.count], 0
599
        mov     [esi + rxfd.count], 0
615
        mov     [esi + rxfd.size], 1528
600
        mov     [esi + rxfd.size], 1528
616
 
601
 
617
;-----------------------
602
;-----------------------
618
; build txfd structure
603
; build txfd structure
619
 
604
 
620
        lea     eax, [ebx + device.txfd.status]
605
        lea     eax, [ebx + device.txfd.status]
621
        invoke  GetPhysAddr
606
        invoke  GetPhysAddr
622
        mov     [ebx + device.txfd.link], eax
607
        mov     [ebx + device.txfd.link], eax
623
        mov     [ebx + device.txfd.count], 0x01208000
608
        mov     [ebx + device.txfd.count], 0x01208000
624
        lea     eax, [ebx + device.txfd.buf_addr0]
609
        lea     eax, [ebx + device.txfd.buf_addr0]
625
        invoke  GetPhysAddr
610
        invoke  GetPhysAddr
626
        mov     [ebx + device.txfd.desc_addr], eax
611
        mov     [ebx + device.txfd.desc_addr], eax
627
 
612
 
628
        ret
613
        ret
629
 
614
 
630
 
615
 
631
 
616
 
632
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
617
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
633
;;                                         ;;
618
;;                                         ;;
634
;; Transmit                                ;;
619
;; Transmit                                ;;
635
;;                                         ;;
620
;;                                         ;;
636
;; In: pointer to device structure in ebx  ;;
621
;; In: pointer to device structure in ebx  ;;
637
;;                                         ;;
622
;;                                         ;;
638
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
623
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
639
 
624
 
640
proc transmit stdcall bufferptr, buffersize
625
proc transmit stdcall bufferptr, buffersize
641
 
626
 
642
        pushf
627
        pushf
643
        cli
628
        cli
644
 
629
 
645
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
630
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
646
        mov     eax, [bufferptr]
631
        mov     eax, [bufferptr]
647
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
632
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
648
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
633
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
649
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
634
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
650
        [eax+13]:2,[eax+12]:2
635
        [eax+13]:2,[eax+12]:2
651
 
636
 
652
        cmp     [buffersize], 1514
637
        cmp     [buffersize], 1514
653
        ja      .fail
638
        ja      .fail
654
        cmp     [buffersize], 60
639
        cmp     [buffersize], 60
655
        jb      .fail
640
        jb      .fail
656
 
641
 
657
        ;;; TODO: check if current descriptor is in use
642
        ;;; TODO: check if current descriptor is in use
658
        ; fill in buffer address and size
643
        ; fill in buffer address and size
659
        mov     [ebx + device.last_tx_buffer], eax
644
        mov     [ebx + device.last_tx_buffer], eax
660
        invoke  GetPhysAddr
645
        invoke  GetPhysAddr
661
        mov     [ebx + device.txfd.buf_addr0], eax
646
        mov     [ebx + device.txfd.buf_addr0], eax
662
        mov     ecx, [buffersize]
647
        mov     ecx, [buffersize]
663
        mov     [ebx + device.txfd.buf_size0], ecx
648
        mov     [ebx + device.txfd.buf_size0], ecx
664
 
649
 
665
        mov     [ebx + device.txfd.status], 0
650
        mov     [ebx + device.txfd.status], 0
666
        mov     [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex + 1 shl 15 ;;; EL bit
651
        mov     [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex + 1 shl 15 ;;; EL bit
667
 ;       mov     [txfd.count], 0x02208000   ;;;;;;;;;;;
652
 ;       mov     [txfd.count], 0x02208000   ;;;;;;;;;;;
668
 
653
 
669
        ; Inform device of the new/updated transmit descriptor
654
        ; Inform device of the new/updated transmit descriptor
670
        lea     eax, [ebx + device.txfd.status]
655
        lea     eax, [ebx + device.txfd.status]
671
        invoke  GetPhysAddr
656
        invoke  GetPhysAddr
672
        set_io  [ebx + device.io_addr], 0
657
        set_io  [ebx + device.io_addr], 0
673
        set_io  [ebx + device.io_addr], reg_scb_ptr
658
        set_io  [ebx + device.io_addr], reg_scb_ptr
674
        out     dx, eax
659
        out     dx, eax
675
 
660
 
676
        ; Start the transmit
661
        ; Start the transmit
677
        mov     ax, CU_START
662
        mov     ax, CU_START
678
        set_io  [ebx + device.io_addr], reg_scb_cmd
663
        set_io  [ebx + device.io_addr], reg_scb_cmd
679
        out     dx, ax
664
        out     dx, ax
680
        call    cmd_wait
665
        call    cmd_wait
681
 
666
 
682
; Update stats
667
; Update stats
683
        inc     [ebx + device.packets_tx]
668
        inc     [ebx + device.packets_tx]
684
        mov     ecx, [buffersize]
669
        mov     ecx, [buffersize]
685
        add     dword[ebx + device.bytes_tx], ecx
670
        add     dword[ebx + device.bytes_tx], ecx
686
        adc     dword[ebx + device.bytes_tx + 4], 0
671
        adc     dword[ebx + device.bytes_tx + 4], 0
687
 
672
 
688
        DEBUGF  1,"Transmit OK\n"
673
        DEBUGF  1,"Transmit OK\n"
689
        popf
674
        popf
690
        xor     eax, eax
675
        xor     eax, eax
691
        ret
676
        ret
692
 
677
 
693
  .fail:
678
  .fail:
694
        invoke  KernelFree, [bufferptr]
679
        invoke  KernelFree, [bufferptr]
695
        popf
680
        popf
696
        or      eax, -1
681
        or      eax, -1
697
        ret
682
        ret
698
 
683
 
699
endp
684
endp
700
 
685
 
701
 
686
 
702
;;;;;;;;;;;;;;;;;;;;;;;
687
;;;;;;;;;;;;;;;;;;;;;;;
703
;;                   ;;
688
;;                   ;;
704
;; Interrupt handler ;;
689
;; Interrupt handler ;;
705
;;                   ;;
690
;;                   ;;
706
;;;;;;;;;;;;;;;;;;;;;;;
691
;;;;;;;;;;;;;;;;;;;;;;;
707
 
692
 
708
align 4
693
align 4
709
int_handler:
694
int_handler:
710
 
695
 
711
        push    ebx esi edi
696
        push    ebx esi edi
712
 
697
 
713
        DEBUGF  1,"INT\n"
698
        DEBUGF  1,"INT\n"
714
 
699
 
715
; find pointer of device wich made IRQ occur
700
; find pointer of device wich made IRQ occur
716
 
701
 
717
        mov     ecx, [devices]
702
        mov     ecx, [devices]
718
        test    ecx, ecx
703
        test    ecx, ecx
719
        jz      .nothing
704
        jz      .nothing
720
        mov     esi, device_list
705
        mov     esi, device_list
721
  .nextdevice:
706
  .nextdevice:
722
        mov     ebx, [esi]
707
        mov     ebx, [esi]
723
 
708
 
724
;        set_io  [ebx + device.io_addr], 0              ; reg_scb_status = 0
709
;        set_io  [ebx + device.io_addr], 0              ; reg_scb_status = 0
725
        set_io  [ebx + device.io_addr], reg_scb_status
710
        set_io  [ebx + device.io_addr], reg_scb_status
726
        in      ax, dx
711
        in      ax, dx
727
        out     dx, ax                              ; send it back to ACK
712
        out     dx, ax                              ; send it back to ACK
728
        test    ax, ax
713
        test    ax, ax
729
        jnz     .got_it
714
        jnz     .got_it
730
  .continue:
715
  .continue:
731
        add     esi, 4
716
        add     esi, 4
732
        dec     ecx
717
        dec     ecx
733
        jnz     .nextdevice
718
        jnz     .nextdevice
734
  .nothing:
719
  .nothing:
735
        pop     edi esi ebx
720
        pop     edi esi ebx
736
        xor     eax, eax
721
        xor     eax, eax
737
 
722
 
738
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
723
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
739
 
724
 
740
  .got_it:
725
  .got_it:
741
 
726
 
742
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
727
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
743
 
728
 
744
        test    ax, 1 shl 14    ; did we receive a frame?
729
        test    ax, 1 shl 14    ; did we receive a frame?
745
        jz      .no_rx
730
        jz      .no_rx
746
 
731
 
747
        push    ax
732
        push    ax
748
 
733
 
749
        DEBUGF  1,"Receiving\n"
734
        DEBUGF  1,"Receiving\n"
750
 
735
 
751
        push    ebx
736
        push    ebx
752
  .rx_loop:
737
  .rx_loop:
753
        pop     ebx
738
        pop     ebx
754
 
739
 
755
        mov     esi, [ebx + device.rx_desc]
740
        mov     esi, [ebx + device.rx_desc]
756
        cmp     [esi + rxfd.status], 0        ; we could also check bits C and OK (bit 15 and 13)
741
        cmp     [esi + rxfd.status], 0        ; we could also check bits C and OK (bit 15 and 13)
757
        je      .nodata
742
        je      .nodata
758
 
743
 
759
        DEBUGF  1,"rxfd status=0x%x\n", [esi + rxfd.status]:4
744
        DEBUGF  1,"rxfd status=0x%x\n", [esi + rxfd.status]:4
760
 
745
 
761
        movzx   ecx, [esi + rxfd.count]
746
        movzx   ecx, [esi + rxfd.count]
762
        and     ecx, 0x3fff
747
        and     ecx, 0x3fff
763
 
748
 
764
        push    ebx
749
        push    ebx
765
        push    .rx_loop
750
        push    .rx_loop
766
        push    ecx
751
        push    ecx
767
        add     esi, rxfd.packet
752
        add     esi, rxfd.packet
768
        push    esi
753
        push    esi
769
 
754
 
770
; Update stats
755
; Update stats
771
        add     dword [ebx + device.bytes_rx], ecx
756
        add     dword [ebx + device.bytes_rx], ecx
772
        adc     dword [ebx + device.bytes_rx + 4], 0
757
        adc     dword [ebx + device.bytes_rx + 4], 0
773
        inc     dword [ebx + device.packets_rx]
758
        inc     dword [ebx + device.packets_rx]
774
 
759
 
775
; allocate new descriptor
760
; allocate new descriptor
776
 
761
 
777
        invoke  KernelAlloc, 2000
762
        invoke  KernelAlloc, 2000
778
        mov     [ebx + device.rx_desc], eax
763
        mov     [ebx + device.rx_desc], eax
779
        mov     esi, eax
764
        mov     esi, eax
780
        invoke  GetPhysAddr
765
        invoke  GetPhysAddr
781
        mov     [esi + rxfd.status], 0x0000
766
        mov     [esi + rxfd.status], 0x0000
782
        mov     [esi + rxfd.command], 0xc000    ; End of list + Suspend
767
        mov     [esi + rxfd.command], 0xc000    ; End of list + Suspend
783
        mov     [esi + rxfd.link], eax
768
        mov     [esi + rxfd.link], eax
784
        mov     [esi + rxfd.count], 0
769
        mov     [esi + rxfd.count], 0
785
        mov     [esi + rxfd.size], 1528
770
        mov     [esi + rxfd.size], 1528
786
 
771
 
787
; restart RX
772
; restart RX
788
 
773
 
789
        set_io  [ebx + device.io_addr], 0
774
        set_io  [ebx + device.io_addr], 0
790
        set_io  [ebx + device.io_addr], reg_scb_ptr
775
        set_io  [ebx + device.io_addr], reg_scb_ptr
791
;        lea     eax, [ebx + device.rx_desc]
776
;        lea     eax, [ebx + device.rx_desc]
792
;        invoke  GetPhysAddr
777
;        invoke  GetPhysAddr
793
        out     dx, eax
778
        out     dx, eax
794
 
779
 
795
        set_io  [ebx + device.io_addr], reg_scb_cmd
780
        set_io  [ebx + device.io_addr], reg_scb_cmd
796
        mov     ax, RX_START
781
        mov     ax, RX_START
797
        out     dx, ax
782
        out     dx, ax
798
        call    cmd_wait
783
        call    cmd_wait
799
 
784
 
800
; And give packet to kernel
785
; And give packet to kernel
801
        jmp     [Eth_input]
786
        jmp     [Eth_input]
802
 
787
 
803
  .nodata:
788
  .nodata:
804
        DEBUGF  1, "no more data\n"
789
        DEBUGF  1, "no more data\n"
805
        pop     ax
790
        pop     ax
806
 
791
 
807
  .no_rx:
792
  .no_rx:
808
 
793
 
809
; Cleanup after TX
794
; Cleanup after TX
810
        cmp     [ebx + device.txfd.status], 0
795
        cmp     [ebx + device.txfd.status], 0
811
        je      .done
796
        je      .done
812
        cmp     [ebx + device.last_tx_buffer], 0
797
        cmp     [ebx + device.last_tx_buffer], 0
813
        je      .done
798
        je      .done
814
        push    ax
799
        push    ax
815
        DEBUGF  1, "Removing packet 0x%x from RAM!\n", [ebx + device.last_tx_buffer]
800
        DEBUGF  1, "Removing packet 0x%x from RAM!\n", [ebx + device.last_tx_buffer]
816
        invoke  KernelFree, [ebx + device.last_tx_buffer]
801
        invoke  KernelFree, [ebx + device.last_tx_buffer]
817
        mov     [ebx + device.last_tx_buffer], 0
802
        mov     [ebx + device.last_tx_buffer], 0
818
        pop     ax
803
        pop     ax
819
 
804
 
820
  .done:
805
  .done:
821
        and     ax, 00111100b
806
        and     ax, 00111100b
822
        cmp     ax, 00001000b
807
        cmp     ax, 00001000b
823
        jne     .fail
808
        jne     .fail
824
 
809
 
825
        DEBUGF  1, "out of resources!\n"
810
        DEBUGF  1, "out of resources!\n"
826
; Restart the RX
811
; Restart the RX
827
 
812
 
828
; allocate new descriptor
813
; allocate new descriptor
829
 
814
 
830
        invoke  KernelAlloc, 2000
815
        invoke  KernelAlloc, 2000
831
        mov     [ebx + device.rx_desc], eax
816
        mov     [ebx + device.rx_desc], eax
832
        mov     esi, eax
817
        mov     esi, eax
833
        invoke  GetPhysAddr
818
        invoke  GetPhysAddr
834
        mov     [esi + rxfd.status], 0x0000
819
        mov     [esi + rxfd.status], 0x0000
835
        mov     [esi + rxfd.command], 0xc000    ; End of list + Suspend
820
        mov     [esi + rxfd.command], 0xc000    ; End of list + Suspend
836
        mov     [esi + rxfd.link], eax
821
        mov     [esi + rxfd.link], eax
837
        mov     [esi + rxfd.count], 0
822
        mov     [esi + rxfd.count], 0
838
        mov     [esi + rxfd.size], 1528
823
        mov     [esi + rxfd.size], 1528
839
 
824
 
840
; restart RX
825
; restart RX
841
 
826
 
842
        set_io  [ebx + device.io_addr], 0
827
        set_io  [ebx + device.io_addr], 0
843
        set_io  [ebx + device.io_addr], reg_scb_ptr
828
        set_io  [ebx + device.io_addr], reg_scb_ptr
844
;        lea     eax, [ebx + device.rx_desc]
829
;        lea     eax, [ebx + device.rx_desc]
845
;        invoke  GetPhysAddr
830
;        invoke  GetPhysAddr
846
        out     dx, eax
831
        out     dx, eax
847
 
832
 
848
        set_io  [ebx + device.io_addr], reg_scb_cmd
833
        set_io  [ebx + device.io_addr], reg_scb_cmd
849
        mov     ax, RX_START
834
        mov     ax, RX_START
850
        out     dx, ax
835
        out     dx, ax
851
        call    cmd_wait
836
        call    cmd_wait
852
 
837
 
853
  .fail:
838
  .fail:
854
        pop     edi esi ebx
839
        pop     edi esi ebx
855
        xor     eax, eax
840
        xor     eax, eax
856
        inc     eax
841
        inc     eax
857
 
842
 
858
        ret
843
        ret
859
 
844
 
860
 
845
 
861
 
846
 
862
 
847
 
863
align 4
848
align 4
864
cmd_wait:
849
cmd_wait:
865
 
850
 
866
        in      al, dx
851
        in      al, dx
867
        test    al, al
852
        test    al, al
868
        jnz     cmd_wait
853
        jnz     cmd_wait
869
 
854
 
870
        ret
855
        ret
871
 
856
 
872
 
857
 
873
 
858
 
874
 
859
 
875
 
860
 
876
 
861
 
877
align 4
862
align 4
878
ee_read:        ; esi = address to read
863
ee_read:        ; esi = address to read
879
 
864
 
880
        DEBUGF  1,"Eeprom read from 0x%x\n", esi
865
        DEBUGF  1,"Eeprom read from 0x%x\n", esi
881
 
866
 
882
        set_io  [ebx + device.io_addr], 0
867
        set_io  [ebx + device.io_addr], 0
883
        set_io  [ebx + device.io_addr], reg_eeprom
868
        set_io  [ebx + device.io_addr], reg_eeprom
884
 
869
 
885
;-----------------------------------------------------
870
;-----------------------------------------------------
886
; Prepend start bit + read opcode to the address field
871
; Prepend start bit + read opcode to the address field
887
; and shift it to the very left bits of esi
872
; and shift it to the very left bits of esi
888
 
873
 
889
        mov     cl, 29
874
        mov     cl, 29
890
        sub     cl, [ebx + device.ee_bus_width]
875
        sub     cl, [ebx + device.ee_bus_width]
891
        shl     esi, cl
876
        shl     esi, cl
892
        or      esi, EE_READ shl 29
877
        or      esi, EE_READ shl 29
893
 
878
 
894
        movzx   ecx, [ebx + device.ee_bus_width]
879
        movzx   ecx, [ebx + device.ee_bus_width]
895
        add     ecx, 3
880
        add     ecx, 3
896
 
881
 
897
        mov     al, EE_CS
882
        mov     al, EE_CS
898
        out     dx, al
883
        out     dx, al
899
        delay
884
        call    udelay
900
 
885
 
901
;-----------------------
886
;-----------------------
902
; Write this to the chip
887
; Write this to the chip
903
 
888
 
904
  .loop:
889
  .loop:
905
        mov     al, EE_CS + EE_SK
890
        mov     al, EE_CS + EE_SK
906
        shl     esi, 1
891
        shl     esi, 1
907
        jnc     @f
892
        jnc     @f
908
        or      al, EE_DI
893
        or      al, EE_DI
909
       @@:
894
       @@:
910
        out     dx, al
895
        out     dx, al
911
        delay
896
        call    udelay
912
 
897
 
913
        and     al, not EE_SK
898
        and     al, not EE_SK
914
        out     dx, al
899
        out     dx, al
915
        delay
900
        call    udelay
916
 
901
 
917
        loop    .loop
902
        loop    .loop
918
 
903
 
919
;------------------------------
904
;------------------------------
920
; Now read the data from eeprom
905
; Now read the data from eeprom
921
 
906
 
922
        xor     esi, esi
907
        xor     esi, esi
923
        mov     ecx, 16
908
        mov     ecx, 16
924
 
909
 
925
  .loop2:
910
  .loop2:
926
        shl     esi, 1
911
        shl     esi, 1
927
        mov     al, EE_CS + EE_SK
912
        mov     al, EE_CS + EE_SK
928
        out     dx, al
913
        out     dx, al
929
        delay
914
        call    udelay
930
 
915
 
931
        in      al, dx
916
        in      al, dx
932
        test    al, EE_DO
917
        test    al, EE_DO
933
        jz      @f
918
        jz      @f
934
        inc     esi
919
        inc     esi
935
       @@:
920
       @@:
936
 
921
 
937
        mov     al, EE_CS
922
        mov     al, EE_CS
938
        out     dx, al
923
        out     dx, al
939
        delay
924
        call    udelay
940
 
925
 
941
        loop    .loop2
926
        loop    .loop2
942
 
927
 
943
;-----------------------
928
;-----------------------
944
; de-activate the eeprom
929
; de-activate the eeprom
945
 
930
 
946
        xor     ax, ax
931
        xor     ax, ax
947
        out     dx, ax
932
        out     dx, ax
948
 
933
 
949
 
934
 
950
        DEBUGF  1,"0x%x\n", esi:4
935
        DEBUGF  1,"0x%x\n", esi:4
951
        ret
936
        ret
952
 
937
 
953
 
938
 
954
 
939
 
955
align 4
940
align 4
956
ee_write:       ; esi = address to write to, di = data
941
ee_write:       ; esi = address to write to, di = data
957
 
942
 
958
        DEBUGF  1,"Eeprom write 0x%x to 0x%x\n", di, esi
943
        DEBUGF  1,"Eeprom write 0x%x to 0x%x\n", di, esi
959
 
944
 
960
        set_io  [ebx + device.io_addr], 0
945
        set_io  [ebx + device.io_addr], 0
961
        set_io  [ebx + device.io_addr], reg_eeprom
946
        set_io  [ebx + device.io_addr], reg_eeprom
962
 
947
 
963
;-----------------------------------------------------
948
;-----------------------------------------------------
964
; Prepend start bit + write opcode to the address field
949
; Prepend start bit + write opcode to the address field
965
; and shift it to the very left bits of esi
950
; and shift it to the very left bits of esi
966
 
951
 
967
        mov     cl, 29
952
        mov     cl, 29
968
        sub     cl, [ebx + device.ee_bus_width]
953
        sub     cl, [ebx + device.ee_bus_width]
969
        shl     esi, cl
954
        shl     esi, cl
970
        or      esi, EE_WRITE shl 29
955
        or      esi, EE_WRITE shl 29
971
 
956
 
972
        movzx   ecx, [ebx + device.ee_bus_width]
957
        movzx   ecx, [ebx + device.ee_bus_width]
973
        add     ecx, 3
958
        add     ecx, 3
974
 
959
 
975
        mov     al, EE_CS       ; enable chip
960
        mov     al, EE_CS       ; enable chip
976
        out     dx, al
961
        out     dx, al
977
 
962
 
978
;-----------------------
963
;-----------------------
979
; Write this to the chip
964
; Write this to the chip
980
 
965
 
981
  .loop:
966
  .loop:
982
        mov     al, EE_CS + EE_SK
967
        mov     al, EE_CS + EE_SK
983
        shl     esi, 1
968
        shl     esi, 1
984
        jnc     @f
969
        jnc     @f
985
        or      al, EE_DI
970
        or      al, EE_DI
986
       @@:
971
       @@:
987
        out     dx, al
972
        out     dx, al
988
        delay
973
        call    udelay
989
 
974
 
990
        and     al, not EE_SK
975
        and     al, not EE_SK
991
        out     dx, al
976
        out     dx, al
992
        delay
977
        call    udelay
993
 
978
 
994
        loop    .loop
979
        loop    .loop
995
 
980
 
996
;-----------------------------
981
;-----------------------------
997
; Now write the data to eeprom
982
; Now write the data to eeprom
998
 
983
 
999
        mov     ecx, 16
984
        mov     ecx, 16
1000
 
985
 
1001
  .loop2:
986
  .loop2:
1002
        mov     al, EE_CS + EE_SK
987
        mov     al, EE_CS + EE_SK
1003
        shl     di, 1
988
        shl     di, 1
1004
        jnc     @f
989
        jnc     @f
1005
        or      al, EE_DI
990
        or      al, EE_DI
1006
       @@:
991
       @@:
1007
        out     dx, al
992
        out     dx, al
1008
        delay
993
        call    udelay
1009
 
994
 
1010
        and     al, not EE_SK
995
        and     al, not EE_SK
1011
        out     dx, al
996
        out     dx, al
1012
        delay
997
        call    udelay
1013
 
998
 
1014
        loop    .loop2
999
        loop    .loop2
1015
 
1000
 
1016
;-----------------------
1001
;-----------------------
1017
; de-activate the eeprom
1002
; de-activate the eeprom
1018
 
1003
 
1019
        xor     al, al
1004
        xor     al, al
1020
        out     dx, al
1005
        out     dx, al
1021
 
1006
 
1022
 
1007
 
1023
        ret
1008
        ret
1024
 
1009
 
1025
 
1010
 
1026
 
1011
 
1027
align 4
1012
align 4
1028
ee_get_width:
1013
ee_get_width:
1029
 
1014
 
1030
        set_io  [ebx + device.io_addr], 0
1015
        set_io  [ebx + device.io_addr], 0
1031
        set_io  [ebx + device.io_addr], reg_eeprom
1016
        set_io  [ebx + device.io_addr], reg_eeprom
1032
 
1017
 
1033
        mov     al, EE_CS      ; activate eeprom
1018
        mov     al, EE_CS      ; activate eeprom
1034
        out     dx, al
1019
        out     dx, al
1035
        delay
1020
        call    udelay
1036
 
1021
 
1037
        mov     si, EE_READ shl 13
1022
        mov     si, EE_READ shl 13
1038
        xor     ecx, ecx
1023
        xor     ecx, ecx
1039
  .loop:
1024
  .loop:
1040
        mov     al, EE_CS + EE_SK
1025
        mov     al, EE_CS + EE_SK
1041
        shl     si, 1
1026
        shl     si, 1
1042
        jnc     @f
1027
        jnc     @f
1043
        or      al, EE_DI
1028
        or      al, EE_DI
1044
       @@:
1029
       @@:
1045
        out     dx, al
1030
        out     dx, al
1046
        delay
1031
        call    udelay
1047
 
1032
 
1048
        and     al, not EE_SK
1033
        and     al, not EE_SK
1049
        out     dx, al
1034
        out     dx, al
1050
        delay
1035
        call    udelay
1051
 
1036
 
1052
        inc     ecx
1037
        inc     ecx
1053
 
1038
 
1054
        cmp     ecx, 15
1039
        cmp     ecx, 15
1055
        jae     .give_up
1040
        jae     .give_up
1056
 
1041
 
1057
        in      al, dx
1042
        in      al, dx
1058
        test    al, EE_DO
1043
        test    al, EE_DO
1059
        jnz     .loop
1044
        jnz     .loop
1060
 
1045
 
1061
        xor     al, al
1046
        xor     al, al
1062
        out     dx, al          ; de-activate eeprom
1047
        out     dx, al          ; de-activate eeprom
1063
 
1048
 
1064
        sub     cl, 3           ; dont count the opcode bits
1049
        sub     cl, 3           ; dont count the opcode bits
1065
        mov     [ebx + device.ee_bus_width], cl
1050
        mov     [ebx + device.ee_bus_width], cl
1066
        DEBUGF  1, "Eeprom width=%u bit\n", ecx
1051
        DEBUGF  1, "Eeprom width=%u bit\n", ecx
1067
 
1052
 
1068
        ret
1053
        ret
1069
 
1054
 
1070
  .give_up:
1055
  .give_up:
1071
        DEBUGF  2, "Eeprom not found!\n"
1056
        DEBUGF  2, "Eeprom not found!\n"
1072
 
1057
 
1073
        xor     al, al
1058
        xor     al, al
1074
        out     dx, al          ; de-activate eeprom
1059
        out     dx, al          ; de-activate eeprom
1075
 
1060
 
1076
        ret
1061
        ret
1077
 
1062
 
-
 
1063
 
-
 
1064
; Wait a minimum of 2µs
-
 
1065
udelay:
-
 
1066
        pusha
-
 
1067
        mov     esi, 1
-
 
1068
        invoke  Sleep
-
 
1069
        popa
-
 
1070
 
-
 
1071
        ret
-
 
1072
 
1078
 
1073
 
1079
 
1074
 
1080
; cx = phy addr
1075
; cx = phy addr
1081
; dx = phy reg addr
1076
; dx = phy reg addr
1082
 
1077
 
1083
; ax = data
1078
; ax = data
1084
 
1079
 
1085
align 4
1080
align 4
1086
mdio_read:
1081
mdio_read:
1087
 
1082
 
1088
        DEBUGF  1,"MDIO read\n"
1083
        DEBUGF  1,"MDIO read\n"
1089
 
1084
 
1090
        shl     ecx, 21                 ; PHY addr
1085
        shl     ecx, 21                 ; PHY addr
1091
        shl     edx, 16                 ; PHY reg addr
1086
        shl     edx, 16                 ; PHY reg addr
1092
 
1087
 
1093
        mov     eax, ecx
1088
        mov     eax, ecx
1094
        or      eax, edx
1089
        or      eax, edx
1095
        or      eax, 10b shl 26         ; read opcode
1090
        or      eax, 10b shl 26         ; read opcode
1096
 
1091
 
1097
        set_io  [ebx + device.io_addr], 0
1092
        set_io  [ebx + device.io_addr], 0
1098
        set_io  [ebx + device.io_addr], reg_mdi_ctrl
1093
        set_io  [ebx + device.io_addr], reg_mdi_ctrl
1099
        out     dx, eax
1094
        out     dx, eax
1100
 
1095
 
1101
  .wait:
1096
  .wait:
1102
        delay
1097
        call    udelay
1103
        in      eax, dx
1098
        in      eax, dx
1104
        test    eax, 1 shl 28           ; ready bit
1099
        test    eax, 1 shl 28           ; ready bit
1105
        jz      .wait
1100
        jz      .wait
1106
 
1101
 
1107
        ret
1102
        ret
1108
 
1103
 
1109
; ax = data
1104
; ax = data
1110
; cx = phy addr
1105
; cx = phy addr
1111
; dx = phy reg addr
1106
; dx = phy reg addr
1112
 
1107
 
1113
; ax = data
1108
; ax = data
1114
 
1109
 
1115
align 4
1110
align 4
1116
mdio_write:
1111
mdio_write:
1117
 
1112
 
1118
        DEBUGF  1,"MDIO write\n"
1113
        DEBUGF  1,"MDIO write\n"
1119
 
1114
 
1120
        and     eax, 0xffff
1115
        and     eax, 0xffff
1121
 
1116
 
1122
        shl     ecx, 21                 ; PHY addr
1117
        shl     ecx, 21                 ; PHY addr
1123
        shl     edx, 16                 ; PHY reg addr
1118
        shl     edx, 16                 ; PHY reg addr
1124
 
1119
 
1125
        or      eax, ecx
1120
        or      eax, ecx
1126
        or      eax, edx
1121
        or      eax, edx
1127
        or      eax, 01b shl 26         ; write opcode
1122
        or      eax, 01b shl 26         ; write opcode
1128
 
1123
 
1129
        set_io  [ebx + device.io_addr], 0
1124
        set_io  [ebx + device.io_addr], 0
1130
        set_io  [ebx + device.io_addr], reg_mdi_ctrl
1125
        set_io  [ebx + device.io_addr], reg_mdi_ctrl
1131
        out     dx, eax
1126
        out     dx, eax
1132
 
1127
 
1133
  .wait:
1128
  .wait:
1134
        delay
1129
        call    udelay
1135
        in      eax, dx
1130
        in      eax, dx
1136
        test    eax, 1 shl 28           ; ready bit
1131
        test    eax, 1 shl 28           ; ready bit
1137
        jz      .wait
1132
        jz      .wait
1138
 
1133
 
1139
        ret
1134
        ret
1140
 
1135
 
1141
read_mac:
1136
read_mac:
1142
 
1137
 
1143
        ret
1138
        ret
1144
 
1139
 
1145
 
1140
 
1146
 
1141
 
1147
align 4
1142
align 4
1148
MAC_read_eeprom:
1143
MAC_read_eeprom:
1149
 
1144
 
1150
        mov     esi, 0
1145
        mov     esi, 0
1151
        call    ee_read
1146
        call    ee_read
1152
        mov     word[ebx + device.mac], si
1147
        mov     word[ebx + device.mac], si
1153
 
1148
 
1154
        mov     esi, 1
1149
        mov     esi, 1
1155
        call    ee_read
1150
        call    ee_read
1156
        mov     word[ebx + device.mac+2], si
1151
        mov     word[ebx + device.mac+2], si
1157
 
1152
 
1158
        mov     esi, 2
1153
        mov     esi, 2
1159
        call    ee_read
1154
        call    ee_read
1160
        mov     word[ebx + device.mac+4], si
1155
        mov     word[ebx + device.mac+4], si
1161
 
1156
 
1162
 
1157
 
1163
        ret
1158
        ret
1164
 
1159
 
1165
 
1160
 
1166
align 4
1161
align 4
1167
MAC_write:
1162
MAC_write:
1168
 
1163
 
1169
;;;;
1164
;;;;
1170
 
1165
 
1171
        ret
1166
        ret
1172
 
1167
 
1173
 
1168
 
1174
 
1169
 
1175
 
1170
 
1176
; End of code
1171
; End of code
1177
 
1172
 
1178
 
1173
 
1179
data fixups
1174
data fixups
1180
end data
1175
end data
1181
 
1176
 
1182
include '../peimport.inc'
1177
include '../peimport.inc'
1183
 
1178
 
1184
my_service      db 'I8255X', 0                    ; max 16 chars include zero
1179
my_service      db 'I8255X', 0                    ; max 16 chars include zero
1185
devicename      db 'Intel Etherexpress pro/100', 0
1180
devicename      db 'Intel Etherexpress pro/100', 0
1186
 
1181
 
1187
confcmd_data    db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
1182
confcmd_data    db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
1188
                db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
1183
                db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
1189
                db 0x80, 0x3f, 0x05                                     ; 22 bytes total
1184
                db 0x80, 0x3f, 0x05                                     ; 22 bytes total
1190
 
1185
 
1191
 
1186
 
1192
device_id_list:
1187
device_id_list:
1193
 
1188
 
1194
        dw 0x1029
1189
        dw 0x1029
1195
        dw 0x1030
1190
        dw 0x1030
1196
        dw 0x1031
1191
        dw 0x1031
1197
        dw 0x1032
1192
        dw 0x1032
1198
        dw 0x1033
1193
        dw 0x1033
1199
        dw 0x1034
1194
        dw 0x1034
1200
        dw 0x1038
1195
        dw 0x1038
1201
        dw 0x1039
1196
        dw 0x1039
1202
        dw 0x103A
1197
        dw 0x103A
1203
        dw 0x103B
1198
        dw 0x103B
1204
        dw 0x103C
1199
        dw 0x103C
1205
        dw 0x103D
1200
        dw 0x103D
1206
        dw 0x103E
1201
        dw 0x103E
1207
        dw 0x1050
1202
        dw 0x1050
1208
        dw 0x1051
1203
        dw 0x1051
1209
        dw 0x1052
1204
        dw 0x1052
1210
        dw 0x1053
1205
        dw 0x1053
1211
        dw 0x1054
1206
        dw 0x1054
1212
        dw 0x1055
1207
        dw 0x1055
1213
        dw 0x1056
1208
        dw 0x1056
1214
        dw 0x1057
1209
        dw 0x1057
1215
        dw 0x1059
1210
        dw 0x1059
1216
        dw 0x1064
1211
        dw 0x1064
1217
        dw 0x1065
1212
        dw 0x1065
1218
        dw 0x1066
1213
        dw 0x1066
1219
        dw 0x1067
1214
        dw 0x1067
1220
        dw 0x1068
1215
        dw 0x1068
1221
        dw 0x1069
1216
        dw 0x1069
1222
        dw 0x106A
1217
        dw 0x106A
1223
        dw 0x106B
1218
        dw 0x106B
1224
        dw 0x1091
1219
        dw 0x1091
1225
        dw 0x1092
1220
        dw 0x1092
1226
        dw 0x1093
1221
        dw 0x1093
1227
        dw 0x1094
1222
        dw 0x1094
1228
        dw 0x1095
1223
        dw 0x1095
1229
        dw 0x10fe
1224
        dw 0x10fe
1230
        dw 0x1209
1225
        dw 0x1209
1231
        dw 0x1229
1226
        dw 0x1229
1232
        dw 0x2449
1227
        dw 0x2449
1233
        dw 0x2459
1228
        dw 0x2459
1234
        dw 0x245D
1229
        dw 0x245D
1235
        dw 0x27DC
1230
        dw 0x27DC
1236
 
1231
 
1237
DEVICE_IDs = ($ - device_id_list) / 2
1232
DEVICE_IDs = ($ - device_id_list) / 2
1238
 
1233
 
1239
include_debug_strings                           ; All data wich FDO uses will be included here
1234
include_debug_strings                           ; All data wich FDO uses will be included here
1240
 
1235
 
1241
align 4
1236
align 4
1242
devices         dd 0                              ; number of currently running devices
1237
devices         dd 0                              ; number of currently running devices
1243
device_list     rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
1238
device_list     rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling