Subversion Repositories Kolibri OS

Rev

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

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