Subversion Repositories Kolibri OS

Rev

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

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