Subversion Repositories Kolibri OS

Rev

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