Subversion Repositories Kolibri OS

Rev

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

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