Subversion Repositories Kolibri OS

Rev

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

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