Subversion Repositories Kolibri OS

Rev

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

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