Subversion Repositories Kolibri OS

Rev

Rev 5363 | Details | Compare with Previous | Last modification | View Log | RSS feed

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