Subversion Repositories Kolibri OS

Rev

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

Rev 5006 Rev 5074
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                    ;;
2
;;                                                                    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.       ;;
3
;; Copyright (C) KolibriOS team 2004-2014. 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
;;  Ethernet driver for KolibriOS                                     ;;
6
;;  Ethernet driver for KolibriOS                                     ;;
7
;;  This is an adaptation of MenuetOS driver with minimal changes.    ;;
7
;;  This is an adaptation of MenuetOS driver with minimal changes.    ;;
8
;;  Changes were made by CleverMouse. Original copyright follows.     ;;
8
;;  Changes were made by CleverMouse. Original copyright follows.     ;;
9
;;                                                                    ;;
9
;;                                                                    ;;
10
;;  This driver is based on the SIS900 driver from                    ;;
10
;;  This driver is based on the SIS900 driver from                    ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is           ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is           ;;
12
;;                                                                    ;;
12
;;                                                                    ;;
13
;;          GNU GENERAL PUBLIC LICENSE                                ;;
13
;;          GNU GENERAL PUBLIC LICENSE                                ;;
14
;;             Version 2, June 1991                                   ;;
14
;;             Version 2, June 1991                                   ;;
15
;;                                                                    ;;
15
;;                                                                    ;;
16
;;  remaining parts Copyright 2004 Jason Delozier,                    ;;
16
;;  remaining parts Copyright 2004 Jason Delozier,                    ;;
17
;;   cordata51@hotmail.com                                            ;;
17
;;   cordata51@hotmail.com                                            ;;
18
;;                                                                    ;;
18
;;                                                                    ;;
19
;;  See file COPYING for details                                      ;;
19
;;  See file COPYING for details                                      ;;
20
;;                                                                    ;;
20
;;                                                                    ;;
21
;;  Updates:                                                          ;;
21
;;  Updates:                                                          ;;
22
;;    Revision Look up table and SIS635 Mac Address by Jarek Pelczar  ;;
22
;;    Revision Look up table and SIS635 Mac Address by Jarek Pelczar  ;;
23
;;                                                                    ;;
23
;;                                                                    ;;
24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25
 
25
 
26
format PE DLL native
26
format PE DLL native
27
entry START
27
entry START
28
 
28
 
29
        CURRENT_API             = 0x0200
29
        CURRENT_API             = 0x0200
30
        COMPATIBLE_API          = 0x0100
30
        COMPATIBLE_API          = 0x0100
31
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
31
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
32
 
32
 
33
        NUM_RX_DESC             = 4             ; Number of RX descriptors
33
        NUM_RX_DESC             = 4             ; Number of RX descriptors
34
        NUM_TX_DESC             = 4             ; Number of TX descriptors
34
        NUM_TX_DESC             = 4             ; Number of TX descriptors
35
        RX_BUFF_SZ              = 1520          ; Buffer size for each Rx buffer
35
        RX_BUFF_SZ              = 1520          ; Buffer size for each Rx buffer
36
 
36
 
37
        MAX_DEVICES             = 16
37
        MAX_DEVICES             = 16
38
 
38
 
39
        __DEBUG__               = 1
39
        __DEBUG__               = 1
40
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
40
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
41
 
41
 
42
        DSIZE                   = 0x00000fff
42
        DSIZE                   = 0x00000fff
43
        CRC_SIZE                = 4
43
        CRC_SIZE                = 4
44
        RFADDR_shift            = 16
44
        RFADDR_shift            = 16
45
 
45
 
46
; If you are having problems sending/receiving packet try changing the
46
; If you are having problems sending/receiving packet try changing the
47
; Max DMA Burst, Possible settings are as follows:
47
; Max DMA Burst, Possible settings are as follows:
48
;
48
;
49
; 0x00000000 = 512 bytes
49
; 0x00000000 = 512 bytes
50
; 0x00100000 = 4 bytes
50
; 0x00100000 = 4 bytes
51
; 0x00200000 = 8 bytes
51
; 0x00200000 = 8 bytes
52
; 0x00300000 = 16 bytes
52
; 0x00300000 = 16 bytes
53
; 0x00400000 = 32 bytes
53
; 0x00400000 = 32 bytes
54
; 0x00500000 = 64 bytes
54
; 0x00500000 = 64 bytes
55
; 0x00600000 = 128 bytes
55
; 0x00600000 = 128 bytes
56
; 0x00700000 = 256 bytes
56
; 0x00700000 = 256 bytes
57
 
57
 
58
        RX_DMA                  = 0x00600000
58
        RX_DMA                  = 0x00600000
59
        TX_DMA                  = 0x00600000
59
        TX_DMA                  = 0x00600000
60
 
60
 
61
;-------------------------------------------------------------------------------------------------
61
;-------------------------------------------------------------------------------------------------
62
; Symbolic offsets to registers.
62
; Symbolic offsets to registers.
63
        cr              = 0x0           ; Command Register
63
        cr              = 0x0           ; Command Register
64
        cfg             = 0x4           ; Configuration Register
64
        cfg             = 0x4           ; Configuration Register
65
        mear            = 0x8           ; EEPROM Access Register
65
        mear            = 0x8           ; EEPROM Access Register
66
        ptscr           = 0xc           ; PCI Test Control Register
66
        ptscr           = 0xc           ; PCI Test Control Register
67
        isr             = 0x10          ; Interrupt Status Register
67
        isr             = 0x10          ; Interrupt Status Register
68
        imr             = 0x14          ; Interrupt Mask Register
68
        imr             = 0x14          ; Interrupt Mask Register
69
        ier             = 0x18          ; Interrupt Enable Register
69
        ier             = 0x18          ; Interrupt Enable Register
70
        epar            = 0x18          ; Enhanced PHY Access Register
70
        epar            = 0x18          ; Enhanced PHY Access Register
71
        txdp            = 0x20          ; Transmit Descriptor Pointer Register
71
        txdp            = 0x20          ; Transmit Descriptor Pointer Register
72
        txcfg           = 0x24          ; Transmit Configuration Register
72
        txcfg           = 0x24          ; Transmit Configuration Register
73
        rxdp            = 0x30          ; Receive Descriptor Pointer Register
73
        rxdp            = 0x30          ; Receive Descriptor Pointer Register
74
        rxcfg           = 0x34          ; Receive Configuration Register
74
        rxcfg           = 0x34          ; Receive Configuration Register
75
        flctrl          = 0x38          ; Flow Control Register
75
        flctrl          = 0x38          ; Flow Control Register
76
        rxlen           = 0x3c          ; Receive Packet Length Register
76
        rxlen           = 0x3c          ; Receive Packet Length Register
77
        rfcr            = 0x48          ; Receive Filter Control Register
77
        rfcr            = 0x48          ; Receive Filter Control Register
78
        rfdr            = 0x4C          ; Receive Filter Data Register
78
        rfdr            = 0x4C          ; Receive Filter Data Register
79
        pmctrl          = 0xB0          ; Power Management Control Register
79
        pmctrl          = 0xB0          ; Power Management Control Register
80
        pmer            = 0xB4          ; Power Management Wake-up Event Register
80
        pmer            = 0xB4          ; Power Management Wake-up Event Register
81
 
81
 
82
; Command Register Bits
82
; Command Register Bits
83
        RELOAD          = 0x00000400
83
        RELOAD          = 0x00000400
84
        ACCESSMODE      = 0x00000200
84
        ACCESSMODE      = 0x00000200
85
        RESET           = 0x00000100
85
        RESET           = 0x00000100
86
        SWI             = 0x00000080
86
        SWI             = 0x00000080
87
        RxRESET         = 0x00000020
87
        RxRESET         = 0x00000020
88
        TxRESET         = 0x00000010
88
        TxRESET         = 0x00000010
89
        RxDIS           = 0x00000008
89
        RxDIS           = 0x00000008
90
        RxENA           = 0x00000004
90
        RxENA           = 0x00000004
91
        TxDIS           = 0x00000002
91
        TxDIS           = 0x00000002
92
        TxENA           = 0x00000001
92
        TxENA           = 0x00000001
93
 
93
 
94
; Configuration Register Bits
94
; Configuration Register Bits
95
        DESCRFMT        = 0x00000100    ; 7016 specific
95
        DESCRFMT        = 0x00000100    ; 7016 specific
96
        REQALG          = 0x00000080
96
        REQALG          = 0x00000080
97
        SB              = 0x00000040
97
        SB              = 0x00000040
98
        POW             = 0x00000020
98
        POW             = 0x00000020
99
        EXD             = 0x00000010
99
        EXD             = 0x00000010
100
        PESEL           = 0x00000008
100
        PESEL           = 0x00000008
101
        LPM             = 0x00000004
101
        LPM             = 0x00000004
102
        BEM             = 0x00000001
102
        BEM             = 0x00000001
103
        RND_CNT         = 0x00000400
103
        RND_CNT         = 0x00000400
104
        FAIR_BACKOFF    = 0x00000200
104
        FAIR_BACKOFF    = 0x00000200
105
        EDB_MASTER_EN   = 0x00002000
105
        EDB_MASTER_EN   = 0x00002000
106
 
106
 
107
; Eeprom Access Reigster Bits
107
; Eeprom Access Reigster Bits
108
        MDC             = 0x00000040
108
        MDC             = 0x00000040
109
        MDDIR           = 0x00000020
109
        MDDIR           = 0x00000020
110
        MDIO            = 0x00000010    ; 7016 specific
110
        MDIO            = 0x00000010    ; 7016 specific
111
        EECS            = 0x00000008
111
        EECS            = 0x00000008
112
        EECLK           = 0x00000004
112
        EECLK           = 0x00000004
113
        EEDO            = 0x00000002
113
        EEDO            = 0x00000002
114
        EEDI            = 0x00000001
114
        EEDI            = 0x00000001
115
 
115
 
116
; TX Configuration Register Bits
116
; TX Configuration Register Bits
117
        ATP             = 0x10000000    ; Automatic Transmit Padding
117
        ATP             = 0x10000000    ; Automatic Transmit Padding
118
        MLB             = 0x20000000    ; Mac Loopback Enable
118
        MLB             = 0x20000000    ; Mac Loopback Enable
119
        HBI             = 0x40000000    ; HeartBeat Ignore (Req for full-dup)
119
        HBI             = 0x40000000    ; HeartBeat Ignore (Req for full-dup)
120
        CSI             = 0x80000000    ; CarrierSenseIgnore (Req for full-du
120
        CSI             = 0x80000000    ; CarrierSenseIgnore (Req for full-du
121
 
121
 
122
; RX Configuration Register Bits
122
; RX Configuration Register Bits
123
        AJAB            = 0x08000000    ;
123
        AJAB            = 0x08000000    ;
124
        ATX             = 0x10000000    ; Accept Transmit Packets
124
        ATX             = 0x10000000    ; Accept Transmit Packets
125
        ARP             = 0x40000000    ; accept runt packets (<64bytes)
125
        ARP             = 0x40000000    ; accept runt packets (<64bytes)
126
        AEP             = 0x80000000    ; accept error packets
126
        AEP             = 0x80000000    ; accept error packets
127
 
127
 
128
; Interrupt Register Bits
128
; Interrupt Register Bits
129
        WKEVT           = 0x10000000
129
        WKEVT           = 0x10000000
130
        TxPAUSEEND      = 0x08000000
130
        TxPAUSEEND      = 0x08000000
131
        TxPAUSE         = 0x04000000
131
        TxPAUSE         = 0x04000000
132
        TxRCMP          = 0x02000000    ; Transmit Reset Complete
132
        TxRCMP          = 0x02000000    ; Transmit Reset Complete
133
        RxRCMP          = 0x01000000    ; Receive Reset Complete
133
        RxRCMP          = 0x01000000    ; Receive Reset Complete
134
        DPERR           = 0x00800000
134
        DPERR           = 0x00800000
135
        SSERR           = 0x00400000
135
        SSERR           = 0x00400000
136
        RMABT           = 0x00200000
136
        RMABT           = 0x00200000
137
        RTABT           = 0x00100000
137
        RTABT           = 0x00100000
138
        RxSOVR          = 0x00010000
138
        RxSOVR          = 0x00010000
139
        HIBERR          = 0x00008000
139
        HIBERR          = 0x00008000
140
        SWINT           = 0x00001000
140
        SWINT           = 0x00001000
141
        MIBINT          = 0x00000800
141
        MIBINT          = 0x00000800
142
        TxURN           = 0x00000400
142
        TxURN           = 0x00000400
143
        TxIDLE          = 0x00000200
143
        TxIDLE          = 0x00000200
144
        TxERR           = 0x00000100
144
        TxERR           = 0x00000100
145
        TxDESC          = 0x00000080
145
        TxDESC          = 0x00000080
146
        TxOK            = 0x00000040
146
        TxOK            = 0x00000040
147
        RxORN           = 0x00000020
147
        RxORN           = 0x00000020
148
        RxIDLE          = 0x00000010
148
        RxIDLE          = 0x00000010
149
        RxEARLY         = 0x00000008
149
        RxEARLY         = 0x00000008
150
        RxERR           = 0x00000004
150
        RxERR           = 0x00000004
151
        RxDESC          = 0x00000002
151
        RxDESC          = 0x00000002
152
        RxOK            = 0x00000001
152
        RxOK            = 0x00000001
153
 
153
 
154
; Interrupt Enable Register Bits
154
; Interrupt Enable Register Bits
155
        IE              = RxOK + TxOK
155
        IE              = RxOK + TxOK
156
 
156
 
157
; Revision ID
157
; Revision ID
158
        SIS900B_900_REV         = 0x03
158
        SIS900B_900_REV         = 0x03
159
        SIS630A_900_REV         = 0x80
159
        SIS630A_900_REV         = 0x80
160
        SIS630E_900_REV         = 0x81
160
        SIS630E_900_REV         = 0x81
161
        SIS630S_900_REV         = 0x82
161
        SIS630S_900_REV         = 0x82
162
        SIS630EA1_900_REV       = 0x83
162
        SIS630EA1_900_REV       = 0x83
163
        SIS630ET_900_REV        = 0x84
163
        SIS630ET_900_REV        = 0x84
164
        SIS635A_900_REV         = 0x90
164
        SIS635A_900_REV         = 0x90
165
        SIS900_960_REV          = 0x91
165
        SIS900_960_REV          = 0x91
166
 
166
 
167
; Receive Filter Control Register Bits
167
; Receive Filter Control Register Bits
168
        RFEN            = 0x80000000            ; enable
168
        RFEN            = 0x80000000            ; enable
169
        RFAAB           = 0x40000000            ; accept all broadcasts
169
        RFAAB           = 0x40000000            ; accept all broadcasts
170
        RFAAM           = 0x20000000            ; accept all multicasts
170
        RFAAM           = 0x20000000            ; accept all multicasts
171
        RFAAP           = 0x10000000            ; accept all packets
171
        RFAAP           = 0x10000000            ; accept all packets
172
 
172
 
173
; Reveive Filter Data Mask
173
; Reveive Filter Data Mask
174
        RFDAT           = 0x0000FFFF
174
        RFDAT           = 0x0000FFFF
175
 
175
 
176
; Eeprom Address
176
; Eeprom Address
177
        EEPROMSignature = 0x00
177
        EEPROMSignature = 0x00
178
        EEPROMVendorID  = 0x02
178
        EEPROMVendorID  = 0x02
179
        EEPROMDeviceID  = 0x03
179
        EEPROMDeviceID  = 0x03
180
        EEPROMMACAddr   = 0x08
180
        EEPROMMACAddr   = 0x08
181
        EEPROMChecksum  = 0x0b
181
        EEPROMChecksum  = 0x0b
182
 
182
 
183
; The EEPROM commands include the alway-set leading bit.
183
; The EEPROM commands include the alway-set leading bit.
184
        EEread          = 0x0180
184
        EEread          = 0x0180
185
        EEwrite         = 0x0140
185
        EEwrite         = 0x0140
186
        EEerase         = 0x01C0
186
        EEerase         = 0x01C0
187
        EEwriteEnable   = 0x0130
187
        EEwriteEnable   = 0x0130
188
        EEwriteDisable  = 0x0100
188
        EEwriteDisable  = 0x0100
189
        EEeraseAll      = 0x0120
189
        EEeraseAll      = 0x0120
190
        EEwriteAll      = 0x0110
190
        EEwriteAll      = 0x0110
191
        EEaddrMask      = 0x013F
191
        EEaddrMask      = 0x013F
192
        EEcmdShift      = 16
192
        EEcmdShift      = 16
193
 
193
 
194
; For SiS962 or SiS963, request the eeprom software access
194
; For SiS962 or SiS963, request the eeprom software access
195
        EEREQ           = 0x00000400
195
        EEREQ           = 0x00000400
196
        EEDONE          = 0x00000200
196
        EEDONE          = 0x00000200
197
        EEGNT           = 0x00000100
197
        EEGNT           = 0x00000100
198
 
198
 
199
section '.flat' readable writable executable
199
section '.flat' readable writable executable
200
 
200
 
201
include '../proc32.inc'
201
include '../proc32.inc'
202
include '../struct.inc'
202
include '../struct.inc'
203
include '../macros.inc'
203
include '../macros.inc'
204
include '../fdo.inc'
204
include '../fdo.inc'
205
include '../netdrv_pe.inc'
205
include '../netdrv.inc'
206
 
206
 
207
 
207
 
208
struct  device          ETH_DEVICE
208
struct  device          ETH_DEVICE
209
 
209
 
210
        io_addr         dd ?
210
        io_addr         dd ?
211
        pci_bus         dd ?
211
        pci_bus         dd ?
212
        pci_dev         dd ?
212
        pci_dev         dd ?
213
        irq_line        db ?
213
        irq_line        db ?
214
        cur_rx          db ?
214
        cur_rx          db ?
215
        cur_tx          db ?
215
        cur_tx          db ?
216
        last_tx         db ?
216
        last_tx         db ?
217
        pci_revision    db ?
217
        pci_revision    db ?
218
        table_entries   db ?
218
        table_entries   db ?
219
 
219
 
220
        rb 0x100 - ($ and 0xff) ; align 256
220
        rb 0x100 - ($ and 0xff) ; align 256
221
        txd             rd (4 * NUM_TX_DESC)
221
        txd             rd (4 * NUM_TX_DESC)
222
        rxd             rd (4 * NUM_RX_DESC)
222
        rxd             rd (4 * NUM_RX_DESC)
223
 
223
 
224
ends
224
ends
225
 
225
 
226
macro   ee_delay {
226
macro   ee_delay {
227
        push    eax
227
        push    eax
228
        in      eax, dx
228
        in      eax, dx
229
        in      eax, dx
229
        in      eax, dx
230
        in      eax, dx
230
        in      eax, dx
231
        in      eax, dx
231
        in      eax, dx
232
        in      eax, dx
232
        in      eax, dx
233
        in      eax, dx
233
        in      eax, dx
234
        in      eax, dx
234
        in      eax, dx
235
        in      eax, dx
235
        in      eax, dx
236
        in      eax, dx
236
        in      eax, dx
237
        in      eax, dx
237
        in      eax, dx
238
        pop     eax
238
        pop     eax
239
}
239
}
240
 
240
 
241
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
242
;;                        ;;
242
;;                        ;;
243
;; proc START             ;;
243
;; proc START             ;;
244
;;                        ;;
244
;;                        ;;
245
;; (standard driver proc) ;;
245
;; (standard driver proc) ;;
246
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
246
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
247
 
247
 
248
; Driver entry point - register our service when the driver is loading.
248
; Driver entry point - register our service when the driver is loading.
249
; TODO: add needed operations when unloading
249
; TODO: add needed operations when unloading
250
 
250
 
251
proc START c, reason:dword, cmdline:dword
251
proc START c, reason:dword, cmdline:dword
252
 
252
 
253
        cmp     [reason], DRV_ENTRY
253
        cmp     [reason], DRV_ENTRY
254
        jne     .fail
254
        jne     .fail
255
 
255
 
256
        DEBUGF  2,"Loading driver\n"
256
        DEBUGF  2,"Loading driver\n"
257
        invoke  RegService, my_service, service_proc
257
        invoke  RegService, my_service, service_proc
258
        ret
258
        ret
259
 
259
 
260
  .fail:
260
  .fail:
261
        xor     eax, eax
261
        xor     eax, eax
262
        ret
262
        ret
263
 
263
 
264
endp
264
endp
265
 
265
 
266
 
266
 
267
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
267
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268
;;                        ;;
268
;;                        ;;
269
;; proc SERVICE_PROC      ;;
269
;; proc SERVICE_PROC      ;;
270
;;                        ;;
270
;;                        ;;
271
;; (standard driver proc) ;;
271
;; (standard driver proc) ;;
272
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
272
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
273
 
273
 
274
; Service procedure for the driver - handle all I/O requests for the driver.
274
; Service procedure for the driver - handle all I/O requests for the driver.
275
; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
275
; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
276
service_proc:
276
service_proc:
277
; 1. Get parameter from the stack: [esp+4] is the first parameter,
277
; 1. Get parameter from the stack: [esp+4] is the first parameter,
278
;       pointer to IOCTL structure.
278
;       pointer to IOCTL structure.
279
        mov     edx, [esp+4]    ; edx -> IOCTL
279
        mov     edx, [esp+4]    ; edx -> IOCTL
280
; 2. Get request code and select a handler for the code.
280
; 2. Get request code and select a handler for the code.
281
        mov     eax, [edx + IOCTL.io_code]
281
        mov     eax, [edx + IOCTL.io_code]
282
        test    eax, eax        ; check for SRV_GETVERSION
282
        test    eax, eax        ; check for SRV_GETVERSION
283
        jnz     @f
283
        jnz     @f
284
; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
284
; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
285
; 3a. Output size must be at least 4 bytes.
285
; 3a. Output size must be at least 4 bytes.
286
        cmp     [edx + IOCTL.out_size], 4
286
        cmp     [edx + IOCTL.out_size], 4
287
        jb      .fail
287
        jb      .fail
288
; 3b. Write result to the output buffer.
288
; 3b. Write result to the output buffer.
289
        mov     eax, [edx + IOCTL.output]
289
        mov     eax, [edx + IOCTL.output]
290
        mov     [eax], dword API_VERSION
290
        mov     [eax], dword API_VERSION
291
; 3c. Return success.
291
; 3c. Return success.
292
        xor     eax, eax
292
        xor     eax, eax
293
        ret     4
293
        ret     4
294
  @@:
294
  @@:
295
        dec     eax     ; check for SRV_HOOK
295
        dec     eax     ; check for SRV_HOOK
296
        jnz     .fail
296
        jnz     .fail
297
; 4. This is SRV_HOOK request, input defines the device to hook, no output.
297
; 4. This is SRV_HOOK request, input defines the device to hook, no output.
298
; 4a. The driver works only with PCI devices,
298
; 4a. The driver works only with PCI devices,
299
;       so input must be at least 3 bytes long.
299
;       so input must be at least 3 bytes long.
300
        cmp     [edx + IOCTL.inp_size], 3
300
        cmp     [edx + IOCTL.inp_size], 3
301
        jb      .fail
301
        jb      .fail
302
; 4b. First byte of input is bus type, 1 stands for PCI.
302
; 4b. First byte of input is bus type, 1 stands for PCI.
303
        mov     eax, [edx + IOCTL.input]
303
        mov     eax, [edx + IOCTL.input]
304
        cmp     byte [eax], 1
304
        cmp     byte [eax], 1
305
        jne     .fail
305
        jne     .fail
306
; 4c. Second and third bytes of the input define the device: bus and dev.
306
; 4c. Second and third bytes of the input define the device: bus and dev.
307
;       Word in bx holds both bytes.
307
;       Word in bx holds both bytes.
308
        mov     bx, [eax+1]
308
        mov     bx, [eax+1]
309
; 4d. Check if the device was already hooked,
309
; 4d. Check if the device was already hooked,
310
;       scan through the list of known devices.
310
;       scan through the list of known devices.
311
; check if the device is already listed
311
; check if the device is already listed
312
        mov     esi, device_list
312
        mov     esi, device_list
313
        mov     ecx, [devices]
313
        mov     ecx, [devices]
314
        test    ecx, ecx
314
        test    ecx, ecx
315
        jz      .firstdevice
315
        jz      .firstdevice
316
 
316
 
317
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
317
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
318
        mov     ax, [eax+1]                             ;
318
        mov     ax, [eax+1]                             ;
319
  .nextdevice:
319
  .nextdevice:
320
        mov     ebx, [esi]
320
        mov     ebx, [esi]
321
        cmp     al, byte[ebx + device.pci_bus]
321
        cmp     al, byte[ebx + device.pci_bus]
322
        jne     @f
322
        jne     @f
323
        cmp     ah, byte[ebx + device.pci_dev]
323
        cmp     ah, byte[ebx + device.pci_dev]
324
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
324
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
325
       @@:
325
       @@:
326
        add     esi, 4
326
        add     esi, 4
327
        loop    .nextdevice
327
        loop    .nextdevice
328
; 4e. This device doesn't have its own eth_device structure yet, let's create one
328
; 4e. This device doesn't have its own eth_device structure yet, let's create one
329
  .firstdevice:
329
  .firstdevice:
330
; 4f. Check that we have place for new device.
330
; 4f. Check that we have place for new device.
331
        cmp     [devices], MAX_DEVICES
331
        cmp     [devices], MAX_DEVICES
332
        jae     .fail
332
        jae     .fail
333
; 4g. Allocate memory for device descriptor and receive+transmit buffers.
333
; 4g. Allocate memory for device descriptor and receive+transmit buffers.
334
; 4h. Zero the structure.
334
; 4h. Zero the structure.
335
        allocate_and_clear ebx, sizeof.device, .fail
335
        allocate_and_clear ebx, sizeof.device, .fail
336
; 4i. Save PCI coordinates
336
; 4i. Save PCI coordinates
337
        mov     eax, [edx + IOCTL.input]
337
        mov     eax, [edx + IOCTL.input]
338
        movzx   ecx, byte[eax+1]
338
        movzx   ecx, byte[eax+1]
339
        mov     [ebx + device.pci_bus], ecx
339
        mov     [ebx + device.pci_bus], ecx
340
        movzx   ecx, byte[eax+2]
340
        movzx   ecx, byte[eax+2]
341
        mov     [ebx + device.pci_dev], ecx
341
        mov     [ebx + device.pci_dev], ecx
342
; 4j. Fill in the direct call addresses into the struct.
342
; 4j. Fill in the direct call addresses into the struct.
343
        mov     [ebx + device.reset], reset
343
        mov     [ebx + device.reset], reset
344
        mov     [ebx + device.transmit], transmit
344
        mov     [ebx + device.transmit], transmit
345
        mov     [ebx + device.unload], unload
345
        mov     [ebx + device.unload], unload
346
        mov     [ebx + device.name], my_service
346
        mov     [ebx + device.name], my_service
347
 
347
 
348
; 4k. Now, it's time to find the base io addres of the PCI device
348
; 4k. Now, it's time to find the base io addres of the PCI device
349
; TODO: implement check if bus and dev exist on this machine
349
; TODO: implement check if bus and dev exist on this machine
350
 
350
 
351
; Now, it's time to find the base io addres of the PCI device
351
; Now, it's time to find the base io addres of the PCI device
352
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
352
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
353
        mov     [ebx + device.io_addr], eax
353
        mov     [ebx + device.io_addr], eax
354
 
354
 
355
; We've found the io address, find IRQ now
355
; We've found the io address, find IRQ now
356
 
356
 
357
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
357
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
358
        mov     [ebx + device.irq_line], al
358
        mov     [ebx + device.irq_line], al
359
 
359
 
360
; 4m. Add new device to the list (required for int_handler).
360
; 4m. Add new device to the list (required for int_handler).
361
        mov     eax, [devices]
361
        mov     eax, [devices]
362
        mov     [device_list+4*eax], ebx
362
        mov     [device_list+4*eax], ebx
363
        inc     [devices]
363
        inc     [devices]
364
 
364
 
365
; 4m. Ok, the eth_device structure is ready, let's probe the device
365
; 4m. Ok, the eth_device structure is ready, let's probe the device
366
        call    probe
366
        call    probe
367
        test    eax, eax
367
        test    eax, eax
368
        jnz     .destroy
368
        jnz     .destroy
369
; 4n. If device was successfully initialized, register it for the kernel.
369
; 4n. If device was successfully initialized, register it for the kernel.
370
 
370
 
371
        mov     [ebx + device.type], NET_TYPE_ETH
371
        mov     [ebx + device.type], NET_TYPE_ETH
372
        invoke  NetRegDev
372
        invoke  NetRegDev
373
 
373
 
374
        cmp     eax, -1
374
        cmp     eax, -1
375
        je      .destroy
375
        je      .destroy
376
 
376
 
377
        ret     4
377
        ret     4
378
 
378
 
379
; 5. If the device was already loaded, find the device number and return it in eax
379
; 5. If the device was already loaded, find the device number and return it in eax
380
 
380
 
381
  .find_devicenum:
381
  .find_devicenum:
382
        invoke  NetPtrToNum                             ; This kernel procedure converts a pointer to device struct in ebx
382
        invoke  NetPtrToNum                             ; This kernel procedure converts a pointer to device struct in ebx
383
                                                        ; into a device number in edi
383
                                                        ; into a device number in edi
384
        mov     eax, edi                                ; Application wants it in eax instead
384
        mov     eax, edi                                ; Application wants it in eax instead
385
        ret     4
385
        ret     4
386
 
386
 
387
; If an error occured, remove all allocated data and exit (returning -1 in eax)
387
; If an error occured, remove all allocated data and exit (returning -1 in eax)
388
 
388
 
389
  .destroy:
389
  .destroy:
390
        dec     [devices]
390
        dec     [devices]
391
        ; todo: reset device into virgin state
391
        ; todo: reset device into virgin state
392
 
392
 
393
  .err:
393
  .err:
394
        invoke  KernelFree, ebx
394
        invoke  KernelFree, ebx
395
 
395
 
396
  .fail:
396
  .fail:
397
        xor     eax, eax
397
        xor     eax, eax
398
        ret     4
398
        ret     4
399
 
399
 
400
 
400
 
401
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
401
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
402
;;                                                                        ;;
402
;;                                                                        ;;
403
;;        Actual Hardware dependent code starts here                      ;;
403
;;        Actual Hardware dependent code starts here                      ;;
404
;;                                                                        ;;
404
;;                                                                        ;;
405
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
405
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
406
 
406
 
407
unload:
407
unload:
408
        ; TODO: (in this particular order)
408
        ; TODO: (in this particular order)
409
        ;
409
        ;
410
        ; - Stop the device
410
        ; - Stop the device
411
        ; - Detach int handler
411
        ; - Detach int handler
412
        ; - Remove device from local list
412
        ; - Remove device from local list
413
        ; - call unregister function in kernel
413
        ; - call unregister function in kernel
414
        ; - Remove all allocated structures and buffers the card used
414
        ; - Remove all allocated structures and buffers the card used
415
 
415
 
416
        or      eax, -1
416
        or      eax, -1
417
 
417
 
418
ret
418
ret
419
 
419
 
420
;***************************************************************************
420
;***************************************************************************
421
;
421
;
422
; probe
422
; probe
423
;
423
;
424
; checks the card and enables it
424
; checks the card and enables it
425
;
425
;
426
; TODO: probe mii transceivers
426
; TODO: probe mii transceivers
427
;
427
;
428
;***************************************************************************
428
;***************************************************************************
429
align 4
429
align 4
430
probe:
430
probe:
431
        DEBUGF  1, "Probe\n"
431
        DEBUGF  1, "Probe\n"
432
 
432
 
433
; wake up device
433
; wake up device
434
; TODO: check capabilities pointer instead of using hardcoded offset.
434
; TODO: check capabilities pointer instead of using hardcoded offset.
435
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, 0
435
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, 0
436
 
436
 
437
; Make the device a bus master
437
; Make the device a bus master
438
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
438
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
439
        or      al, PCI_CMD_MASTER
439
        or      al, PCI_CMD_MASTER
440
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
440
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
441
 
441
 
442
; Adjust PCI latency to be at least 64
442
; Adjust PCI latency to be at least 64
443
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
443
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
444
        cmp     al, 64
444
        cmp     al, 64
445
        jae     @f
445
        jae     @f
446
        mov     al, 64
446
        mov     al, 64
447
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
447
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
448
  @@:
448
  @@:
449
 
449
 
450
; Get Card Revision
450
; Get Card Revision
451
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x08
451
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x08
452
        mov     [ebx + device.pci_revision], al         ; save the revision for later use
452
        mov     [ebx + device.pci_revision], al         ; save the revision for later use
453
 
453
 
454
; Look up through the specific_table
454
; Look up through the specific_table
455
        mov     esi, specific_table
455
        mov     esi, specific_table
456
  .tableloop:
456
  .tableloop:
457
        cmp     dword[esi], 0                           ; Check if we reached end of the list
457
        cmp     dword[esi], 0                           ; Check if we reached end of the list
458
        je      .notsupported
458
        je      .notsupported
459
        cmp     al, [esi]                               ; Check if revision is OK
459
        cmp     al, [esi]                               ; Check if revision is OK
460
        je      .ok
460
        je      .ok
461
        add     esi, 12                                 ; Advance to next entry
461
        add     esi, 12                                 ; Advance to next entry
462
        jmp     .tableloop
462
        jmp     .tableloop
463
  .ok:
463
  .ok:
464
        call     dword[esi + 4]                         ; "get MAC" function
464
        call     dword[esi + 4]                         ; "get MAC" function
465
 
465
 
466
; Set table entries
466
; Set table entries
467
        mov      [ebx + device.table_entries], 16
467
        mov      [ebx + device.table_entries], 16
468
        cmp      [ebx + device.pci_revision], SIS635A_900_REV
468
        cmp      [ebx + device.pci_revision], SIS635A_900_REV
469
        jae      @f
469
        jae      @f
470
        cmp      [ebx + device.pci_revision], SIS900B_900_REV
470
        cmp      [ebx + device.pci_revision], SIS900B_900_REV
471
        je       @f
471
        je       @f
472
        mov      [ebx + device.table_entries], 8
472
        mov      [ebx + device.table_entries], 8
473
       @@:
473
       @@:
474
 
474
 
475
; TODO: Probe for mii transceiver
475
; TODO: Probe for mii transceiver
476
        jmp     reset
476
        jmp     reset
477
 
477
 
478
  .notsupported:
478
  .notsupported:
479
        DEBUGF  2, "Device not supported\n"
479
        DEBUGF  2, "Device not supported\n"
480
        or      eax, -1
480
        or      eax, -1
481
 
481
 
482
        ret
482
        ret
483
 
483
 
484
reset:
484
reset:
485
 
485
 
486
        DEBUGF  1, "reset\n"
486
        DEBUGF  1, "reset\n"
487
 
487
 
488
        movzx   eax, [ebx + device.irq_line]
488
        movzx   eax, [ebx + device.irq_line]
489
        invoke  AttachIntHandler, eax, int_handler, ebx
489
        invoke  AttachIntHandler, eax, int_handler, ebx
490
        test    eax, eax
490
        test    eax, eax
491
        jnz     @f
491
        jnz     @f
492
        DEBUGF  2,"Could not attach int handler!\n"
492
        DEBUGF  2,"Could not attach int handler!\n"
493
        or      eax, -1
493
        or      eax, -1
494
        ret
494
        ret
495
       @@:   
495
       @@:   
496
 
496
 
497
;--------------------------------------------
497
;--------------------------------------------
498
; Disable Interrupts and reset Receive Filter
498
; Disable Interrupts and reset Receive Filter
499
 
499
 
500
        set_io  [ebx + device.io_addr], 0
500
        set_io  [ebx + device.io_addr], 0
501
        set_io  [ebx + device.io_addr], ier
501
        set_io  [ebx + device.io_addr], ier
502
        xor     eax, eax
502
        xor     eax, eax
503
        out     dx, eax
503
        out     dx, eax
504
 
504
 
505
        set_io  [ebx + device.io_addr], imr
505
        set_io  [ebx + device.io_addr], imr
506
        out     dx, eax
506
        out     dx, eax
507
 
507
 
508
        set_io  [ebx + device.io_addr], rfcr
508
        set_io  [ebx + device.io_addr], rfcr
509
        out     dx, eax
509
        out     dx, eax
510
 
510
 
511
;-----------
511
;-----------
512
; Reset Card
512
; Reset Card
513
 
513
 
514
        set_io  [ebx + device.io_addr], cr
514
        set_io  [ebx + device.io_addr], cr
515
        in      eax, dx                                 ; Get current Command Register
515
        in      eax, dx                                 ; Get current Command Register
516
        or      eax, RESET + RxRESET + TxRESET          ; set flags
516
        or      eax, RESET + RxRESET + TxRESET          ; set flags
517
        out     dx, eax                                 ; Write new Command Register
517
        out     dx, eax                                 ; Write new Command Register
518
 
518
 
519
;----------
519
;----------
520
; Wait loop
520
; Wait loop
521
 
521
 
522
        set_io  [ebx + device.io_addr], isr
522
        set_io  [ebx + device.io_addr], isr
523
        mov     ecx, 1000
523
        mov     ecx, 1000
524
  .loop:
524
  .loop:
525
        dec     ecx
525
        dec     ecx
526
        jz      .fail
526
        jz      .fail
527
        in      eax, dx                                 ; read interrupt status
527
        in      eax, dx                                 ; read interrupt status
528
        test    eax, TxRCMP + RxRCMP
528
        test    eax, TxRCMP + RxRCMP
529
        jz      .loop
529
        jz      .loop
530
        DEBUGF  1, "status=%x\n", eax
530
        DEBUGF  1, "status=%x\n", eax
531
 
531
 
532
;------------------------------------------------------
532
;------------------------------------------------------
533
; Set Configuration Register depending on Card Revision
533
; Set Configuration Register depending on Card Revision
534
 
534
 
535
        set_io  [ebx + device.io_addr], cfg
535
        set_io  [ebx + device.io_addr], cfg
536
        mov     eax, PESEL                              ; Configuration Register Bit
536
        mov     eax, PESEL                              ; Configuration Register Bit
537
        cmp     [ebx + device.pci_revision], SIS635A_900_REV
537
        cmp     [ebx + device.pci_revision], SIS635A_900_REV
538
        je      .match
538
        je      .match
539
        cmp     [ebx + device.pci_revision], SIS900B_900_REV ; Check card revision
539
        cmp     [ebx + device.pci_revision], SIS900B_900_REV ; Check card revision
540
        jne     .done
540
        jne     .done
541
  .match:                                               ; Revision match
541
  .match:                                               ; Revision match
542
        or      eax, RND_CNT                            ; Configuration Register Bit
542
        or      eax, RND_CNT                            ; Configuration Register Bit
543
  .done:
543
  .done:
544
        out     dx, eax
544
        out     dx, eax
545
 
545
 
546
        DEBUGF  1, "Initialising RX Filter\n"
546
        DEBUGF  1, "Initialising RX Filter\n"
547
 
547
 
548
; Get Receive Filter Control Register
548
; Get Receive Filter Control Register
549
        set_io  [ebx + device.io_addr], rfcr
549
        set_io  [ebx + device.io_addr], rfcr
550
        in      eax, dx
550
        in      eax, dx
551
        push    eax
551
        push    eax
552
 
552
 
553
; disable packet filtering before setting filter
553
; disable packet filtering before setting filter
554
        and     eax, not RFEN
554
        and     eax, not RFEN
555
        out     dx, eax
555
        out     dx, eax
556
 
556
 
557
; load MAC addr to filter data register
557
; load MAC addr to filter data register
558
        xor     ecx, ecx
558
        xor     ecx, ecx
559
  .macloop:
559
  .macloop:
560
        mov     eax, ecx
560
        mov     eax, ecx
561
        set_io  [ebx + device.io_addr], 0
561
        set_io  [ebx + device.io_addr], 0
562
        set_io  [ebx + device.io_addr], rfcr
562
        set_io  [ebx + device.io_addr], rfcr
563
        shl     eax, 16                                 ; high word of eax tells card which mac byte to write
563
        shl     eax, 16                                 ; high word of eax tells card which mac byte to write
564
        out     dx, eax                                 ;
564
        out     dx, eax                                 ;
565
        set_io  [ebx + device.io_addr], rfdr
565
        set_io  [ebx + device.io_addr], rfdr
566
        mov     ax, word [ebx + device.mac + ecx*2]     ; Get Mac ID word
566
        mov     ax, word [ebx + device.mac + ecx*2]     ; Get Mac ID word
567
        out     dx, ax                                  ; Send Mac ID
567
        out     dx, ax                                  ; Send Mac ID
568
        inc     cl                                      ; send next word
568
        inc     cl                                      ; send next word
569
        cmp     cl, 3                                   ; more to send?
569
        cmp     cl, 3                                   ; more to send?
570
        jne     .macloop
570
        jne     .macloop
571
 
571
 
572
; enable packet filtering
572
; enable packet filtering
573
        pop     eax                                     ; old register value
573
        pop     eax                                     ; old register value
574
        set_io  [ebx + device.io_addr], rfcr
574
        set_io  [ebx + device.io_addr], rfcr
575
        or      eax, RFEN                               ; enable filtering
575
        or      eax, RFEN                               ; enable filtering
576
        out     dx, eax                                 ; set register
576
        out     dx, eax                                 ; set register
577
 
577
 
578
        DEBUGF  1, "Initialising TX Descriptors\n"
578
        DEBUGF  1, "Initialising TX Descriptors\n"
579
 
579
 
580
        mov     ecx, NUM_TX_DESC
580
        mov     ecx, NUM_TX_DESC
581
        lea     esi, [ebx + device.txd]
581
        lea     esi, [ebx + device.txd]
582
  .txdescloop:
582
  .txdescloop:
583
        lea     eax, [esi + 16]                         ; next ptr
583
        lea     eax, [esi + 16]                         ; next ptr
584
        invoke  GetPhysAddr
584
        invoke  GetPhysAddr
585
        mov     dword[esi], eax                         ; link to next desc
585
        mov     dword[esi], eax                         ; link to next desc
586
        mov     dword[esi + 4], 0                       ; status field
586
        mov     dword[esi + 4], 0                       ; status field
587
        mov     dword[esi + 8], 0                       ; ptr to buffer
587
        mov     dword[esi + 8], 0                       ; ptr to buffer
588
        add     esi, 16
588
        add     esi, 16
589
        dec     ecx
589
        dec     ecx
590
        jnz     .txdescloop
590
        jnz     .txdescloop
591
 
591
 
592
        lea     eax, [ebx + device.txd]
592
        lea     eax, [ebx + device.txd]
593
        invoke  GetPhysAddr
593
        invoke  GetPhysAddr
594
        mov     dword[esi - 16], eax                    ; correct last descriptor link ptr
594
        mov     dword[esi - 16], eax                    ; correct last descriptor link ptr
595
 
595
 
596
        set_io  [ebx + device.io_addr], txdp            ; TX Descriptor Pointer
596
        set_io  [ebx + device.io_addr], txdp            ; TX Descriptor Pointer
597
;        lea     eax, [ebx + device.txd]
597
;        lea     eax, [ebx + device.txd]
598
;        invoke  GetPhysAddr
598
;        invoke  GetPhysAddr
599
        out     dx, eax
599
        out     dx, eax
600
 
600
 
601
        mov     [ebx + device.cur_tx], 0                ; Set current tx descriptor to 0
601
        mov     [ebx + device.cur_tx], 0                ; Set current tx descriptor to 0
602
        mov     [ebx + device.last_tx], 0
602
        mov     [ebx + device.last_tx], 0
603
 
603
 
604
        DEBUGF  1, "Initialising RX Descriptors\n"
604
        DEBUGF  1, "Initialising RX Descriptors\n"
605
 
605
 
606
        mov     ecx, NUM_RX_DESC
606
        mov     ecx, NUM_RX_DESC
607
        lea     esi, [ebx + device.rxd]
607
        lea     esi, [ebx + device.rxd]
608
  .rxdescloop:
608
  .rxdescloop:
609
        lea     eax, [esi + 16]                         ; next ptr
609
        lea     eax, [esi + 16]                         ; next ptr
610
        invoke  GetPhysAddr
610
        invoke  GetPhysAddr
611
        mov     dword [esi], eax
611
        mov     dword [esi], eax
612
        mov     dword [esi + 4], RX_BUFF_SZ             ; size
612
        mov     dword [esi + 4], RX_BUFF_SZ             ; size
613
 
613
 
614
        push    ecx esi
614
        push    ecx esi
615
        invoke  KernelAlloc, RX_BUFF_SZ
615
        invoke  KernelAlloc, RX_BUFF_SZ
616
        pop     esi ecx
616
        pop     esi ecx
617
        test    eax, eax
617
        test    eax, eax
618
        jz      .fail
618
        jz      .fail
619
        mov     dword [esi + 12], eax                   ; address
619
        mov     dword [esi + 12], eax                   ; address
620
        invoke  GetPhysAddr
620
        invoke  GetPhysAddr
621
        mov     dword [esi + 8], eax                    ; real address
621
        mov     dword [esi + 8], eax                    ; real address
622
        add     esi, 16
622
        add     esi, 16
623
        dec     ecx
623
        dec     ecx
624
        jnz     .rxdescloop
624
        jnz     .rxdescloop
625
 
625
 
626
        lea     eax, [ebx + device.rxd]
626
        lea     eax, [ebx + device.rxd]
627
        invoke  GetPhysAddr
627
        invoke  GetPhysAddr
628
        mov     dword [esi - 16], eax                   ; correct last descriptor link ptr
628
        mov     dword [esi - 16], eax                   ; correct last descriptor link ptr
629
 
629
 
630
        set_io  [ebx + device.io_addr], 0
630
        set_io  [ebx + device.io_addr], 0
631
        set_io  [ebx + device.io_addr], rxdp
631
        set_io  [ebx + device.io_addr], rxdp
632
;        lea     eax, [ebx + device.rxd]
632
;        lea     eax, [ebx + device.rxd]
633
;        invoke  GetPhysAddr
633
;        invoke  GetPhysAddr
634
        out     dx, eax
634
        out     dx, eax
635
 
635
 
636
        mov     [ebx + device.cur_rx], 0                ; Set current rx descriptor to 0
636
        mov     [ebx + device.cur_rx], 0                ; Set current rx descriptor to 0
637
 
637
 
638
        DEBUGF  1, "setting RX mode\n"
638
        DEBUGF  1, "setting RX mode\n"
639
 
639
 
640
        xor     cl, cl
640
        xor     cl, cl
641
  .rxfilterloop:
641
  .rxfilterloop:
642
        set_io  [ebx + device.io_addr], 0
642
        set_io  [ebx + device.io_addr], 0
643
        set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Reg offset
643
        set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Reg offset
644
        mov     eax, 4                                  ; determine table entry
644
        mov     eax, 4                                  ; determine table entry
645
        add     al, cl
645
        add     al, cl
646
        shl     eax, 16
646
        shl     eax, 16
647
        out     dx, eax                                 ; tell card which entry to modify
647
        out     dx, eax                                 ; tell card which entry to modify
648
 
648
 
649
        set_io  [ebx + device.io_addr], rfdr            ; Receive Filter Control Reg offset
649
        set_io  [ebx + device.io_addr], rfdr            ; Receive Filter Control Reg offset
650
        mov     eax, 0xffff                             ; entry value
650
        mov     eax, 0xffff                             ; entry value
651
        out     dx, ax                                  ; write value to table in card
651
        out     dx, ax                                  ; write value to table in card
652
 
652
 
653
        inc     cl                                      ; next entry
653
        inc     cl                                      ; next entry
654
        cmp     cl, [ebx + device.table_entries]
654
        cmp     cl, [ebx + device.table_entries]
655
        jb      .rxfilterloop
655
        jb      .rxfilterloop
656
 
656
 
657
        set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Register offset
657
        set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Register offset
658
        mov     eax, RFAAB + RFAAM + RFAAP + RFEN
658
        mov     eax, RFAAB + RFAAM + RFAAP + RFEN
659
        out     dx, eax
659
        out     dx, eax
660
 
660
 
661
        set_io  [ebx + device.io_addr], rxcfg           ; Receive Config Register offset
661
        set_io  [ebx + device.io_addr], rxcfg           ; Receive Config Register offset
662
        mov     eax, ATX + RX_DMA + 2                   ; 0x2 : RX Drain Threshold = 8*8=64 bytes
662
        mov     eax, ATX + RX_DMA + 2                   ; 0x2 : RX Drain Threshold = 8*8=64 bytes
663
        out     dx, eax
663
        out     dx, eax
664
 
664
 
665
        DEBUGF  1, "setting TX mode\n"
665
        DEBUGF  1, "setting TX mode\n"
666
 
666
 
667
        set_io  [ebx + device.io_addr], txcfg           ; Transmit config Register offset
667
        set_io  [ebx + device.io_addr], txcfg           ; Transmit config Register offset
668
        mov     eax, ATP + HBI + CSI + TX_DMA + 0x120   ; TX Fill threshold = 0x100
668
        mov     eax, ATP + HBI + CSI + TX_DMA + 0x120   ; TX Fill threshold = 0x100
669
                                                        ; TX Drain Threshold = 0x20
669
                                                        ; TX Drain Threshold = 0x20
670
        out     dx, eax
670
        out     dx, eax
671
 
671
 
672
        DEBUGF  1, "Enabling interrupts\n"
672
        DEBUGF  1, "Enabling interrupts\n"
673
 
673
 
674
        set_io  [ebx + device.io_addr], imr
674
        set_io  [ebx + device.io_addr], imr
675
        mov     eax, IE                                 ; Interrupt enable mask
675
        mov     eax, IE                                 ; Interrupt enable mask
676
        out     dx, eax
676
        out     dx, eax
677
 
677
 
678
        set_io  [ebx + device.io_addr], cr
678
        set_io  [ebx + device.io_addr], cr
679
        in      eax, dx
679
        in      eax, dx
680
        or      eax, RxENA                              ; Enable Receive
680
        or      eax, RxENA                              ; Enable Receive
681
        out     dx, eax
681
        out     dx, eax
682
 
682
 
683
        set_io  [ebx + device.io_addr], ier             ; Interrupt enable
683
        set_io  [ebx + device.io_addr], ier             ; Interrupt enable
684
        mov     eax, 1
684
        mov     eax, 1
685
        out     dx, eax
685
        out     dx, eax
686
 
686
 
687
        mov     [ebx + device.mtu], 1514
687
        mov     [ebx + device.mtu], 1514
688
 
688
 
689
; Set link state to unknown
689
; Set link state to unknown
690
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
690
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
691
 
691
 
692
        xor     eax, eax
692
        xor     eax, eax
693
        ret
693
        ret
694
 
694
 
695
  .fail:
695
  .fail:
696
        DEBUGF  2, "Resetting device failed\n"
696
        DEBUGF  2, "Resetting device failed\n"
697
        or      eax, -1
697
        or      eax, -1
698
 
698
 
699
        ret
699
        ret
700
 
700
 
701
 
701
 
702
;***************************************************************************
702
;***************************************************************************
703
;
703
;
704
; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
704
; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
705
;
705
;
706
; SiS962 or SiS963 model, use EEPROM to store MAC address.
706
; SiS962 or SiS963 model, use EEPROM to store MAC address.
707
; EEPROM is shared by LAN and 1394.
707
; EEPROM is shared by LAN and 1394.
708
; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT.
708
; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT.
709
; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not.
709
; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not.
710
; After MAC address is read from EEPROM, send
710
; After MAC address is read from EEPROM, send
711
; EEDONE signal to refuse EEPROM access by LAN.
711
; EEDONE signal to refuse EEPROM access by LAN.
712
; The EEPROM map of SiS962 or SiS963 is different to SiS900.
712
; The EEPROM map of SiS962 or SiS963 is different to SiS900.
713
; The signature field in SiS962 or SiS963 spec is meaningless.
713
; The signature field in SiS962 or SiS963 spec is meaningless.
714
;
714
;
715
; Return 0 is EAX = failure
715
; Return 0 is EAX = failure
716
;
716
;
717
;***************************************************************************
717
;***************************************************************************
718
align 4
718
align 4
719
SIS960_get_mac_addr:
719
SIS960_get_mac_addr:
720
        DEBUGF  1, "SIS960 - get mac:\n"
720
        DEBUGF  1, "SIS960 - get mac:\n"
721
 
721
 
722
;-------------------------------
722
;-------------------------------
723
; Send Request for eeprom access
723
; Send Request for eeprom access
724
 
724
 
725
        set_io  [ebx + device.io_addr], 0
725
        set_io  [ebx + device.io_addr], 0
726
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
726
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
727
        mov     eax, EEREQ                              ; Request access to eeprom
727
        mov     eax, EEREQ                              ; Request access to eeprom
728
        out     dx, eax                                 ; Send request
728
        out     dx, eax                                 ; Send request
729
 
729
 
730
;-----------------------------------------------------
730
;-----------------------------------------------------
731
; Loop 4000 times and if access not granted, error out
731
; Loop 4000 times and if access not granted, error out
732
 
732
 
733
        mov     ecx, 4000
733
        mov     ecx, 4000
734
  .loop:
734
  .loop:
735
        in      eax, dx                                 ; get eeprom status
735
        in      eax, dx                                 ; get eeprom status
736
        test    eax, EEGNT                              ; see if eeprom access granted flag is set
736
        test    eax, EEGNT                              ; see if eeprom access granted flag is set
737
        jnz     .got_access                             ; if it is, go access the eeprom
737
        jnz     .got_access                             ; if it is, go access the eeprom
738
        loop    .loop                                   ; else keep waiting
738
        loop    .loop                                   ; else keep waiting
739
 
739
 
740
        DEBUGF  2, "Access to EEprom failed!\n", 0
740
        DEBUGF  2, "Access to EEprom failed!\n", 0
741
 
741
 
742
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
742
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
743
        mov     eax, EEDONE                             ; tell eeprom we are done
743
        mov     eax, EEDONE                             ; tell eeprom we are done
744
        out     dx, eax
744
        out     dx, eax
745
 
745
 
746
        or      eax, -1                                 ; error
746
        or      eax, -1                                 ; error
747
        ret
747
        ret
748
 
748
 
749
  .got_access:
749
  .got_access:
750
 
750
 
751
;------------------------------------------
751
;------------------------------------------
752
; EEprom access granted, read MAC from card
752
; EEprom access granted, read MAC from card
753
 
753
 
754
    ; zero based so 3-16 bit reads will take place
754
    ; zero based so 3-16 bit reads will take place
755
 
755
 
756
        mov     ecx, 2
756
        mov     ecx, 2
757
  .read_loop:
757
  .read_loop:
758
        mov     eax, EEPROMMACAddr                      ; Base Mac Address
758
        mov     eax, EEPROMMACAddr                      ; Base Mac Address
759
        add     eax, ecx                                ; Current Mac Byte Offset
759
        add     eax, ecx                                ; Current Mac Byte Offset
760
        push    ecx
760
        push    ecx
761
        call    read_eeprom                             ; try to read 16 bits
761
        call    read_eeprom                             ; try to read 16 bits
762
        pop     ecx
762
        pop     ecx
763
        mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID varible
763
        mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID varible
764
        dec     ecx                                     ; one less word to read
764
        dec     ecx                                     ; one less word to read
765
        jns     .read_loop                              ; if more read more
765
        jns     .read_loop                              ; if more read more
766
        mov     eax, 1                                  ; return non-zero indicating success
766
        mov     eax, 1                                  ; return non-zero indicating success
767
 
767
 
768
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
768
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
769
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
769
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
770
 
770
 
771
;-------------------------------------
771
;-------------------------------------
772
; Tell EEPROM We are Done Accessing It
772
; Tell EEPROM We are Done Accessing It
773
 
773
 
774
  .done:
774
  .done:
775
        set_io  [ebx + device.io_addr], 0
775
        set_io  [ebx + device.io_addr], 0
776
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
776
        set_io  [ebx + device.io_addr], mear            ; Eeprom access register
777
        mov     eax, EEDONE                             ; tell eeprom we are done
777
        mov     eax, EEDONE                             ; tell eeprom we are done
778
        out     dx, eax
778
        out     dx, eax
779
 
779
 
780
        xor     eax, eax                                ; ok
780
        xor     eax, eax                                ; ok
781
        ret
781
        ret
782
 
782
 
783
 
783
 
784
 
784
 
785
 
785
 
786
;***************************************************************************
786
;***************************************************************************
787
;
787
;
788
; get_mac_addr: - Get MAC address for stand alone SiS900 model
788
; get_mac_addr: - Get MAC address for stand alone SiS900 model
789
;
789
;
790
; Older SiS900 and friends, use EEPROM to store MAC address.
790
; Older SiS900 and friends, use EEPROM to store MAC address.
791
;
791
;
792
;***************************************************************************
792
;***************************************************************************
793
align 4
793
align 4
794
SIS900_get_mac_addr:
794
SIS900_get_mac_addr:
795
        DEBUGF  1, "SIS900 - get mac:\n"
795
        DEBUGF  1, "SIS900 - get mac:\n"
796
 
796
 
797
;------------------------------------
797
;------------------------------------
798
; check to see if we have sane EEPROM
798
; check to see if we have sane EEPROM
799
 
799
 
800
        mov     eax, EEPROMSignature                    ; Base Eeprom Signature
800
        mov     eax, EEPROMSignature                    ; Base Eeprom Signature
801
        call    read_eeprom                             ; try to read 16 bits
801
        call    read_eeprom                             ; try to read 16 bits
802
        cmp     ax, 0xffff
802
        cmp     ax, 0xffff
803
        je      .err
803
        je      .err
804
        test    ax, ax
804
        test    ax, ax
805
        je      .err
805
        je      .err
806
 
806
 
807
;-----------
807
;-----------
808
; Read MacID
808
; Read MacID
809
 
809
 
810
; zero based so 3-16 bit reads will take place
810
; zero based so 3-16 bit reads will take place
811
 
811
 
812
        mov     ecx, 2
812
        mov     ecx, 2
813
  .loop:
813
  .loop:
814
        mov     eax, EEPROMMACAddr                      ; Base Mac Address
814
        mov     eax, EEPROMMACAddr                      ; Base Mac Address
815
        add     eax, ecx                                ; Current Mac Byte Offset
815
        add     eax, ecx                                ; Current Mac Byte Offset
816
        push    ecx
816
        push    ecx
817
        call    read_eeprom                             ; try to read 16 bits
817
        call    read_eeprom                             ; try to read 16 bits
818
        pop     ecx
818
        pop     ecx
819
        mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID storage
819
        mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID storage
820
        dec     ecx                                     ; one less word to read
820
        dec     ecx                                     ; one less word to read
821
        jns     .loop                                   ; if more read more
821
        jns     .loop                                   ; if more read more
822
 
822
 
823
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
823
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
824
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
824
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
825
 
825
 
826
        xor     eax, eax
826
        xor     eax, eax
827
        ret
827
        ret
828
 
828
 
829
 
829
 
830
  .err:
830
  .err:
831
        DEBUGF  1, "Access to EEprom failed!\n", 0
831
        DEBUGF  1, "Access to EEprom failed!\n", 0
832
 
832
 
833
        or      eax, -1
833
        or      eax, -1
834
        ret
834
        ret
835
 
835
 
836
 
836
 
837
;***************************************************************************
837
;***************************************************************************
838
;
838
;
839
; Get_Mac_SIS635_900_REV: - Get MAC address for model 635
839
; Get_Mac_SIS635_900_REV: - Get MAC address for model 635
840
;
840
;
841
;***************************************************************************
841
;***************************************************************************
842
align 4
842
align 4
843
Get_Mac_SIS635_900_REV:
843
Get_Mac_SIS635_900_REV:
844
        DEBUGF  1, "SIS635 - get mac:\n"
844
        DEBUGF  1, "SIS635 - get mac:\n"
845
 
845
 
846
        set_io  [ebx + device.io_addr], 0
846
        set_io  [ebx + device.io_addr], 0
847
        set_io  [ebx + device.io_addr], rfcr
847
        set_io  [ebx + device.io_addr], rfcr
848
        in      eax, dx
848
        in      eax, dx
849
        mov     esi, eax
849
        mov     esi, eax
850
 
850
 
851
        set_io  [ebx + device.io_addr], cr
851
        set_io  [ebx + device.io_addr], cr
852
        or      eax, RELOAD
852
        or      eax, RELOAD
853
        out     dx, eax
853
        out     dx, eax
854
 
854
 
855
        xor     eax, eax
855
        xor     eax, eax
856
        out     dx, eax
856
        out     dx, eax
857
 
857
 
858
;-----------------------------------------------
858
;-----------------------------------------------
859
; Disable packet filtering before setting filter
859
; Disable packet filtering before setting filter
860
 
860
 
861
        set_io  [ebx + device.io_addr], rfcr
861
        set_io  [ebx + device.io_addr], rfcr
862
        mov     eax, esi
862
        mov     eax, esi
863
        and     eax, not RFEN
863
        and     eax, not RFEN
864
        out     dx, eax
864
        out     dx, eax
865
 
865
 
866
;---------------------------------
866
;---------------------------------
867
; Load MAC to filter data register
867
; Load MAC to filter data register
868
 
868
 
869
        xor     ecx, ecx
869
        xor     ecx, ecx
870
        lea     edi, [ebx + device.mac]
870
        lea     edi, [ebx + device.mac]
871
  .loop:
871
  .loop:
872
        set_io  [ebx + device.io_addr], 0
872
        set_io  [ebx + device.io_addr], 0
873
        set_io  [ebx + device.io_addr], rfcr
873
        set_io  [ebx + device.io_addr], rfcr
874
        mov     eax, ecx
874
        mov     eax, ecx
875
        shl     eax, RFADDR_shift
875
        shl     eax, RFADDR_shift
876
        out     dx, eax
876
        out     dx, eax
877
 
877
 
878
        set_io  [ebx + device.io_addr], rfdr
878
        set_io  [ebx + device.io_addr], rfdr
879
        in      ax, dx
879
        in      ax, dx
880
        stosw
880
        stosw
881
        inc     ecx
881
        inc     ecx
882
        cmp     ecx, 3
882
        cmp     ecx, 3
883
        jb      .loop
883
        jb      .loop
884
 
884
 
885
;------------------------
885
;------------------------
886
; Enable packet filtering
886
; Enable packet filtering
887
 
887
 
888
        set_io  [ebx + device.io_addr], rfcr
888
        set_io  [ebx + device.io_addr], rfcr
889
        mov     eax, esi
889
        mov     eax, esi
890
        or      eax, RFEN
890
        or      eax, RFEN
891
        out     dx, eax
891
        out     dx, eax
892
 
892
 
893
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
893
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
894
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
894
        [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
895
 
895
 
896
        xor     eax, eax
896
        xor     eax, eax
897
        ret
897
        ret
898
 
898
 
899
;***************************************************************************
899
;***************************************************************************
900
;
900
;
901
; read_eeprom
901
; read_eeprom
902
;
902
;
903
; reads and returns a given location from EEPROM
903
; reads and returns a given location from EEPROM
904
;
904
;
905
; IN:  si = addr
905
; IN:  si = addr
906
; OUT: ax = data
906
; OUT: ax = data
907
;
907
;
908
;***************************************************************************
908
;***************************************************************************
909
align 4
909
align 4
910
read_eeprom:
910
read_eeprom:
911
 
911
 
912
        set_io  [ebx + device.io_addr], 0
912
        set_io  [ebx + device.io_addr], 0
913
        set_io  [ebx + device.io_addr], mear
913
        set_io  [ebx + device.io_addr], mear
914
 
914
 
915
        xor     eax, eax                                ; start send
915
        xor     eax, eax                                ; start send
916
        out     dx, eax
916
        out     dx, eax
917
        ee_delay
917
        ee_delay
918
 
918
 
919
        or      eax, EECLK
919
        or      eax, EECLK
920
        out     dx, eax
920
        out     dx, eax
921
        ee_delay
921
        ee_delay
922
 
922
 
923
;------------------------------------
923
;------------------------------------
924
; Send the read command
924
; Send the read command
925
 
925
 
926
        or      esi, EEread
926
        or      esi, EEread
927
        mov     ecx, 1 shl 9
927
        mov     ecx, 1 shl 9
928
 
928
 
929
  .loop:
929
  .loop:
930
        mov     eax, EECS
930
        mov     eax, EECS
931
        test    esi, ecx
931
        test    esi, ecx
932
        jz      @f
932
        jz      @f
933
        or      eax, EEDI
933
        or      eax, EEDI
934
       @@:
934
       @@:
935
        out     dx, eax
935
        out     dx, eax
936
        ee_delay
936
        ee_delay
937
 
937
 
938
        or      eax, EECLK
938
        or      eax, EECLK
939
        out     dx, eax
939
        out     dx, eax
940
        ee_delay
940
        ee_delay
941
 
941
 
942
        shr     esi, 1
942
        shr     esi, 1
943
        jnc     .loop
943
        jnc     .loop
944
 
944
 
945
        mov     eax, EECS
945
        mov     eax, EECS
946
        out     dx, eax
946
        out     dx, eax
947
        ee_delay
947
        ee_delay
948
 
948
 
949
;------------------------
949
;------------------------
950
; Read 16-bits of data in
950
; Read 16-bits of data in
951
 
951
 
952
        xor     esi, esi
952
        xor     esi, esi
953
        mov     cx, 16
953
        mov     cx, 16
954
  .loop2:
954
  .loop2:
955
        mov     eax, EECS
955
        mov     eax, EECS
956
        out     dx, eax
956
        out     dx, eax
957
        ee_delay
957
        ee_delay
958
 
958
 
959
        or      eax, EECLK
959
        or      eax, EECLK
960
        out     dx, eax
960
        out     dx, eax
961
        ee_delay
961
        ee_delay
962
 
962
 
963
        in      eax, dx
963
        in      eax, dx
964
        shl     esi, 1
964
        shl     esi, 1
965
        test    eax, EEDO
965
        test    eax, EEDO
966
        jz      @f
966
        jz      @f
967
        inc     esi
967
        inc     esi
968
       @@:
968
       @@:
969
        loop    .loop2
969
        loop    .loop2
970
 
970
 
971
;----------------------------
971
;----------------------------
972
; Terminate the EEPROM access
972
; Terminate the EEPROM access
973
 
973
 
974
        xor     eax, eax
974
        xor     eax, eax
975
        out     dx, eax
975
        out     dx, eax
976
        ee_delay
976
        ee_delay
977
 
977
 
978
        mov     eax, EECLK
978
        mov     eax, EECLK
979
        out     dx, eax
979
        out     dx, eax
980
        ee_delay
980
        ee_delay
981
 
981
 
982
        movzx   eax, si
982
        movzx   eax, si
983
 
983
 
984
        ret
984
        ret
985
 
985
 
986
 
986
 
987
 
987
 
988
align 4
988
align 4
989
write_mac:
989
write_mac:
990
        DEBUGF  2,'Setting MAC is not supported for SIS900 card.\n'
990
        DEBUGF  2,'Setting MAC is not supported for SIS900 card.\n'
991
        add     esp, 6
991
        add     esp, 6
992
        ret
992
        ret
993
 
993
 
994
 
994
 
995
 
995
 
996
 
996
 
997
;***************************************************************************
997
;***************************************************************************
998
;   Function
998
;   Function
999
;      transmit
999
;      transmit
1000
;   Description
1000
;   Description
1001
;      Transmits a packet of data via the ethernet card
1001
;      Transmits a packet of data via the ethernet card
1002
;         buffer pointer in [esp+4]
1002
;         buffer pointer in [esp+4]
1003
;         size of buffer in [esp+8]
1003
;         size of buffer in [esp+8]
1004
;         pointer to device structure in ebx
1004
;         pointer to device structure in ebx
1005
;
1005
;
1006
;***************************************************************************
1006
;***************************************************************************
1007
align 4
1007
align 4
1008
 
1008
 
1009
proc transmit stdcall bufferptr, buffersize
1009
proc transmit stdcall bufferptr, buffersize
1010
 
1010
 
1011
        pushf
1011
        pushf
1012
        cli
1012
        cli
1013
 
1013
 
1014
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1014
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1015
        mov     eax, [bufferptr]
1015
        mov     eax, [bufferptr]
1016
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1016
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1017
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1017
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1018
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1018
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1019
        [eax+13]:2,[eax+12]:2
1019
        [eax+13]:2,[eax+12]:2
1020
 
1020
 
1021
        cmp     [buffersize], 1514
1021
        cmp     [buffersize], 1514
1022
        ja      .fail
1022
        ja      .fail
1023
        cmp     [buffersize], 60
1023
        cmp     [buffersize], 60
1024
        jb      .fail
1024
        jb      .fail
1025
 
1025
 
1026
        movzx   ecx, [ebx + device.cur_tx]
1026
        movzx   ecx, [ebx + device.cur_tx]
1027
        shl     ecx, 4                                  ; *16
1027
        shl     ecx, 4                                  ; *16
1028
        lea     ecx, [ebx + device.txd + ecx]
1028
        lea     ecx, [ebx + device.txd + ecx]
1029
 
1029
 
1030
        test    dword[ecx + 4], 0x80000000              ; card owns descriptor ?
1030
        test    dword[ecx + 4], 0x80000000              ; card owns descriptor ?
1031
        jnz     .fail
1031
        jnz     .fail
1032
 
1032
 
1033
        mov     eax, [bufferptr]
1033
        mov     eax, [bufferptr]
1034
        mov     dword[ecx + 12], eax
1034
        mov     dword[ecx + 12], eax
1035
        invoke  GetPhysAddr
1035
        invoke  GetPhysAddr
1036
        mov     dword[ecx + 8], eax                     ; buffer address
1036
        mov     dword[ecx + 8], eax                     ; buffer address
1037
 
1037
 
1038
        mov     eax, [buffersize]
1038
        mov     eax, [buffersize]
1039
        and     eax, DSIZE
1039
        and     eax, DSIZE
1040
        or      eax, 0x80000000                         ; card owns descriptor
1040
        or      eax, 0x80000000                         ; card owns descriptor
1041
        mov     dword[ecx + 4], eax                     ; status field
1041
        mov     dword[ecx + 4], eax                     ; status field
1042
 
1042
 
1043
        set_io  [ebx + device.io_addr], 0
1043
        set_io  [ebx + device.io_addr], 0
1044
        set_io  [ebx + device.io_addr], cr
1044
        set_io  [ebx + device.io_addr], cr
1045
        in      eax, dx
1045
        in      eax, dx
1046
        or      eax, TxENA                              ; Enable the transmit state machine
1046
        or      eax, TxENA                              ; Enable the transmit state machine
1047
        out     dx, eax
1047
        out     dx, eax
1048
 
1048
 
1049
        inc     [ebx + device.cur_tx]
1049
        inc     [ebx + device.cur_tx]
1050
        and     [ebx + device.cur_tx], NUM_TX_DESC-1
1050
        and     [ebx + device.cur_tx], NUM_TX_DESC-1
1051
 
1051
 
1052
; update stats
1052
; update stats
1053
        mov     ecx, [buffersize]
1053
        mov     ecx, [buffersize]
1054
        inc     [ebx + device.packets_tx]
1054
        inc     [ebx + device.packets_tx]
1055
        add     dword [ebx + device.bytes_tx], ecx
1055
        add     dword [ebx + device.bytes_tx], ecx
1056
        adc     dword [ebx + device.bytes_tx + 4], 0
1056
        adc     dword [ebx + device.bytes_tx + 4], 0
1057
 
1057
 
1058
        DEBUGF  1,"Transmit OK\n"
1058
        DEBUGF  1,"Transmit OK\n"
1059
        popf
1059
        popf
1060
        xor     eax, eax
1060
        xor     eax, eax
1061
        ret
1061
        ret
1062
 
1062
 
1063
  .fail:
1063
  .fail:
1064
        DEBUGF  2,"Transmit failed\n"
1064
        DEBUGF  2,"Transmit failed\n"
1065
        invoke  KernelFree, [bufferptr]
1065
        invoke  KernelFree, [bufferptr]
1066
        popf
1066
        popf
1067
        or      eax, -1
1067
        or      eax, -1
1068
        ret
1068
        ret
1069
 
1069
 
1070
endp
1070
endp
1071
 
1071
 
1072
 
1072
 
1073
;***************************************************************************
1073
;***************************************************************************
1074
;
1074
;
1075
; int_handler
1075
; int_handler
1076
;
1076
;
1077
; handles received IRQs, which signal received packets
1077
; handles received IRQs, which signal received packets
1078
;
1078
;
1079
; Currently only supports one descriptor per packet, if packet is fragmented
1079
; Currently only supports one descriptor per packet, if packet is fragmented
1080
; between multiple descriptors you will lose part of the packet
1080
; between multiple descriptors you will lose part of the packet
1081
;
1081
;
1082
;***************************************************************************
1082
;***************************************************************************
1083
 
1083
 
1084
align 4
1084
align 4
1085
int_handler:
1085
int_handler:
1086
 
1086
 
1087
        push    ebx esi edi
1087
        push    ebx esi edi
1088
 
1088
 
1089
        DEBUGF  1,"INT\n"
1089
        DEBUGF  1,"INT\n"
1090
 
1090
 
1091
; find pointer of device which made IRQ occur
1091
; find pointer of device which made IRQ occur
1092
 
1092
 
1093
        mov     ecx, [devices]
1093
        mov     ecx, [devices]
1094
        test    ecx, ecx
1094
        test    ecx, ecx
1095
        jz      .nothing
1095
        jz      .nothing
1096
        mov     esi, device_list
1096
        mov     esi, device_list
1097
  .nextdevice:
1097
  .nextdevice:
1098
        mov     ebx, [esi]
1098
        mov     ebx, [esi]
1099
 
1099
 
1100
        set_io  [ebx + device.io_addr], 0
1100
        set_io  [ebx + device.io_addr], 0
1101
        set_io  [ebx + device.io_addr], isr
1101
        set_io  [ebx + device.io_addr], isr
1102
        in      eax, dx                                 ; note that this clears all interrupts
1102
        in      eax, dx                                 ; note that this clears all interrupts
1103
        test    ax, IE
1103
        test    ax, IE
1104
        jnz     .got_it
1104
        jnz     .got_it
1105
  .continue:
1105
  .continue:
1106
        add     esi, 4
1106
        add     esi, 4
1107
        dec     ecx
1107
        dec     ecx
1108
        jnz     .nextdevice
1108
        jnz     .nextdevice
1109
  .nothing:
1109
  .nothing:
1110
        pop     edi esi ebx
1110
        pop     edi esi ebx
1111
        xor     eax, eax
1111
        xor     eax, eax
1112
 
1112
 
1113
        ret
1113
        ret
1114
 
1114
 
1115
  .got_it:
1115
  .got_it:
1116
 
1116
 
1117
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
1117
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
1118
 
1118
 
1119
        test    ax, RxOK
1119
        test    ax, RxOK
1120
        jz      .no_rx_
1120
        jz      .no_rx_
1121
 
1121
 
1122
        push    ax
1122
        push    ax
1123
 
1123
 
1124
  .rx_loop:
1124
  .rx_loop:
1125
 
1125
 
1126
;-----------
1126
;-----------
1127
; Get Status
1127
; Get Status
1128
        movzx   eax, [ebx + device.cur_rx]              ; find current descriptor
1128
        movzx   eax, [ebx + device.cur_rx]              ; find current descriptor
1129
        shl     eax, 4                                  ; * 16
1129
        shl     eax, 4                                  ; * 16
1130
        mov     ecx, dword[ebx + device.rxd + eax + 4]  ; get receive status
1130
        mov     ecx, dword[ebx + device.rxd + eax + 4]  ; get receive status
1131
 
1131
 
1132
;-------------------------------------------
1132
;-------------------------------------------
1133
; Check RX_Status to see if packet is waiting
1133
; Check RX_Status to see if packet is waiting
1134
        test    ecx, 0x80000000
1134
        test    ecx, 0x80000000
1135
        jz      .no_rx
1135
        jz      .no_rx
1136
 
1136
 
1137
;----------------------------------------------
1137
;----------------------------------------------
1138
; There is a packet waiting check it for errors
1138
; There is a packet waiting check it for errors
1139
        test    ecx, 0x67C0000                          ; see if there are any errors
1139
        test    ecx, 0x67C0000                          ; see if there are any errors
1140
        jnz     .error_status
1140
        jnz     .error_status
1141
 
1141
 
1142
;---------------------
1142
;---------------------
1143
; Check size of packet
1143
; Check size of packet
1144
        and     ecx, DSIZE                              ; get packet size minus CRC
1144
        and     ecx, DSIZE                              ; get packet size minus CRC
1145
        sub     ecx, CRC_SIZE                           ; make sure packet contains data
1145
        sub     ecx, CRC_SIZE                           ; make sure packet contains data
1146
        jbe     .error_size
1146
        jbe     .error_size
1147
 
1147
 
1148
; update statistics
1148
; update statistics
1149
        inc     dword [ebx + device.packets_rx]
1149
        inc     dword [ebx + device.packets_rx]
1150
        add     dword [ebx + device.bytes_rx], ecx
1150
        add     dword [ebx + device.bytes_rx], ecx
1151
        adc     dword [ebx + device.bytes_rx + 4], 0
1151
        adc     dword [ebx + device.bytes_rx + 4], 0
1152
 
1152
 
1153
        push    ebx
1153
        push    ebx
1154
        push    .return
1154
        push    .return
1155
        push    ecx                                     ; packet size
1155
        push    ecx                                     ; packet size
1156
        pushd   [ebx + device.rxd + eax + 12]           ; packet ptr
1156
        pushd   [ebx + device.rxd + eax + 12]           ; packet ptr
1157
        DEBUGF  1, "Packet received OK\n"
1157
        DEBUGF  1, "Packet received OK\n"
1158
        jmp     [Eth_input]
1158
        jmp     [Eth_input]
1159
  .return:
1159
  .return:
1160
        pop     ebx
1160
        pop     ebx
1161
 
1161
 
1162
; Reset status, allow ethernet card access to descriptor
1162
; Reset status, allow ethernet card access to descriptor
1163
        invoke  KernelAlloc, RX_BUFF_SZ
1163
        invoke  KernelAlloc, RX_BUFF_SZ
1164
        test    eax, eax
1164
        test    eax, eax
1165
        jz      .fail
1165
        jz      .fail
1166
        movzx   ecx, [ebx + device.cur_rx]
1166
        movzx   ecx, [ebx + device.cur_rx]
1167
        shl     ecx, 4                                  ; *16
1167
        shl     ecx, 4                                  ; *16
1168
        lea     ecx, [ebx + device.rxd + ecx]
1168
        lea     ecx, [ebx + device.rxd + ecx]
1169
        mov     dword [ecx + 12], eax
1169
        mov     dword [ecx + 12], eax
1170
        invoke  GetPhysAddr
1170
        invoke  GetPhysAddr
1171
        mov     dword [ecx + 8], eax
1171
        mov     dword [ecx + 8], eax
1172
        mov     dword [ecx + 4], RX_BUFF_SZ
1172
        mov     dword [ecx + 4], RX_BUFF_SZ
1173
 
1173
 
1174
        inc     [ebx + device.cur_rx]                   ; get next descriptor
1174
        inc     [ebx + device.cur_rx]                   ; get next descriptor
1175
        and     [ebx + device.cur_rx], NUM_RX_DESC-1    ; only 4 descriptors 0-3
1175
        and     [ebx + device.cur_rx], NUM_RX_DESC-1    ; only 4 descriptors 0-3
1176
 
1176
 
1177
        jmp     .rx_loop
1177
        jmp     .rx_loop
1178
 
1178
 
1179
  .no_rx:
1179
  .no_rx:
1180
        set_io  [ebx + device.io_addr], 0
1180
        set_io  [ebx + device.io_addr], 0
1181
        set_io  [ebx + device.io_addr], cr
1181
        set_io  [ebx + device.io_addr], cr
1182
        in      eax, dx
1182
        in      eax, dx
1183
        or      eax, RxENA                              ; Re-Enable the Receive state machine
1183
        or      eax, RxENA                              ; Re-Enable the Receive state machine
1184
        out     dx, eax
1184
        out     dx, eax
1185
 
1185
 
1186
        pop     ax
1186
        pop     ax
1187
 
1187
 
1188
  .no_rx_:
1188
  .no_rx_:
1189
        test    ax, TxOK
1189
        test    ax, TxOK
1190
        jz      .no_tx
1190
        jz      .no_tx
1191
 
1191
 
1192
        DEBUGF  1, "TX ok!\n"
1192
        DEBUGF  1, "TX ok!\n"
1193
 
1193
 
1194
  .tx_loop:
1194
  .tx_loop:
1195
        movzx   ecx, [ebx + device.last_tx]
1195
        movzx   ecx, [ebx + device.last_tx]
1196
        shl     ecx, 4                  ; *16
1196
        shl     ecx, 4                  ; *16
1197
        lea     ecx, [ebx + device.txd + ecx]
1197
        lea     ecx, [ebx + device.txd + ecx]
1198
 
1198
 
1199
        test    dword[ecx + 4], 0x80000000              ; card owns descr
1199
        test    dword[ecx + 4], 0x80000000              ; card owns descr
1200
        jnz     .no_tx
1200
        jnz     .no_tx
1201
        cmp     dword[ecx + 12], 0
1201
        cmp     dword[ecx + 12], 0
1202
        je      .no_tx
1202
        je      .no_tx
1203
 
1203
 
1204
        DEBUGF  1, "Freeing packet = %x\n", [ecx + 12]:8
1204
        DEBUGF  1, "Freeing packet = %x\n", [ecx + 12]:8
1205
        push    dword[ecx + 12]
1205
        push    dword[ecx + 12]
1206
        mov     dword[ecx + 12], 0
1206
        mov     dword[ecx + 12], 0
1207
        invoke  KernelFree
1207
        invoke  KernelFree
1208
 
1208
 
1209
        inc     [ebx + device.last_tx]
1209
        inc     [ebx + device.last_tx]
1210
        and     [ebx + device.last_tx], NUM_TX_DESC-1
1210
        and     [ebx + device.last_tx], NUM_TX_DESC-1
1211
        jmp     .tx_loop
1211
        jmp     .tx_loop
1212
 
1212
 
1213
  .no_tx:
1213
  .no_tx:
1214
  .fail:
1214
  .fail:
1215
        pop     edi esi ebx
1215
        pop     edi esi ebx
1216
        xor     eax, eax
1216
        xor     eax, eax
1217
        inc     eax
1217
        inc     eax
1218
 
1218
 
1219
        ret
1219
        ret
1220
 
1220
 
1221
        ret
1221
        ret
1222
 
1222
 
1223
  .error_status:
1223
  .error_status:
1224
        DEBUGF  2, "Packet error: %x\n", ecx
1224
        DEBUGF  2, "Packet error: %x\n", ecx
1225
        jmp     .fail
1225
        jmp     .fail
1226
 
1226
 
1227
  .error_size:
1227
  .error_size:
1228
        DEBUGF  2, "Packet too large/small\n"
1228
        DEBUGF  2, "Packet too large/small\n"
1229
        jmp     .fail
1229
        jmp     .fail
1230
 
1230
 
1231
 
1231
 
1232
 
1232
 
1233
 
1233
 
1234
 
1234
 
1235
; End of code
1235
; End of code
1236
 
1236
 
1237
data fixups
1237
data fixups
1238
end data
1238
end data
1239
 
1239
 
1240
include '../peimport.inc'
1240
include '../peimport.inc'
1241
 
1241
 
1242
my_service      db 'SIS900',0                           ; max 16 chars include zero
1242
my_service      db 'SIS900',0                           ; max 16 chars include zero
1243
 
1243
 
1244
specific_table:
1244
specific_table:
1245
;    dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0
1245
;    dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0
1246
;    dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0
1246
;    dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0
1247
    dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0
1247
    dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0
1248
    dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0
1248
    dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0
1249
    dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0      ; SIS630ET_900_REV_SpecialFN
1249
    dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0      ; SIS630ET_900_REV_SpecialFN
1250
    dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0
1250
    dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0
1251
    dd SIS900_960_REV, SIS960_get_mac_addr, 0
1251
    dd SIS900_960_REV, SIS960_get_mac_addr, 0
1252
    dd SIS900B_900_REV, SIS900_get_mac_addr, 0
1252
    dd SIS900B_900_REV, SIS900_get_mac_addr, 0
1253
    dd 0                                                ; end of list
1253
    dd 0                                                ; end of list
1254
 
1254
 
1255
include_debug_strings                                   ; All data wich FDO uses will be included here
1255
include_debug_strings                                   ; All data wich FDO uses will be included here
1256
 
1256
 
1257
align 4
1257
align 4
1258
devices         dd 0
1258
devices         dd 0
1259
device_list     rd MAX_DEVICES                          ; This list contains all pointers to device structures the driver is handling
1259
device_list     rd MAX_DEVICES                          ; This list contains all pointers to device structures the driver is handling
1260
>
1260
>