Subversion Repositories Kolibri OS

Rev

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

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