Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                    ;;
4467 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2014. 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
3545 hidnplayr 417
 
418
ret
419
 
420
;***************************************************************************
421
;
422
; probe
423
;
424
; checks the card and enables it
425
;
426
; TODO: probe mii transceivers
427
;
428
;***************************************************************************
429
align 4
430
probe:
431
        DEBUGF  1, "Probe\n"
432
 
5006 hidnplayr 433
; wake up device
434
; TODO: check capabilities pointer instead of using hardcoded offset.
435
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, 0
3545 hidnplayr 436
 
5006 hidnplayr 437
; Make the device a bus master
438
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
439
        or      al, PCI_CMD_MASTER
440
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 441
 
5006 hidnplayr 442
; Adjust PCI latency to be at least 64
443
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
444
        cmp     al, 64
445
        jae     @f
446
        mov     al, 64
447
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
448
  @@:
3545 hidnplayr 449
 
450
; Get Card Revision
5006 hidnplayr 451
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x08
452
        mov     [ebx + device.pci_revision], al         ; save the revision for later use
3545 hidnplayr 453
 
454
; Look up through the specific_table
455
        mov     esi, specific_table
456
  .tableloop:
5006 hidnplayr 457
        cmp     dword[esi], 0                           ; Check if we reached end of the list
3545 hidnplayr 458
        je      .notsupported
5006 hidnplayr 459
        cmp     al, [esi]                               ; Check if revision is OK
3545 hidnplayr 460
        je      .ok
5006 hidnplayr 461
        add     esi, 12                                 ; Advance to next entry
3545 hidnplayr 462
        jmp     .tableloop
463
  .ok:
5006 hidnplayr 464
        call     dword[esi + 4]                         ; "get MAC" function
3545 hidnplayr 465
 
466
; Set table entries
5006 hidnplayr 467
        mov      [ebx + device.table_entries], 16
468
        cmp      [ebx + device.pci_revision], SIS635A_900_REV
3545 hidnplayr 469
        jae      @f
5006 hidnplayr 470
        cmp      [ebx + device.pci_revision], SIS900B_900_REV
3545 hidnplayr 471
        je       @f
5006 hidnplayr 472
        mov      [ebx + device.table_entries], 8
3545 hidnplayr 473
       @@:
474
 
475
; TODO: Probe for mii transceiver
476
        jmp     reset
477
 
478
  .notsupported:
5006 hidnplayr 479
        DEBUGF  2, "Device not supported\n"
3545 hidnplayr 480
        or      eax, -1
481
 
482
        ret
483
 
484
reset:
485
 
486
        DEBUGF  1, "reset\n"
487
 
5006 hidnplayr 488
        movzx   eax, [ebx + device.irq_line]
489
        invoke  AttachIntHandler, eax, int_handler, ebx
490
        test    eax, eax
491
        jnz     @f
492
        DEBUGF  2,"Could not attach int handler!\n"
493
        or      eax, -1
494
        ret
495
       @@:
3545 hidnplayr 496
 
497
;--------------------------------------------
498
; Disable Interrupts and reset Receive Filter
499
 
5006 hidnplayr 500
        set_io  [ebx + device.io_addr], 0
501
        set_io  [ebx + device.io_addr], ier
3545 hidnplayr 502
        xor     eax, eax
503
        out     dx, eax
504
 
5006 hidnplayr 505
        set_io  [ebx + device.io_addr], imr
3545 hidnplayr 506
        out     dx, eax
507
 
5006 hidnplayr 508
        set_io  [ebx + device.io_addr], rfcr
3545 hidnplayr 509
        out     dx, eax
510
 
511
;-----------
512
; Reset Card
513
 
5006 hidnplayr 514
        set_io  [ebx + device.io_addr], cr
515
        in      eax, dx                                 ; Get current Command Register
516
        or      eax, RESET + RxRESET + TxRESET          ; set flags
517
        out     dx, eax                                 ; Write new Command Register
3545 hidnplayr 518
 
519
;----------
520
; Wait loop
521
 
5006 hidnplayr 522
        set_io  [ebx + device.io_addr], isr
3545 hidnplayr 523
        mov     ecx, 1000
524
  .loop:
525
        dec     ecx
526
        jz      .fail
5006 hidnplayr 527
        in      eax, dx                                 ; read interrupt status
3545 hidnplayr 528
        test    eax, TxRCMP + RxRCMP
529
        jz      .loop
530
        DEBUGF  1, "status=%x\n", eax
531
 
532
;------------------------------------------------------
533
; Set Configuration Register depending on Card Revision
534
 
5006 hidnplayr 535
        set_io  [ebx + device.io_addr], cfg
536
        mov     eax, PESEL                              ; Configuration Register Bit
537
        cmp     [ebx + device.pci_revision], SIS635A_900_REV
3545 hidnplayr 538
        je      .match
5006 hidnplayr 539
        cmp     [ebx + device.pci_revision], SIS900B_900_REV ; Check card revision
3545 hidnplayr 540
        jne     .done
5006 hidnplayr 541
  .match:                                               ; Revision match
542
        or      eax, RND_CNT                            ; Configuration Register Bit
3545 hidnplayr 543
  .done:
544
        out     dx, eax
545
 
546
        DEBUGF  1, "Initialising RX Filter\n"
547
 
548
; Get Receive Filter Control Register
5006 hidnplayr 549
        set_io  [ebx + device.io_addr], rfcr
3545 hidnplayr 550
        in      eax, dx
551
        push    eax
552
 
553
; disable packet filtering before setting filter
554
        and     eax, not RFEN
555
        out     dx, eax
556
 
557
; load MAC addr to filter data register
558
        xor     ecx, ecx
559
  .macloop:
560
        mov     eax, ecx
5006 hidnplayr 561
        set_io  [ebx + device.io_addr], 0
562
        set_io  [ebx + device.io_addr], rfcr
563
        shl     eax, 16                                 ; high word of eax tells card which mac byte to write
564
        out     dx, eax                                 ;
565
        set_io  [ebx + device.io_addr], rfdr
566
        mov     ax, word [ebx + device.mac + ecx*2]     ; Get Mac ID word
567
        out     dx, ax                                  ; Send Mac ID
568
        inc     cl                                      ; send next word
569
        cmp     cl, 3                                   ; more to send?
3545 hidnplayr 570
        jne     .macloop
571
 
572
; enable packet filtering
5006 hidnplayr 573
        pop     eax                                     ; old register value
574
        set_io  [ebx + device.io_addr], rfcr
575
        or      eax, RFEN                               ; enable filtering
576
        out     dx, eax                                 ; set register
3545 hidnplayr 577
 
578
        DEBUGF  1, "Initialising TX Descriptors\n"
579
 
580
        mov     ecx, NUM_TX_DESC
5006 hidnplayr 581
        lea     esi, [ebx + device.txd]
3545 hidnplayr 582
  .txdescloop:
5006 hidnplayr 583
        lea     eax, [esi + 16]                         ; next ptr
584
        invoke  GetPhysAddr
585
        mov     dword[esi], eax                         ; link to next desc
586
        mov     dword[esi + 4], 0                       ; status field
587
        mov     dword[esi + 8], 0                       ; ptr to buffer
3545 hidnplayr 588
        add     esi, 16
589
        dec     ecx
590
        jnz     .txdescloop
591
 
5006 hidnplayr 592
        lea     eax, [ebx + device.txd]
593
        invoke  GetPhysAddr
594
        mov     dword[esi - 16], eax                    ; correct last descriptor link ptr
3545 hidnplayr 595
 
5006 hidnplayr 596
        set_io  [ebx + device.io_addr], txdp            ; TX Descriptor Pointer
597
;        lea     eax, [ebx + device.txd]
598
;        invoke  GetPhysAddr
3545 hidnplayr 599
        out     dx, eax
600
 
5006 hidnplayr 601
        mov     [ebx + device.cur_tx], 0                ; Set current tx descriptor to 0
602
        mov     [ebx + device.last_tx], 0
3545 hidnplayr 603
 
604
        DEBUGF  1, "Initialising RX Descriptors\n"
605
 
606
        mov     ecx, NUM_RX_DESC
5006 hidnplayr 607
        lea     esi, [ebx + device.rxd]
3545 hidnplayr 608
  .rxdescloop:
5006 hidnplayr 609
        lea     eax, [esi + 16]                         ; next ptr
610
        invoke  GetPhysAddr
3545 hidnplayr 611
        mov     dword [esi], eax
5006 hidnplayr 612
        mov     dword [esi + 4], RX_BUFF_SZ             ; size
3545 hidnplayr 613
 
614
        push    ecx esi
5006 hidnplayr 615
        invoke  KernelAlloc, RX_BUFF_SZ
3545 hidnplayr 616
        pop     esi ecx
617
        test    eax, eax
618
        jz      .fail
5006 hidnplayr 619
        mov     dword [esi + 12], eax                   ; address
620
        invoke  GetPhysAddr
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
 
1009
proc transmit stdcall bufferptr, buffersize
1010
 
1011
        pushf
1012
        cli
1013
 
1014
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1015
        mov     eax, [bufferptr]
3545 hidnplayr 1016
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1017
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1018
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1019
        [eax+13]:2,[eax+12]:2
1020
 
5006 hidnplayr 1021
        cmp     [buffersize], 1514
1022
        ja      .fail
1023
        cmp     [buffersize], 60
1024
        jb      .fail
3545 hidnplayr 1025
 
5006 hidnplayr 1026
        movzx   ecx, [ebx + device.cur_tx]
1027
        shl     ecx, 4                                  ; *16
1028
        lea     ecx, [ebx + device.txd + ecx]
3545 hidnplayr 1029
 
5006 hidnplayr 1030
        test    dword[ecx + 4], 0x80000000              ; card owns descriptor ?
1031
        jnz     .fail
3545 hidnplayr 1032
 
5006 hidnplayr 1033
        mov     eax, [bufferptr]
1034
        mov     dword[ecx + 12], eax
1035
        invoke  GetPhysAddr
1036
        mov     dword[ecx + 8], eax                     ; buffer address
3545 hidnplayr 1037
 
5006 hidnplayr 1038
        mov     eax, [buffersize]
3545 hidnplayr 1039
        and     eax, DSIZE
5006 hidnplayr 1040
        or      eax, 0x80000000                         ; card owns descriptor
1041
        mov     dword[ecx + 4], eax                     ; status field
3545 hidnplayr 1042
 
5006 hidnplayr 1043
        set_io  [ebx + device.io_addr], 0
1044
        set_io  [ebx + device.io_addr], cr
3545 hidnplayr 1045
        in      eax, dx
5006 hidnplayr 1046
        or      eax, TxENA                              ; Enable the transmit state machine
3545 hidnplayr 1047
        out     dx, eax
1048
 
5006 hidnplayr 1049
        inc     [ebx + device.cur_tx]
1050
        and     [ebx + device.cur_tx], NUM_TX_DESC-1
3545 hidnplayr 1051
 
1052
; update stats
5006 hidnplayr 1053
        mov     ecx, [buffersize]
1054
        inc     [ebx + device.packets_tx]
1055
        add     dword [ebx + device.bytes_tx], ecx
1056
        adc     dword [ebx + device.bytes_tx + 4], 0
3545 hidnplayr 1057
 
5006 hidnplayr 1058
        DEBUGF  1,"Transmit OK\n"
1059
        popf
3545 hidnplayr 1060
        xor     eax, eax
5006 hidnplayr 1061
        ret
3545 hidnplayr 1062
 
5006 hidnplayr 1063
  .fail:
1064
        DEBUGF  2,"Transmit failed\n"
1065
        invoke  KernelFree, [bufferptr]
1066
        popf
3545 hidnplayr 1067
        or      eax, -1
5006 hidnplayr 1068
        ret
3545 hidnplayr 1069
 
5006 hidnplayr 1070
endp
3545 hidnplayr 1071
 
5006 hidnplayr 1072
 
3545 hidnplayr 1073
;***************************************************************************
1074
;
1075
; int_handler
1076
;
1077
; handles received IRQs, which signal received packets
1078
;
1079
; Currently only supports one descriptor per packet, if packet is fragmented
1080
; between multiple descriptors you will lose part of the packet
1081
;
1082
;***************************************************************************
1083
 
1084
align 4
1085
int_handler:
1086
 
1087
        push    ebx esi edi
1088
 
5006 hidnplayr 1089
        DEBUGF  1,"INT\n"
3545 hidnplayr 1090
 
1091
; find pointer of device which made IRQ occur
1092
 
1093
        mov     ecx, [devices]
1094
        test    ecx, ecx
1095
        jz      .nothing
1096
        mov     esi, device_list
1097
  .nextdevice:
1098
        mov     ebx, [esi]
1099
 
5006 hidnplayr 1100
        set_io  [ebx + device.io_addr], 0
1101
        set_io  [ebx + device.io_addr], isr
1102
        in      eax, dx                                 ; note that this clears all interrupts
3545 hidnplayr 1103
        test    ax, IE
1104
        jnz     .got_it
1105
  .continue:
1106
        add     esi, 4
1107
        dec     ecx
1108
        jnz     .nextdevice
1109
  .nothing:
1110
        pop     edi esi ebx
1111
        xor     eax, eax
1112
 
1113
        ret
1114
 
1115
  .got_it:
1116
 
5006 hidnplayr 1117
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
3545 hidnplayr 1118
 
1119
        test    ax, RxOK
1120
        jz      .no_rx_
1121
 
1122
        push    ax
1123
 
1124
  .rx_loop:
1125
 
1126
;-----------
1127
; Get Status
5006 hidnplayr 1128
        movzx   eax, [ebx + device.cur_rx]              ; find current descriptor
3545 hidnplayr 1129
        shl     eax, 4                                  ; * 16
5006 hidnplayr 1130
        mov     ecx, dword[ebx + device.rxd + eax + 4]  ; get receive status
3545 hidnplayr 1131
 
1132
;-------------------------------------------
1133
; Check RX_Status to see if packet is waiting
1134
        test    ecx, 0x80000000
1135
        jz      .no_rx
1136
 
1137
;----------------------------------------------
1138
; There is a packet waiting check it for errors
5006 hidnplayr 1139
        test    ecx, 0x67C0000                          ; see if there are any errors
3545 hidnplayr 1140
        jnz     .error_status
1141
 
1142
;---------------------
1143
; Check size of packet
5006 hidnplayr 1144
        and     ecx, DSIZE                              ; get packet size minus CRC
1145
        sub     ecx, CRC_SIZE                           ; make sure packet contains data
3545 hidnplayr 1146
        jbe     .error_size
1147
 
1148
; update statistics
5006 hidnplayr 1149
        inc     dword [ebx + device.packets_rx]
1150
        add     dword [ebx + device.bytes_rx], ecx
1151
        adc     dword [ebx + device.bytes_rx + 4], 0
3545 hidnplayr 1152
 
1153
        push    ebx
1154
        push    .return
5006 hidnplayr 1155
        push    ecx                                     ; packet size
1156
        pushd   [ebx + device.rxd + eax + 12]           ; packet ptr
3545 hidnplayr 1157
        DEBUGF  1, "Packet received OK\n"
5006 hidnplayr 1158
        jmp     [Eth_input]
3545 hidnplayr 1159
  .return:
1160
        pop     ebx
1161
 
1162
; Reset status, allow ethernet card access to descriptor
5006 hidnplayr 1163
        invoke  KernelAlloc, RX_BUFF_SZ
3545 hidnplayr 1164
        test    eax, eax
1165
        jz      .fail
5006 hidnplayr 1166
        movzx   ecx, [ebx + device.cur_rx]
1167
        shl     ecx, 4                                  ; *16
1168
        lea     ecx, [ebx + device.rxd + ecx]
3545 hidnplayr 1169
        mov     dword [ecx + 12], eax
5006 hidnplayr 1170
        invoke  GetPhysAddr
3545 hidnplayr 1171
        mov     dword [ecx + 8], eax
1172
        mov     dword [ecx + 4], RX_BUFF_SZ
1173
 
5006 hidnplayr 1174
        inc     [ebx + device.cur_rx]                   ; get next descriptor
1175
        and     [ebx + device.cur_rx], NUM_RX_DESC-1    ; only 4 descriptors 0-3
3545 hidnplayr 1176
 
1177
        jmp     .rx_loop
1178
 
1179
  .no_rx:
5006 hidnplayr 1180
        set_io  [ebx + device.io_addr], 0
1181
        set_io  [ebx + device.io_addr], cr
3545 hidnplayr 1182
        in      eax, dx
1183
        or      eax, RxENA                              ; Re-Enable the Receive state machine
1184
        out     dx, eax
1185
 
1186
        pop     ax
1187
 
1188
  .no_rx_:
1189
        test    ax, TxOK
1190
        jz      .no_tx
1191
 
1192
        DEBUGF  1, "TX ok!\n"
1193
 
1194
  .tx_loop:
5006 hidnplayr 1195
        movzx   ecx, [ebx + device.last_tx]
3545 hidnplayr 1196
        shl     ecx, 4                  ; *16
5006 hidnplayr 1197
        lea     ecx, [ebx + device.txd + ecx]
3545 hidnplayr 1198
 
5006 hidnplayr 1199
        test    dword[ecx + 4], 0x80000000              ; card owns descr
3545 hidnplayr 1200
        jnz     .no_tx
5006 hidnplayr 1201
        cmp     dword[ecx + 12], 0
3545 hidnplayr 1202
        je      .no_tx
1203
 
1204
        DEBUGF  1, "Freeing packet = %x\n", [ecx + 12]:8
5006 hidnplayr 1205
        push    dword[ecx + 12]
1206
        mov     dword[ecx + 12], 0
1207
        invoke  KernelFree
3545 hidnplayr 1208
 
5006 hidnplayr 1209
        inc     [ebx + device.last_tx]
1210
        and     [ebx + device.last_tx], NUM_TX_DESC-1
3545 hidnplayr 1211
        jmp     .tx_loop
1212
 
1213
  .no_tx:
1214
  .fail:
1215
        pop     edi esi ebx
1216
        xor     eax, eax
1217
        inc     eax
1218
 
1219
        ret
1220
 
1221
        ret
1222
 
1223
  .error_status:
5006 hidnplayr 1224
        DEBUGF  2, "Packet error: %x\n", ecx
3545 hidnplayr 1225
        jmp     .fail
1226
 
1227
  .error_size:
5006 hidnplayr 1228
        DEBUGF  2, "Packet too large/small\n"
3545 hidnplayr 1229
        jmp     .fail
1230
 
1231
 
1232
 
1233
 
1234
 
1235
; End of code
1236
 
5006 hidnplayr 1237
data fixups
1238
end data
3545 hidnplayr 1239
 
5006 hidnplayr 1240
include '../peimport.inc'
3545 hidnplayr 1241
 
5006 hidnplayr 1242
my_service      db 'SIS900',0                           ; max 16 chars include zero
1243
 
3545 hidnplayr 1244
specific_table:
1245
;    dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0
1246
;    dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0
1247
    dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0
1248
    dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0
5006 hidnplayr 1249
    dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0      ; SIS630ET_900_REV_SpecialFN
3545 hidnplayr 1250
    dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0
1251
    dd SIS900_960_REV, SIS960_get_mac_addr, 0
1252
    dd SIS900B_900_REV, SIS900_get_mac_addr, 0
5006 hidnplayr 1253
    dd 0                                                ; end of list
3545 hidnplayr 1254
 
5006 hidnplayr 1255
include_debug_strings                                   ; All data wich FDO uses will be included here
3545 hidnplayr 1256
 
5006 hidnplayr 1257
align 4
1258
devices         dd 0
1259
device_list     rd MAX_DEVICES                          ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1260