Subversion Repositories Kolibri OS

Rev

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