Subversion Repositories Kolibri OS

Rev

Rev 2304 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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