Subversion Repositories Kolibri OS

Rev

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

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