Subversion Repositories Kolibri OS

Rev

Rev 3205 | 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.
2910 hidnplayr 331
        mov     [device.reset], reset
2387 hidnplayr 332
        mov     [device.transmit], transmit
333
        mov     [device.unload], unload
334
        mov     [device.name], my_service
1237 clevermous 335
 
336
; 4k. Now, it's time to find the base io addres of the PCI device
337
; TODO: implement check if bus and dev exist on this machine
338
 
1519 hidnplayr 339
; Now, it's time to find the base io addres of the PCI device
3205 hidnplayr 340
        PCI_find_io
1237 clevermous 341
 
1519 hidnplayr 342
; We've found the io address, find IRQ now
3205 hidnplayr 343
        PCI_find_irq
1237 clevermous 344
 
345
; 4m. Add new device to the list (required for int_handler).
2387 hidnplayr 346
        mov     eax, [devices]
347
        mov     [device_list+4*eax], ebx
348
        inc     [devices]
1237 clevermous 349
 
350
; 4m. Ok, the eth_device structure is ready, let's probe the device
2387 hidnplayr 351
        call    probe
352
        test    eax, eax
353
        jnz     .destroy
1237 clevermous 354
; 4n. If device was successfully initialized, register it for the kernel.
355
 
2387 hidnplayr 356
        mov     [device.type], NET_TYPE_ETH
357
        call    NetRegDev
1514 hidnplayr 358
 
2387 hidnplayr 359
        cmp     eax, -1
360
        je      .destroy
1237 clevermous 361
 
2387 hidnplayr 362
        ret     4
1237 clevermous 363
 
364
; 5. If the device was already loaded, find the device number and return it in eax
365
 
366
  .find_devicenum:
2387 hidnplayr 367
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
368
                                                                        ; into a device number in edi
369
        mov     eax, edi                                                ; Application wants it in eax instead
370
        ret     4
1237 clevermous 371
 
372
; If an error occured, remove all allocated data and exit (returning -1 in eax)
373
 
374
  .destroy:
2387 hidnplayr 375
        dec     [devices]
376
        ; todo: reset device into virgin state
1237 clevermous 377
 
378
  .err:
2387 hidnplayr 379
        stdcall KernelFree, ebx
1237 clevermous 380
 
381
  .fail:
2387 hidnplayr 382
        xor     eax, eax
383
        ret     4
1237 clevermous 384
 
385
 
386
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
387
;;                                                                        ;;
388
;;        Actual Hardware dependent code starts here                      ;;
389
;;                                                                        ;;
390
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
391
 
392
unload:
2387 hidnplayr 393
        ; TODO: (in this particular order)
394
        ;
395
        ; - Stop the device
396
        ; - Detach int handler
397
        ; - Remove device from local list
398
        ; - call unregister function in kernel
399
        ; - Remove all allocated structures and buffers the card used
1237 clevermous 400
 
2387 hidnplayr 401
        or      eax,-1
1237 clevermous 402
 
403
ret
404
 
261 hidnplayr 405
;***************************************************************************
1519 hidnplayr 406
;
407
; probe
408
;
2910 hidnplayr 409
; checks the card and enables it
1519 hidnplayr 410
;
411
; TODO: probe mii transceivers
412
;
261 hidnplayr 413
;***************************************************************************
1519 hidnplayr 414
align 4
415
probe:
2909 hidnplayr 416
        DEBUGF  1, "Probe\n"
261 hidnplayr 417
 
2910 hidnplayr 418
; wake up device   CHECKME
3205 hidnplayr 419
        stdcall PciWrite8, [device.pci_bus], [device.pci_dev], 0x40, 0
1519 hidnplayr 420
 
3205 hidnplayr 421
        PCI_make_bus_master
1519 hidnplayr 422
 
3205 hidnplayr 423
        PCI_adjust_latency 64
424
 
1519 hidnplayr 425
; Get Card Revision
3205 hidnplayr 426
        stdcall PciRead8, [device.pci_bus], [device.pci_dev], 0x08
2387 hidnplayr 427
        mov     [device.pci_revision], al       ; save the revision for later use
1519 hidnplayr 428
 
429
; Look up through the specific_table
2387 hidnplayr 430
        mov     esi, specific_table
2910 hidnplayr 431
  .tableloop:
2387 hidnplayr 432
        cmp     dword [esi], 0                  ; Check if we reached end of the list
2910 hidnplayr 433
        je      .notsupported
2387 hidnplayr 434
        cmp     al, [esi]                       ; Check if revision is OK
435
        je      .ok
436
        add     esi, 12                         ; Advance to next entry
2910 hidnplayr 437
        jmp     .tableloop
1519 hidnplayr 438
 
439
  .ok:
440
 
3346 hidnplayr 441
        call     dword[esi + 4]                 ; "get MAC" function
1519 hidnplayr 442
 
443
; Set table entries
2387 hidnplayr 444
        mov      [device.table_entries], 16
445
        cmp      [device.pci_revision], SIS635A_900_REV
446
        jae      @f
447
        cmp      [device.pci_revision], SIS900B_900_REV
448
        je       @f
449
        mov      [device.table_entries], 8
1519 hidnplayr 450
       @@:
451
 
452
; TODO: Probe for mii transceiver
453
 
2910 hidnplayr 454
        jmp     reset
1519 hidnplayr 455
 
2910 hidnplayr 456
  .notsupported:
457
        DEBUGF  1, "Device not supported\n"
458
        or      eax, -1
1519 hidnplayr 459
 
2387 hidnplayr 460
        ret
1519 hidnplayr 461
 
462
reset:
2910 hidnplayr 463
 
2909 hidnplayr 464
        DEBUGF  1, "reset\n"
465
 
2387 hidnplayr 466
        movzx   eax, [device.irq_line]
467
        stdcall AttachIntHandler, eax, int_handler, 0
261 hidnplayr 468
 
1519 hidnplayr 469
;--------------------------------------------
470
; Disable Interrupts and reset Receive Filter
471
 
2387 hidnplayr 472
        set_io  0
473
        set_io  ier
474
        xor     eax, eax
475
        out     dx, eax
1519 hidnplayr 476
 
2387 hidnplayr 477
        set_io  imr
478
        out     dx, eax
1519 hidnplayr 479
 
2387 hidnplayr 480
        set_io  rfcr
481
        out     dx, eax
1519 hidnplayr 482
 
483
;-----------
484
; Reset Card
485
 
2387 hidnplayr 486
        set_io  cr
487
        in      eax, dx                         ; Get current Command Register
488
        or      eax, RESET + RxRESET + TxRESET  ; set flags
489
        out     dx, eax                         ; Write new Command Register
1519 hidnplayr 490
 
491
;----------
492
; Wait loop
493
 
2387 hidnplayr 494
        set_io  isr
495
        mov     ecx, 1000
1519 hidnplayr 496
  .loop:
2387 hidnplayr 497
        dec     ecx
2910 hidnplayr 498
        jz      .fail
499
        in      eax, dx                         ; read interrupt status
500
        test    eax, TxRCMP + RxRCMP
2909 hidnplayr 501
        jz      .loop
2910 hidnplayr 502
        DEBUGF  1, "status=%x\n", eax
1519 hidnplayr 503
 
504
;------------------------------------------------------
505
; Set Configuration Register depending on Card Revision
506
 
2387 hidnplayr 507
        set_io  cfg
508
        mov     eax, PESEL                      ; Configuration Register Bit
509
        cmp     [device.pci_revision], SIS635A_900_REV
510
        je      .match
511
        cmp     [device.pci_revision], SIS900B_900_REV ; Check card revision
2910 hidnplayr 512
        jne     .done
2387 hidnplayr 513
  .match:                                       ; Revision match
514
        or      eax, RND_CNT                    ; Configuration Register Bit
2910 hidnplayr 515
  .done:
2387 hidnplayr 516
        out     dx, eax
1519 hidnplayr 517
 
2910 hidnplayr 518
        DEBUGF  1, "Initialising RX Filter\n"
1519 hidnplayr 519
 
520
; Get Receive Filter Control Register
2387 hidnplayr 521
        set_io  rfcr
522
        in      eax, dx
523
        push    eax
1519 hidnplayr 524
 
525
; disable packet filtering before setting filter
2387 hidnplayr 526
        and     eax, not RFEN
527
        out     dx, eax
1519 hidnplayr 528
 
529
; load MAC addr to filter data register
2387 hidnplayr 530
        xor     ecx, ecx
2910 hidnplayr 531
  .macloop:
2387 hidnplayr 532
        mov     eax, ecx
533
        set_io  0
534
        set_io  rfcr
2910 hidnplayr 535
        shl     eax, 16                                             ; high word of eax tells card which mac byte to write
2387 hidnplayr 536
        out     dx, eax                                             ;
537
        set_io  rfdr
2910 hidnplayr 538
        mov     ax, word [device.mac + ecx*2]                       ; Get Mac ID word
2387 hidnplayr 539
        out     dx, ax                                              ; Send Mac ID
540
        inc     cl                                                  ; send next word
541
        cmp     cl, 3                                               ; more to send?
2910 hidnplayr 542
        jne     .macloop
1519 hidnplayr 543
 
544
; enable packet filtering
2910 hidnplayr 545
        pop     eax                     ; old register value
2387 hidnplayr 546
        set_io  rfcr
2910 hidnplayr 547
        or      eax, RFEN               ; enable filtering
548
        out     dx, eax                 ; set register
1519 hidnplayr 549
 
2910 hidnplayr 550
        DEBUGF  1, "Initialising TX Descriptors\n"
1519 hidnplayr 551
 
2910 hidnplayr 552
        mov     ecx, NUM_TX_DESC
553
        lea     esi, [device.txd]
554
  .txdescloop:
555
        lea     eax, [esi + 16]                 ; next ptr
556
        GetRealAddr
557
        mov     dword [esi], eax                ; link to next desc
558
        mov     dword [esi + 4], 0              ; status field
559
        mov     dword [esi + 8], 0              ; ptr to buffer
560
        add     esi, 16
561
        dec     ecx
562
        jnz     .txdescloop
261 hidnplayr 563
 
2387 hidnplayr 564
        lea     eax, [device.txd]
565
        GetRealAddr
2910 hidnplayr 566
        mov     dword [esi - 16], eax           ; correct last descriptor link ptr
1519 hidnplayr 567
 
2910 hidnplayr 568
        set_io  txdp                            ; TX Descriptor Pointer
569
;        lea     eax, [device.txd]
570
;        GetRealAddr
571
        out     dx, eax
1519 hidnplayr 572
 
2910 hidnplayr 573
        mov     [device.cur_tx], 0              ; Set current tx descriptor to 0
2912 hidnplayr 574
        mov     [device.last_tx], 0
261 hidnplayr 575
 
2910 hidnplayr 576
        DEBUGF  1, "Initialising RX Descriptors\n"
577
 
2387 hidnplayr 578
        mov     ecx, NUM_RX_DESC
579
        lea     esi, [device.rxd]
2910 hidnplayr 580
  .rxdescloop:
2909 hidnplayr 581
        lea     eax, [esi + 16]                 ; next ptr
2387 hidnplayr 582
        GetRealAddr
2909 hidnplayr 583
        mov     dword [esi], eax
584
        mov     dword [esi + 4], RX_BUFF_SZ     ; size
1519 hidnplayr 585
 
2910 hidnplayr 586
        push    ecx esi
2387 hidnplayr 587
        stdcall KernelAlloc, RX_BUFF_SZ
2910 hidnplayr 588
        pop     esi ecx
2387 hidnplayr 589
        test    eax, eax
590
        jz      .fail
2909 hidnplayr 591
        mov     dword [esi + 12], eax           ; address
2387 hidnplayr 592
        GetRealAddr
2909 hidnplayr 593
        mov     dword [esi + 8], eax            ; real address
2387 hidnplayr 594
        add     esi, 16
2909 hidnplayr 595
        dec     ecx
2910 hidnplayr 596
        jnz     .rxdescloop
1519 hidnplayr 597
 
2387 hidnplayr 598
        lea     eax, [device.rxd]
599
        GetRealAddr
2909 hidnplayr 600
        mov     dword [esi - 16], eax           ; correct last descriptor link ptr
1519 hidnplayr 601
 
2387 hidnplayr 602
        set_io  0
603
        set_io  rxdp
2910 hidnplayr 604
;        lea     eax, [device.rxd]
605
;        GetRealAddr
2387 hidnplayr 606
        out     dx, eax
1519 hidnplayr 607
 
2910 hidnplayr 608
        mov     [device.cur_rx], 0              ; Set current rx descriptor to 0
1519 hidnplayr 609
 
2910 hidnplayr 610
        DEBUGF  1, "setting RX mode\n"
1519 hidnplayr 611
 
2910 hidnplayr 612
        xor     cl, cl
613
  .rxfilterloop:
2387 hidnplayr 614
        set_io  0
2910 hidnplayr 615
        set_io  rfcr                    ; Receive Filter Control Reg offset
616
        mov     eax, 4                  ; determine table entry
617
        add     al, cl
618
        shl     eax, 16
619
        out     dx, eax                 ; tell card which entry to modify
1519 hidnplayr 620
 
2910 hidnplayr 621
        set_io  rfdr                    ; Receive Filter Control Reg offset
622
        mov     eax, 0xffff             ; entry value
623
        out     dx, ax                  ; write value to table in card
1519 hidnplayr 624
 
2910 hidnplayr 625
        inc     cl                      ; next entry
626
        cmp     cl, [device.table_entries]
627
        jb      .rxfilterloop
1519 hidnplayr 628
 
2910 hidnplayr 629
        set_io  rfcr                    ; Receive Filter Control Register offset
630
        mov     eax, RFAAB + RFAAM + RFAAP + RFEN
631
        out     dx, eax
261 hidnplayr 632
 
2910 hidnplayr 633
        set_io  rxcfg                   ; Receive Config Register offset
634
        mov     eax, ATX + RX_DMA + 2   ; 0x2 : RX Drain Threshold = 8*8=64 bytes
635
        out     dx, eax
1519 hidnplayr 636
 
2910 hidnplayr 637
        DEBUGF  1, "setting TX mode\n"
1519 hidnplayr 638
 
2910 hidnplayr 639
        set_io  txcfg                   ; Transmit config Register offset
640
        mov     eax, ATP + HBI + CSI + TX_DMA + 0x120
641
                                        ; TX Fill threshold = 0x100
642
                                        ; TX Drain Threshold = 0x20
643
        out     dx, eax
1519 hidnplayr 644
 
2910 hidnplayr 645
        DEBUGF  1, "Enabling interrupts\n"
1519 hidnplayr 646
 
2910 hidnplayr 647
        set_io  imr
648
        mov     eax, IE                 ; Interrupt enable mask
2387 hidnplayr 649
        out     dx, eax
1519 hidnplayr 650
 
2387 hidnplayr 651
        set_io  cr
2910 hidnplayr 652
        in      eax, dx
2387 hidnplayr 653
        or      eax, RxENA              ; Enable Receive
654
        out     dx, eax
1519 hidnplayr 655
 
2910 hidnplayr 656
        set_io  ier                     ; Interrupt enable
657
        mov     eax, 1
2909 hidnplayr 658
        out     dx, eax
1519 hidnplayr 659
 
2910 hidnplayr 660
        mov     [device.mtu], 1514
3346 hidnplayr 661
 
662
; Set link state to unknown
663
        mov     [device.state], ETH_LINK_UNKOWN
664
 
2910 hidnplayr 665
        xor     eax, eax
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"
2981 hidnplayr 1115
        jmp     Eth_input
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