Subversion Repositories Kolibri OS

Rev

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

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