Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
6227 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  Realtek 8139 driver for KolibriOS                              ;;
7
;;                                                                 ;;
8
;;  based on RTL8139.asm driver for menuetos                       ;;
9
;;  and realtek8139.asm for SolarOS by Eugen Brasoveanu            ;;
10
;;                                                                 ;;
11
;;    Written by hidnplayr@kolibrios.org                           ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
5045 hidnplayr 18
format PE DLL native
19
entry START
3545 hidnplayr 20
 
5045 hidnplayr 21
        CURRENT_API             = 0x0200
22
        COMPATIBLE_API          = 0x0100
23
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 24
 
25
        MAX_DEVICES             = 16
26
 
5045 hidnplayr 27
        RBLEN                   = 3     ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
3545 hidnplayr 28
 
5045 hidnplayr 29
        TXRR                    = 8     ; total retries = 16+(TXRR*16)
30
        TX_MXDMA                = 6     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048
31
        ERTXTH                  = 8     ; in unit of 32 bytes e.g:(8*32)=256
32
        RX_MXDMA                = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited
33
        RXFTH                   = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold
3857 hidnplayr 34
 
3545 hidnplayr 35
        __DEBUG__               = 1
5045 hidnplayr 36
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
3545 hidnplayr 37
 
5045 hidnplayr 38
section '.flat' readable writable executable
39
 
40
include '../proc32.inc'
4467 hidnplayr 41
include '../struct.inc'
42
include '../macros.inc'
3545 hidnplayr 43
include '../fdo.inc'
5074 hidnplayr 44
include '../netdrv.inc'
3545 hidnplayr 45
 
46
        REG_IDR0                = 0x00
47
        REG_MAR0                = 0x08 ; multicast filter register 0
48
        REG_MAR4                = 0x0c ; multicast filter register 4
49
        REG_TSD0                = 0x10 ; transmit status of descriptor
50
        REG_TSAD0               = 0x20 ; transmit start address of descriptor
51
        REG_RBSTART             = 0x30 ; RxBuffer start address
52
        REG_COMMAND             = 0x37 ; command register
53
        REG_CAPR                = 0x38 ; current address of packet read (word) R/W
54
        REG_IMR                 = 0x3c ; interrupt mask register
55
        REG_ISR                 = 0x3e ; interrupt status register
56
        REG_TXCONFIG            = 0x40 ; transmit configuration register
57
        REG_RXCONFIG            = 0x44 ; receive configuration register 0
58
        REG_MPC                 = 0x4c ; missed packet counter
59
        REG_9346CR              = 0x50 ; serial eeprom 93C46 command register
60
        REG_CONFIG1             = 0x52 ; configuration register 1
6227 hidnplayr 61
        REG_MSR                 = 0x58 ; Media Status register
3545 hidnplayr 62
        REG_CONFIG4             = 0x5a ; configuration register 4
63
        REG_HLTCLK              = 0x5b ; undocumented halt clock register
64
        REG_BMCR                = 0x62 ; basic mode control register
65
        REG_ANAR                = 0x66 ; auto negotiation advertisement register
66
        REG_9346CR_WE           = 11b shl 6
67
 
68
        BIT_RUNT                = 4 ; total packet length < 64 bytes
69
        BIT_LONG                = 3 ; total packet length > 4k
70
        BIT_CRC                 = 2 ; crc error occured
71
        BIT_FAE                 = 1 ; frame alignment error occured
72
        BIT_ROK                 = 0 ; received packet is ok
73
 
74
        BIT_RST                 = 4 ; reset bit
75
        BIT_RE                  = 3 ; receiver enabled
76
        BIT_TE                  = 2 ; transmitter enabled
77
        BUFE                    = 1 ; rx buffer is empty, no packet stored
78
 
79
        BIT_ISR_TOK             = 2 ; transmit ok
80
        BIT_ISR_RER             = 1 ; receive error interrupt
81
        BIT_ISR_ROK             = 0 ; receive ok
82
 
83
        BIT_TX_MXDMA            = 8 ; Max DMA burst size per Tx DMA burst
84
        BIT_TXRR                = 4 ; Tx Retry count 16+(TXRR*16)
85
 
86
        BIT_RXFTH               = 13 ; Rx fifo threshold
87
        BIT_RBLEN               = 11 ; Ring buffer length indicator
88
        BIT_RX_MXDMA            = 8 ; Max DMA burst size per Rx DMA burst
89
        BIT_NOWRAP              = 7 ; transfered data wrapping
90
        BIT_9356SEL             = 6 ; eeprom selector 9346/9356
91
        BIT_AER                 = 5 ; accept error packets
92
        BIT_AR                  = 4 ; accept runt packets
93
        BIT_AB                  = 3 ; accept broadcast packets
94
        BIT_AM                  = 2 ; accept multicast packets
95
        BIT_APM                 = 1 ; accept physical match packets
96
        BIT_AAP                 = 0 ; accept all packets
97
 
98
        BIT_93C46_EEM1          = 7 ; RTL8139 eeprom operating mode1
99
        BIT_93C46_EEM0          = 6 ; RTL8139 eeprom operating mode0
100
        BIT_93C46_EECS          = 3 ; chip select
101
        BIT_93C46_EESK          = 2 ; serial data clock
102
        BIT_93C46_EEDI          = 1 ; serial data input
103
        BIT_93C46_EEDO          = 0 ; serial data output
104
 
105
        BIT_LWACT               = 4 ; see REG_CONFIG1
106
        BIT_SLEEP               = 1 ; sleep bit at older chips
107
        BIT_PWRDWN              = 0 ; power down bit at older chips
108
        BIT_PMEn                = 0 ; power management enabled
109
 
110
        BIT_LWPTN               = 2 ; see REG_CONFIG4
111
 
112
        BIT_ERTXTH              = 16 ; early TX threshold
113
        BIT_TOK                 = 15 ; transmit ok
114
        BIT_OWN                 = 13 ; tx DMA operation is completed
115
 
116
        BIT_ANE                 = 12 ; auto negotiation enable
117
 
118
        BIT_TXFD                = 8 ; 100base-T full duplex
119
        BIT_TX                  = 7 ; 100base-T
120
        BIT_10FD                = 6 ; 10base-T full duplex
121
        BIT_10                  = 5 ; 10base-T
122
        BIT_SELECTOR            = 0 ; binary encoded selector CSMA/CD=00001
123
 
6229 hidnplayr 124
        BIT_IFG1                = 1 shl 25
125
        BIT_IFG0                = 1 shl 24
3545 hidnplayr 126
 
127
        RX_CONFIG               = (RBLEN shl BIT_RBLEN) or \
128
                                  (RX_MXDMA shl BIT_RX_MXDMA) or \
129
                                  (1 shl BIT_NOWRAP) or \
130
                                  (RXFTH shl BIT_RXFTH) or\
3857 hidnplayr 131
                                  (1 shl BIT_AB) or \                   ; Accept broadcast packets
132
                                  (1 shl BIT_APM) or \                  ; Accept physical match packets
133
                                  (1 shl BIT_AER) or \                  ; Accept error packets
134
                                  (1 shl BIT_AR) or \                   ; Accept Runt packets (smaller then 64 bytes)
135
                                  (1 shl BIT_AM)                        ; Accept multicast packets
3545 hidnplayr 136
 
3857 hidnplayr 137
        RX_BUFFER_SIZE          = (8192 shl RBLEN);+16+1500
138
        NUM_TX_DESC             = 4                                     ; not user selectable
3545 hidnplayr 139
 
140
        EE_93C46_REG_ETH_ID     = 7 ; MAC offset
141
        EE_93C46_READ_CMD       = (6 shl 6) ; 110b + 6bit address
142
        EE_93C56_READ_CMD       = (6 shl 8) ; 110b + 8bit address
143
        EE_93C46_CMD_LENGTH     = 9  ; start bit + cmd + 6bit address
144
        EE_93C56_CMD_LENGTH     = 11 ; start bit + cmd + 8bit ddress
145
 
6227 hidnplayr 146
; See chapter "5.7 Transmit Configuration Register" of RTL8139D(L).pdf
3545 hidnplayr 147
        VER_RTL8139             = 1100000b
148
        VER_RTL8139A            = 1110000b
149
        VER_RTL8139AG           = 1110100b
150
        VER_RTL8139B            = 1111000b
151
        VER_RTL8130             = VER_RTL8139B
152
        VER_RTL8139C            = 1110100b
153
        VER_RTL8100             = 1111010b
154
        VER_RTL8100B            = 1110101b
155
        VER_RTL8139D            = VER_RTL8100B
156
        VER_RTL8139CP           = 1110110b
157
        VER_RTL8101             = 1110111b
158
 
159
        IDX_RTL8139             = 0
160
        IDX_RTL8139A            = 1
161
        IDX_RTL8139B            = 2
162
        IDX_RTL8139C            = 3
163
        IDX_RTL8100             = 4
164
        IDX_RTL8139D            = 5
165
        IDX_RTL8139D            = 6
166
        IDX_RTL8101             = 7
167
 
168
        ISR_SERR                = 1 shl 15
169
        ISR_TIMEOUT             = 1 shl 14
170
        ISR_LENCHG              = 1 shl 13
171
        ISR_FIFOOVW             = 1 shl 6
172
        ISR_PUN                 = 1 shl 5
173
        ISR_RXOVW               = 1 shl 4
174
        ISR_TER                 = 1 shl 3
175
        ISR_TOK                 = 1 shl 2
176
        ISR_RER                 = 1 shl 1
177
        ISR_ROK                 = 1 shl 0
178
 
179
        INTERRUPT_MASK          = ISR_ROK or \
3857 hidnplayr 180
                                  ISR_RER or \
181
                                  ISR_TOK or \
182
                                  ISR_TER or \
3545 hidnplayr 183
                                  ISR_RXOVW or \
184
                                  ISR_PUN or \
185
                                  ISR_FIFOOVW or \
186
                                  ISR_LENCHG or \
3857 hidnplayr 187
                                  ISR_TIMEOUT or \
188
                                  ISR_SERR
3545 hidnplayr 189
 
190
        TSR_OWN                 = 1 shl 13
191
        TSR_TUN                 = 1 shl 14
192
        TSR_TOK                 = 1 shl 15
193
 
194
        TSR_CDH                 = 1 shl 28
195
        TSR_OWC                 = 1 shl 29
196
        TSR_TABT                = 1 shl 30
197
        TSR_CRS                 = 1 shl 31
198
 
199
 
5045 hidnplayr 200
struct  device          ETH_DEVICE
3545 hidnplayr 201
 
5045 hidnplayr 202
        io_addr         dd ?
203
        pci_bus         dd ?
204
        pci_dev         dd ?
205
        irq_line        db ?
206
                        rb 3    ; align 4
3545 hidnplayr 207
 
5045 hidnplayr 208
        rx_buffer       dd ?
209
        rx_data_offset  dd ?
210
        curr_tx_desc    db ?
211
        hw_ver_id       db ?
212
                        rb 2    ; align 4
3545 hidnplayr 213
 
5045 hidnplayr 214
        TX_DESC         rd NUM_TX_DESC
3545 hidnplayr 215
 
5045 hidnplayr 216
ends
3545 hidnplayr 217
 
218
 
219
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
220
;;                        ;;
221
;; proc START             ;;
222
;;                        ;;
223
;; (standard driver proc) ;;
224
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
225
 
5045 hidnplayr 226
proc START c, reason:dword, cmdline:dword
3545 hidnplayr 227
 
5045 hidnplayr 228
        cmp     [reason], DRV_ENTRY
229
        jne     .fail
3545 hidnplayr 230
 
5045 hidnplayr 231
        DEBUGF  2,"Loading driver\n"
232
        invoke  RegService, my_service, service_proc
3545 hidnplayr 233
        ret
234
 
235
  .fail:
236
        xor     eax, eax
237
        ret
238
 
239
endp
240
 
241
 
242
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
243
;;                        ;;
244
;; proc SERVICE_PROC      ;;
245
;;                        ;;
246
;; (standard driver proc) ;;
247
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
248
 
249
proc service_proc stdcall, ioctl:dword
250
 
251
        mov     edx, [ioctl]
4470 hidnplayr 252
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 253
 
254
;------------------------------------------------------
255
 
256
        cmp     eax, 0 ;SRV_GETVERSION
257
        jne     @F
258
 
4470 hidnplayr 259
        cmp     [edx + IOCTL.out_size], 4
3545 hidnplayr 260
        jb      .fail
4470 hidnplayr 261
        mov     eax, [edx + IOCTL.output]
3545 hidnplayr 262
        mov     [eax], dword API_VERSION
263
 
264
        xor     eax, eax
265
        ret
266
 
267
;------------------------------------------------------
268
  @@:
269
        cmp     eax, 1 ;SRV_HOOK
270
        jne     .fail
271
 
4470 hidnplayr 272
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
3545 hidnplayr 273
        jb      .fail
274
 
4470 hidnplayr 275
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 276
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
277
        jne     .fail                                   ; other types arent supported for this card yet
278
 
279
; check if the device is already listed
280
 
281
        mov     esi, device_list
282
        mov     ecx, [devices]
283
        test    ecx, ecx
284
        jz      .firstdevice
285
 
286
        mov     ax, [eax+1]                             ; get the pci bus and device numbers
287
  .nextdevice:
288
        mov     ebx, [esi]
5045 hidnplayr 289
        cmp     al, byte[ebx + device.pci_bus]
3545 hidnplayr 290
        jne     @f
5045 hidnplayr 291
        cmp     ah, byte[ebx + device.pci_dev]
3545 hidnplayr 292
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
293
       @@:
294
        add     esi, 4
295
        loop    .nextdevice
296
 
297
 
298
; This device doesnt have its own eth_device structure yet, lets create one
299
  .firstdevice:
300
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
301
        jae     .fail
302
 
5045 hidnplayr 303
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
3545 hidnplayr 304
 
305
; Fill in the direct call addresses into the struct
306
 
5045 hidnplayr 307
        mov     [ebx + device.reset], reset
308
        mov     [ebx + device.transmit], transmit
309
        mov     [ebx + device.unload], unload
310
        mov     [ebx + device.name], my_service
3545 hidnplayr 311
 
312
; save the pci bus and device numbers
313
 
4470 hidnplayr 314
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 315
        movzx   ecx, byte[eax+1]
5045 hidnplayr 316
        mov     [ebx + device.pci_bus], ecx
3545 hidnplayr 317
        movzx   ecx, byte[eax+2]
5045 hidnplayr 318
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 319
 
320
; Now, it's time to find the base io addres of the PCI device
321
 
5045 hidnplayr 322
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
323
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 324
 
325
; We've found the io address, find IRQ now
326
 
5045 hidnplayr 327
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
328
        mov     [ebx + device.irq_line], al
3545 hidnplayr 329
 
3856 hidnplayr 330
        DEBUGF  1, "Hooking into device, dev:%x, bus:%x, irq:%x, I/O addr:%x\n",\
5045 hidnplayr 331
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
3545 hidnplayr 332
 
333
; Allocate the receive buffer
334
 
5045 hidnplayr 335
        invoke  CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW
3545 hidnplayr 336
        test    eax, eax
337
        jz      .err
5045 hidnplayr 338
        mov     [ebx + device.rx_buffer], eax
3545 hidnplayr 339
 
340
; Ok, the eth_device structure is ready, let's probe the device
341
 
342
        call    probe                                                   ; this function will output in eax
343
        test    eax, eax
344
        jnz     .err                                                    ; If an error occured, exit
345
 
346
        mov     eax, [devices]                                          ; Add the device structure to our device list
347
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
348
        inc     [devices]                                               ;
349
 
3685 hidnplayr 350
        call    reset
351
        test    eax, eax
352
        jnz     .destroy
353
 
5045 hidnplayr 354
        mov     [ebx + device.type], NET_TYPE_ETH
355
        invoke  NetRegDev
3545 hidnplayr 356
 
357
        cmp     eax, -1
358
        je      .destroy
359
 
360
        ret
361
 
362
; If the device was already loaded, find the device number and return it in eax
363
 
364
  .find_devicenum:
3856 hidnplayr 365
        DEBUGF  1, "Trying to find device number of already registered device\n"
5045 hidnplayr 366
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
3545 hidnplayr 367
                                                                        ; into a device number in edi
368
        mov     eax, edi                                                ; Application wants it in eax instead
3856 hidnplayr 369
        DEBUGF  1, "Kernel says: %u\n", eax
3545 hidnplayr 370
        ret
371
 
372
; If an error occured, remove all allocated data and exit (returning -1 in eax)
373
  .destroy:
6682 hidnplayr 374
        ; unregister device from device_list
375
        mov     eax, [devices]
376
        mov     dword[device_list-4+4*eax], 0
377
        dec     [devices]
3545 hidnplayr 378
 
379
  .err:
3856 hidnplayr 380
        DEBUGF  2, "Error, removing all data !\n"
5045 hidnplayr 381
        invoke  KernelFree, [ebx + device.rx_buffer]
382
        invoke  KernelFree, ebx
3545 hidnplayr 383
 
384
  .fail:
385
        or      eax, -1
386
        ret
387
 
388
;------------------------------------------------------
389
endp
390
 
391
 
392
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
393
;;                                                                        ;;
394
;;        Actual Hardware dependent code starts here                      ;;
395
;;                                                                        ;;
396
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
397
 
398
align 4
399
unload:
400
        ; TODO: (in this particular order)
401
        ;
402
        ; - Stop the device
403
        ; - Detach int handler
404
        ; - Remove device from local list (RTL8139_LIST)
405
        ; - call unregister function in kernel
406
        ; - Remove all allocated structures and buffers the card used
407
 
408
        or      eax, -1
5522 hidnplayr 409
        ret
3545 hidnplayr 410
 
411
 
412
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
413
;;
414
;;  probe: enables the device (if it really is RTL8139)
415
;;
416
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
417
 
418
align 4
419
probe:
3856 hidnplayr 420
        DEBUGF  1, "Probing\n"
3545 hidnplayr 421
 
5045 hidnplayr 422
; Make the device a bus master
423
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
424
        or      al, PCI_CMD_MASTER
425
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 426
 
427
; get chip version
5045 hidnplayr 428
        set_io  [ebx + device.io_addr], 0
429
        set_io  [ebx + device.io_addr], REG_TXCONFIG + 2
3545 hidnplayr 430
        in      ax, dx
431
        shr     ah, 2
432
        shr     ax, 6
433
        and     al, 01111111b
434
 
435
; now find it in our array
436
        mov     ecx, HW_VER_ARRAY_SIZE-1
437
  .chip_ver_loop:
438
        cmp     al, [hw_ver_array + ecx]
439
        je      .chip_ver_found
440
        dec     ecx
441
        jns     .chip_ver_loop
442
  .unknown:
443
        mov     ecx, 8
444
  .chip_ver_found:
445
        cmp     ecx, 8
446
        ja      .unknown
447
 
5045 hidnplayr 448
        mov     [ebx + device.hw_ver_id], cl
3545 hidnplayr 449
 
450
        mov     ecx, [crosslist+ecx*4]
5045 hidnplayr 451
        mov     [ebx + device.name], ecx
3545 hidnplayr 452
 
3856 hidnplayr 453
        DEBUGF  1, "Chip version: %s\n", ecx
3545 hidnplayr 454
 
455
; wake up the chip
5045 hidnplayr 456
        set_io  [ebx + device.io_addr], 0
457
        set_io  [ebx + device.io_addr], REG_HLTCLK
3545 hidnplayr 458
        mov     al, 'R'         ; run the clock
459
        out     dx, al
460
 
461
; unlock config and BMCR registers
5045 hidnplayr 462
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 463
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
464
        out     dx, al
465
 
466
; enable power management
5045 hidnplayr 467
        set_io  [ebx + device.io_addr], REG_CONFIG1
3545 hidnplayr 468
        in      al, dx
5045 hidnplayr 469
        cmp     [ebx + device.hw_ver_id], IDX_RTL8139B
3545 hidnplayr 470
        jae     .new_chip
471
; wake up older chips
472
        and     al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
473
        out     dx, al
474
        jmp     .finish_wake_up
475
 
476
; set LWAKE pin to active high (default value).
477
; it is for Wake-On-LAN functionality of some motherboards.
478
; this signal is used to inform the motherboard to execute a wake-up process.
479
; only at newer chips.
480
  .new_chip:
481
        or      al, (1 shl BIT_PMEn)
482
        and     al, not (1 shl BIT_LWACT)
483
        out     dx, al
484
 
5045 hidnplayr 485
        set_io  [ebx + device.io_addr], REG_CONFIG4
3545 hidnplayr 486
        in      al, dx
487
        and     al, not (1 shl BIT_LWPTN)
488
        out     dx, al
489
 
490
; lock config and BMCR registers
491
  .finish_wake_up:
492
        xor     al, al
5045 hidnplayr 493
        set_io  [ebx + device.io_addr], 0
494
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 495
        out     dx, al
3856 hidnplayr 496
        DEBUGF  1, "probing done!\n"
3545 hidnplayr 497
 
3685 hidnplayr 498
        xor     eax, eax
3545 hidnplayr 499
 
3685 hidnplayr 500
        ret
501
 
502
 
3545 hidnplayr 503
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
504
;;
505
;;   reset: Set up all registers and descriptors, clear some values
506
;;
507
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
508
 
509
reset:
3856 hidnplayr 510
        DEBUGF  1, "Reset\n"
3545 hidnplayr 511
 
512
; reset chip
513
        DEBUGF  1, "Resetting chip\n"
5045 hidnplayr 514
        set_io  [ebx + device.io_addr], 0
515
        set_io  [ebx + device.io_addr], REG_COMMAND
3545 hidnplayr 516
        mov     al, 1 shl BIT_RST
517
        out     dx, al
518
        mov     cx, 1000                ; wait no longer for the reset
519
  .wait_for_reset:
520
        in      al, dx
521
        test    al, 1 shl BIT_RST
522
        jz      .reset_completed        ; RST remains 1 during reset
523
        dec     cx
524
        jns     .wait_for_reset
3856 hidnplayr 525
        DEBUGF  2, "Reset timeout!\n"
6682 hidnplayr 526
        or      eax, -1
527
        ret
3545 hidnplayr 528
  .reset_completed:
529
 
3858 hidnplayr 530
; Read MAC address
531
        call    read_mac
532
 
6682 hidnplayr 533
; attach int handler
534
        movzx   eax, [ebx + device.irq_line]
535
        DEBUGF  1, "Attaching int handler to irq %x\n", eax:1
536
        invoke  AttachIntHandler, eax, int_handler, ebx
537
        test    eax, eax
538
        jnz     @f
539
        DEBUGF  2, "Could not attach int handler!\n"
540
        or      eax, -1
541
        ret
542
       @@:
543
 
3545 hidnplayr 544
; unlock config and BMCR registers
5045 hidnplayr 545
        set_io  [ebx + device.io_addr], 0
546
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 547
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
548
        out     dx, al
549
 
550
; initialize multicast registers (no filtering)
551
        mov     eax, 0xffffffff
5045 hidnplayr 552
        set_io  [ebx + device.io_addr], REG_MAR0
3545 hidnplayr 553
        out     dx, eax
5045 hidnplayr 554
        set_io  [ebx + device.io_addr], REG_MAR4
3545 hidnplayr 555
        out     dx, eax
556
 
557
; enable Rx/Tx
558
        mov     al, (1 shl BIT_RE) or (1 shl BIT_TE)
5045 hidnplayr 559
        set_io  [ebx + device.io_addr], REG_COMMAND
3545 hidnplayr 560
        out     dx, al
561
 
562
; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold
563
; accept broadcast packets, accept physical match packets
3858 hidnplayr 564
        mov     eax, RX_CONFIG
5045 hidnplayr 565
        set_io  [ebx + device.io_addr], REG_RXCONFIG
3858 hidnplayr 566
        out     dx, eax
3545 hidnplayr 567
 
568
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
569
        mov     eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
5045 hidnplayr 570
        set_io  [ebx + device.io_addr], REG_TXCONFIG
3545 hidnplayr 571
        out     dx, eax
572
 
573
; enable auto negotiation
5045 hidnplayr 574
        set_io  [ebx + device.io_addr], REG_BMCR
3545 hidnplayr 575
        in      ax, dx
576
        or      ax, (1 shl BIT_ANE)
577
        out     dx, ax
578
 
579
; set auto negotiation advertisement
5045 hidnplayr 580
        set_io  [ebx + device.io_addr], REG_ANAR
3545 hidnplayr 581
        in      ax, dx
582
        or      ax, (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD)
583
        out     dx, ax
584
 
585
; lock config and BMCR registers
586
        xor     eax, eax
5045 hidnplayr 587
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 588
        out     dx, al
589
 
590
; init RX/TX pointers
5045 hidnplayr 591
        mov     [ebx + device.rx_data_offset], eax
592
        mov     [ebx + device.curr_tx_desc], al
593
;        set_io  [ebx + device.io_addr], REG_CAPR
3545 hidnplayr 594
;        out     dx, ax
595
 
596
; clear packet/byte counters
5045 hidnplayr 597
        lea     edi, [ebx + device.bytes_tx]
3545 hidnplayr 598
        mov     ecx, 6
599
        rep     stosd
600
 
601
; clear missing packet counter
5045 hidnplayr 602
        set_io  [ebx + device.io_addr], REG_MPC
3545 hidnplayr 603
        out     dx, eax
604
 
605
; set RxBuffer address, init RX buffer offset
5045 hidnplayr 606
        mov     eax, [ebx + device.rx_buffer]
3545 hidnplayr 607
        mov     dword[eax], 0                   ; clear receive flags for first packet (really needed??)
3685 hidnplayr 608
        DEBUGF  1, "RX buffer virtual addr=0x%x\n", eax
5045 hidnplayr 609
        invoke  GetPhysAddr
3857 hidnplayr 610
        DEBUGF  1, "RX buffer physical addr=0x%x\n", eax
5045 hidnplayr 611
        set_io  [ebx + device.io_addr], REG_RBSTART
3545 hidnplayr 612
        out     dx, eax
613
 
614
; enable interrupts
5045 hidnplayr 615
        set_io  [ebx + device.io_addr], 0
616
        set_io  [ebx + device.io_addr], REG_IMR
3545 hidnplayr 617
        mov     ax, INTERRUPT_MASK
618
        out     dx, ax
619
 
620
; Set the mtu, kernel will be able to send now
5045 hidnplayr 621
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 622
 
6227 hidnplayr 623
        call    link
3545 hidnplayr 624
 
625
; Indicate that we have successfully reset the card
626
        xor     eax, eax
627
        ret
628
 
629
 
630
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
631
;;                                         ;;
632
;; Transmit                                ;;
633
;;                                         ;;
5522 hidnplayr 634
;; In: pointer to device structure in ebx  ;;
3545 hidnplayr 635
;;                                         ;;
636
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5045 hidnplayr 637
 
5522 hidnplayr 638
proc transmit stdcall bufferptr
5045 hidnplayr 639
 
640
        pushf
641
        cli
642
 
5522 hidnplayr 643
        mov     esi, [bufferptr]
644
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
645
        lea     eax, [esi + NET_BUFF.data]
5045 hidnplayr 646
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
3545 hidnplayr 647
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
648
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
649
        [eax+13]:2,[eax+12]:2
650
 
5522 hidnplayr 651
        cmp     [esi + NET_BUFF.length], 1514
3545 hidnplayr 652
        ja      .fail
5522 hidnplayr 653
        cmp     [esi + NET_BUFF.length], 60
3545 hidnplayr 654
        jb      .fail
655
 
656
; check if we own the current discriptor
5045 hidnplayr 657
        set_io  [ebx + device.io_addr], 0
658
        set_io  [ebx + device.io_addr], REG_TSD0
659
        movzx   ecx, [ebx + device.curr_tx_desc]
3545 hidnplayr 660
        shl     ecx, 2
661
        add     edx, ecx
662
        in      eax, dx
663
        test    eax, (1 shl BIT_OWN)
664
        jz      .wait_to_send
665
 
666
  .send_packet:
667
; Set the buffer address
5045 hidnplayr 668
        set_io  [ebx + device.io_addr], REG_TSAD0
5522 hidnplayr 669
        mov     [ebx + device.TX_DESC+ecx], esi
670
        mov     eax, esi
671
        add     eax, [eax + NET_BUFF.offset]
5045 hidnplayr 672
        invoke  GetPhysAddr
3545 hidnplayr 673
        out     dx, eax
674
 
675
; And the size of the buffer
5045 hidnplayr 676
        set_io  [ebx + device.io_addr], REG_TSD0
5522 hidnplayr 677
        mov     eax, [esi + NET_BUFF.length]
3545 hidnplayr 678
        or      eax, (ERTXTH shl BIT_ERTXTH)    ; Early threshold
679
        out     dx, eax
680
 
5522 hidnplayr 681
; get next descriptor
682
        inc     [ebx + device.curr_tx_desc]
683
        and     [ebx + device.curr_tx_desc], NUM_TX_DESC-1
684
 
685
; Update stats
686
        inc     [ebx + device.packets_tx]
687
        mov     ecx, [esi + NET_BUFF.length]
688
        add     dword [ebx + device.bytes_tx], ecx
689
        adc     dword [ebx + device.bytes_tx+4], 0
690
 
3545 hidnplayr 691
        DEBUGF  1, "Packet Sent!\n"
5127 hidnplayr 692
        popf
3545 hidnplayr 693
        xor     eax, eax
5045 hidnplayr 694
        ret
3545 hidnplayr 695
 
696
  .wait_to_send:
697
        DEBUGF  1, "Waiting for timeout\n"
698
 
699
        push    edx
700
        mov     esi, 30
5045 hidnplayr 701
        invoke  Sleep
3545 hidnplayr 702
        pop     edx
703
 
704
        in      ax, dx
705
        test    ax, (1 shl BIT_OWN)
706
        jnz     .send_packet
707
 
708
        pusha
709
        call    reset                            ; if chip hung, reset it
710
        popa
711
 
712
        jmp     .send_packet
713
 
714
  .fail:
3856 hidnplayr 715
        DEBUGF  2, "transmit failed!\n"
5522 hidnplayr 716
        invoke  NetFree, [bufferptr]
5045 hidnplayr 717
        popf
3545 hidnplayr 718
        or      eax, -1
5045 hidnplayr 719
        ret
3545 hidnplayr 720
 
5045 hidnplayr 721
endp
3545 hidnplayr 722
 
723
 
724
 
725
 
5045 hidnplayr 726
 
3545 hidnplayr 727
;;;;;;;;;;;;;;;;;;;;;;;
728
;;                   ;;
729
;; Interrupt handler ;;
730
;;                   ;;
731
;;;;;;;;;;;;;;;;;;;;;;;
732
 
733
align 4
734
int_handler:
735
 
736
        push    ebx esi edi
737
 
3856 hidnplayr 738
        DEBUGF  1, "INT\n"
3545 hidnplayr 739
 
740
; find pointer of device wich made IRQ occur
741
        mov     ecx, [devices]
742
        test    ecx, ecx
743
        jz      .nothing
744
        mov     esi, device_list
745
  .nextdevice:
746
        mov     ebx, [esi]
747
 
5045 hidnplayr 748
        set_io  [ebx + device.io_addr], 0
749
        set_io  [ebx + device.io_addr], REG_ISR
3545 hidnplayr 750
        in      ax, dx                          ; Get interrupt status
751
        out     dx, ax                          ; send it back to ACK
752
        test    ax, ax
753
        jnz     .got_it
754
  .continue:
755
        add     esi, 4
756
        dec     ecx
757
        jnz     .nextdevice
758
  .nothing:
759
        pop     edi esi ebx
760
        xor     eax, eax
761
 
762
        ret                                     ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
763
 
764
  .got_it:
765
 
766
        DEBUGF  1, "Device: %x Status: %x\n", ebx, ax
767
 
768
;----------------------------------------------------
769
; Received packet ok?
770
 
771
        test    ax, ISR_ROK
772
        jz      @f
773
        push    ax
774
 
775
  .receive:
5045 hidnplayr 776
        set_io  [ebx + device.io_addr], 0
777
        set_io  [ebx + device.io_addr], REG_COMMAND
3545 hidnplayr 778
        in      al, dx
779
        test    al, BUFE                        ; test if RX buffer is empty
780
        jnz     .finish
781
 
3856 hidnplayr 782
        DEBUGF  1, "RX:\n"
3545 hidnplayr 783
 
5045 hidnplayr 784
        mov     eax, [ebx + device.rx_buffer]
785
        add     eax, [ebx + device.rx_data_offset]
3545 hidnplayr 786
        test    byte [eax], (1 shl BIT_ROK)     ; check if packet is ok
787
        jz      .reset_rx
788
 
789
; packet is ok, copy it
790
        movzx   ecx, word [eax+2]               ; packet length
791
        sub     cx, 4                           ; don't copy CRC
792
 
793
; Update stats
5045 hidnplayr 794
        add     dword [ebx + device.bytes_rx], ecx
795
        adc     dword [ebx + device.bytes_rx + 4], 0
796
        inc     [ebx + device.packets_rx]
3545 hidnplayr 797
 
798
        DEBUGF  1, "Received %u bytes\n", ecx
799
 
800
        push    ebx eax ecx
5522 hidnplayr 801
        add     ecx, NET_BUFF.data
802
        invoke  NetAlloc, ecx                   ; Allocate a buffer to put packet into
3545 hidnplayr 803
        pop     ecx
804
        test    eax, eax                        ; Test if we allocated succesfully
805
        jz      .abort
5522 hidnplayr 806
        mov     [eax + NET_BUFF.length], ecx
807
        mov     [eax + NET_BUFF.device], ebx
808
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
3545 hidnplayr 809
 
5522 hidnplayr 810
        lea     edi, [eax + NET_BUFF.data]      ; Where we will copy too
3545 hidnplayr 811
        mov     esi, [esp]                      ; The buffer we will copy from
812
        add     esi, 4                          ; Dont copy CRC
813
 
5522 hidnplayr 814
        push    .abort                          ; return addr for Eth_input
815
        push    eax                             ; buffer ptr for Eth_input
3545 hidnplayr 816
 
817
  .copy:
818
        shr     ecx, 1
819
        jnc     .nb
820
        movsb
821
  .nb:
822
        shr     ecx, 1
823
        jnc     .nw
824
        movsw
825
  .nw:
826
        jz      .nd
827
        rep     movsd
828
  .nd:
829
 
5522 hidnplayr 830
        jmp     [EthInput]                      ; Send it to kernel
3545 hidnplayr 831
 
832
  .abort:
833
        pop     eax ebx
834
                                                ; update eth_data_start_offset
835
        movzx   eax, word [eax+2]               ; packet length
5045 hidnplayr 836
        add     eax, [ebx + device.rx_data_offset]
3545 hidnplayr 837
        add     eax, 4+3                        ; packet header is 4 bytes long + dword alignment
838
        and     eax, not 3                      ; dword alignment
839
 
840
        cmp     eax, RX_BUFFER_SIZE
841
        jb      .no_wrap
3856 hidnplayr 842
        DEBUGF  1, "Wrapping\n"
3545 hidnplayr 843
        sub     eax, RX_BUFFER_SIZE
844
  .no_wrap:
5045 hidnplayr 845
        mov     [ebx + device.rx_data_offset], eax
3545 hidnplayr 846
        DEBUGF  1, "New RX ptr: %d\n", eax
847
 
5045 hidnplayr 848
        set_io  [ebx + device.io_addr], 0
849
        set_io  [ebx + device.io_addr], REG_CAPR                        ; update 'Current Address of Packet Read register'
3545 hidnplayr 850
        sub     eax, 0x10                       ; value 0x10 is a constant for CAPR
3857 hidnplayr 851
        out     dx, ax
3545 hidnplayr 852
 
853
        jmp     .receive                        ; check for multiple packets
854
 
855
  .reset_rx:
856
        test    byte [eax], (1 shl BIT_CRC)
857
        jz      .no_crc_error
3856 hidnplayr 858
        DEBUGF  2, "RX: CRC error!\n"
3545 hidnplayr 859
 
860
  .no_crc_error:
861
        test    byte [eax], (1 shl BIT_FAE)
862
        jz      .no_fae_error
3856 hidnplayr 863
        DEBUGF  2, "RX: Frame alignment error!\n"
3545 hidnplayr 864
 
865
  .no_fae_error:
866
        DEBUGF  1, "Reset RX\n"
867
        in      al, dx                          ; read command register
868
        push    ax
869
        and     al, not (1 shl BIT_RE)          ; Clear the RE bit
870
        out     dx, al
871
        pop     ax
872
        out     dx, al                          ; write original command back
873
 
874
        add     edx, REG_RXCONFIG - REG_COMMAND         ; Restore RX configuration
875
        mov     ax, RX_CONFIG
876
        out     dx, ax
877
 
878
  .finish:
879
        pop     ax
880
 
881
;----------------------------------------------------
882
; Transmit ok / Transmit error
883
  @@:
884
        test    ax, ISR_TOK + ISR_TER
885
        jz      @f
886
 
3857 hidnplayr 887
        DEBUGF  1, "Transmit done!\n"
888
 
3545 hidnplayr 889
        push    ax
890
        mov     ecx, (NUM_TX_DESC-1)*4
891
  .txdescloop:
5045 hidnplayr 892
        set_io  [ebx + device.io_addr], 0
893
        set_io  [ebx + device.io_addr], REG_TSD0
3545 hidnplayr 894
        add     edx, ecx
895
        in      eax, dx
896
 
897
        test    eax, TSR_OWN                    ; DMA operation completed
898
        jz      .notthisone
899
 
5045 hidnplayr 900
        cmp     [ebx + device.TX_DESC+ecx], 0
3545 hidnplayr 901
        je      .notthisone
902
 
3857 hidnplayr 903
        DEBUGF  1, "TSD: 0x%x\n", eax
3545 hidnplayr 904
 
3857 hidnplayr 905
        test    eax, TSR_TUN
906
        jz      .no_bun
907
        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
908
 
909
  .no_bun:
910
        test    eax, TSR_OWC
911
        jz      .no_owc
912
        DEBUGF  2, "TX: OWC!\n"
913
 
914
  .no_owc:
915
        test    eax, TSR_TABT
916
        jz      .no_tabt
917
        DEBUGF  2, "TX: TABT!\n"
918
 
919
  .no_tabt:
920
        test    eax, TSR_CRS
921
        jz      .no_csl
922
        DEBUGF  2, "TX: Carrier Sense Lost!\n"
923
 
924
  .no_csl:
925
        test    eax, TSR_TOK
926
        jz      .no_tok
927
        DEBUGF  1, "TX: Transmit OK!\n"
928
 
929
  .no_tok:
5045 hidnplayr 930
        DEBUGF  1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8
3545 hidnplayr 931
        push    ecx ebx
5522 hidnplayr 932
        invoke  NetFree, [ebx + device.TX_DESC+ecx]
3545 hidnplayr 933
        pop     ebx ecx
5045 hidnplayr 934
        mov     [ebx + device.TX_DESC+ecx], 0
3545 hidnplayr 935
 
936
  .notthisone:
937
        sub     ecx, 4
3857 hidnplayr 938
        jae     .txdescloop
3545 hidnplayr 939
        pop     ax
940
 
941
;----------------------------------------------------
942
; Rx buffer overflow ?
943
  @@:
944
        test    ax, ISR_RXOVW
945
        jz      @f
946
 
947
        push    ax
3856 hidnplayr 948
        DEBUGF  2, "RX:buffer overflow!\n"
3545 hidnplayr 949
 
5045 hidnplayr 950
        set_io  [ebx + device.io_addr], 0
951
        set_io  [ebx + device.io_addr], REG_ISR
6227 hidnplayr 952
        mov     ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
3545 hidnplayr 953
        out     dx, ax
954
        pop     ax
955
 
956
;----------------------------------------------------
957
; Packet underrun?
958
  @@:
959
        test    ax, ISR_PUN
960
        jz      @f
961
 
4449 hidnplayr 962
        DEBUGF  1, "Packet underrun or link changed!\n"
3545 hidnplayr 963
 
6227 hidnplayr 964
        call    link
4449 hidnplayr 965
 
3545 hidnplayr 966
;----------------------------------------------------
967
; Receive FIFO overflow ?
968
  @@:
969
        test    ax, ISR_FIFOOVW
970
        jz      @f
971
 
972
        push    ax
4449 hidnplayr 973
        DEBUGF  2, "RX fifo overflow!\n"
3545 hidnplayr 974
 
5045 hidnplayr 975
        set_io  [ebx + device.io_addr], 0
976
        set_io  [ebx + device.io_addr], REG_ISR
6227 hidnplayr 977
        mov     ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
3545 hidnplayr 978
        out     dx, ax
979
        pop     ax
980
 
981
;----------------------------------------------------
4449 hidnplayr 982
; cable length changed ?
3545 hidnplayr 983
  @@:
984
        test    ax, ISR_LENCHG
985
        jz      .fail
986
 
4449 hidnplayr 987
        DEBUGF  2, "Cable length changed!\n"
988
 
6227 hidnplayr 989
        call    link
3545 hidnplayr 990
 
991
  .fail:
992
        pop     edi esi ebx
993
        xor     eax, eax
994
        inc     eax
995
 
996
        ret
997
 
998
 
999
 
1000
 
6227 hidnplayr 1001
;;;;;;;;;;;;;;;;;;;;;;;
1002
;;                   ;;
1003
;; Check link status ;;
1004
;;                   ;;
1005
;;;;;;;;;;;;;;;;;;;;;;;
3545 hidnplayr 1006
 
1007
align 4
6227 hidnplayr 1008
link:
3857 hidnplayr 1009
        DEBUGF  1, "Checking link status:\n"
3545 hidnplayr 1010
 
5045 hidnplayr 1011
        set_io  [ebx + device.io_addr], 0
1012
        set_io  [ebx + device.io_addr], REG_MSR
6227 hidnplayr 1013
        in      ax, dx
3545 hidnplayr 1014
 
1015
        test    al, 1 shl 2             ; 0 = link ok 1 = link fail
1016
        jnz     .notconnected
1017
 
6227 hidnplayr 1018
        mov     ecx, ETH_LINK_10M
3545 hidnplayr 1019
        test    al, 1 shl 3             ; 0 = 100 Mbps 1 = 10 Mbps
6227 hidnplayr 1020
        jnz     @f
1021
        mov     ecx, ETH_LINK_100M
1022
  @@:
3545 hidnplayr 1023
 
6227 hidnplayr 1024
        set_io  [ebx + device.io_addr], REG_BMCR
1025
        in      ax, dx
1026
        test    ax, 1 shl 8             ; Duplex mode
1027
        jz      @f
1028
        or      ecx, ETH_LINK_FD
1029
  @@:
3545 hidnplayr 1030
 
6227 hidnplayr 1031
        mov     [ebx + device.state], ecx
5045 hidnplayr 1032
        invoke  NetLinkChanged
6227 hidnplayr 1033
        DEBUGF  2, "link is up\n"
3545 hidnplayr 1034
        ret
1035
 
1036
  .notconnected:
5045 hidnplayr 1037
        mov     [ebx + device.state], ETH_LINK_DOWN
1038
        invoke  NetLinkChanged
6227 hidnplayr 1039
        DEBUGF  2, "link is down\n"
3545 hidnplayr 1040
        ret
1041
 
1042
 
1043
 
1044
;;;;;;;;;;;;;;;;;;;;;;;
1045
;;                   ;;
1046
;; Write MAC address ;;
1047
;;                   ;;
1048
;;;;;;;;;;;;;;;;;;;;;;;
1049
 
1050
align 4
1051
write_mac:      ; in: mac pushed onto stack (as 3 words)
1052
 
3856 hidnplayr 1053
        DEBUGF  1, "Writing MAC\n"
3545 hidnplayr 1054
 
1055
; disable all in command registers
5045 hidnplayr 1056
        set_io  [ebx + device.io_addr], 0
1057
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 1058
        xor     eax, eax
1059
        out     dx, al
1060
 
5045 hidnplayr 1061
        set_io  [ebx + device.io_addr], REG_IMR
3545 hidnplayr 1062
        xor     eax, eax
1063
        out     dx, ax
1064
 
5045 hidnplayr 1065
        set_io  [ebx + device.io_addr], REG_ISR
3545 hidnplayr 1066
        mov     eax, -1
1067
        out     dx, ax
1068
 
1069
; enable writing
5045 hidnplayr 1070
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 1071
        mov     eax, REG_9346CR_WE
1072
        out     dx, al
1073
 
1074
 ; write the mac ...
5045 hidnplayr 1075
        set_io  [ebx + device.io_addr], REG_IDR0
3545 hidnplayr 1076
        pop     eax
1077
        out     dx, eax
1078
 
5045 hidnplayr 1079
        set_io  [ebx + device.io_addr], REG_IDR0+4
3545 hidnplayr 1080
        xor     eax, eax
1081
        pop     ax
1082
        out     dx, eax
1083
 
1084
; disable writing
5045 hidnplayr 1085
        set_io  [ebx + device.io_addr], REG_9346CR
3545 hidnplayr 1086
        xor     eax, eax
1087
        out     dx, al
1088
 
3856 hidnplayr 1089
        DEBUGF  1, "MAC write ok!\n"
3545 hidnplayr 1090
 
1091
; Notice this procedure does not ret, but continues to read_mac instead.
1092
 
1093
 
1094
;;;;;;;;;;;;;;;;;;;;;;
1095
;;                  ;;
1096
;; Read MAC address ;;
1097
;;                  ;;
1098
;;;;;;;;;;;;;;;;;;;;;;
1099
 
1100
read_mac:
3857 hidnplayr 1101
        DEBUGF  1, "Reading MAC:\n"
3545 hidnplayr 1102
 
5045 hidnplayr 1103
        set_io  [ebx + device.io_addr], 0
1104
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1105
        in      eax, dx
1106
        stosd
1107
        add     edx, 4
1108
        in      ax, dx
1109
        stosw
1110
 
3857 hidnplayr 1111
        DEBUGF  1, "%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
3545 hidnplayr 1112
 
1113
        ret
1114
 
1115
 
1116
; End of code
1117
 
5045 hidnplayr 1118
data fixups
1119
end data
3545 hidnplayr 1120
 
5045 hidnplayr 1121
include '../peimport.inc'
1122
 
3545 hidnplayr 1123
my_service      db 'RTL8139',0                    ; max 16 chars include zero
1124
 
1125
device_1        db 'Realtek 8139',0
1126
device_2        db 'Realtek 8139A',0
1127
device_3        db 'Realtek 8139B',0
1128
device_4        db 'Realtek 8139C',0
1129
device_5        db 'Realtek 8100',0
1130
device_6        db 'Realtek 8139D',0
1131
device_7        db 'Realtek 8139CP',0
1132
device_8        db 'Realtek 8101',0
1133
device_unknown  db 'Unknown RTL8139 clone', 0
1134
 
1135
crosslist:
1136
        dd device_1
1137
        dd device_2
1138
        dd device_3
1139
        dd device_4
1140
        dd device_5
1141
        dd device_6
1142
        dd device_7
1143
        dd device_8
1144
        dd device_unknown
1145
 
1146
hw_ver_array:                    ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1147
        db VER_RTL8139
1148
        db VER_RTL8139A
1149
        db VER_RTL8139B
1150
        db VER_RTL8139C
1151
        db VER_RTL8100
1152
        db VER_RTL8139D
1153
        db VER_RTL8139CP
1154
        db VER_RTL8101
1155
        db 0
1156
 
1157
HW_VER_ARRAY_SIZE = $-hw_ver_array
1158
 
1159
include_debug_strings                           ; All data wich FDO uses will be included here
1160
 
5045 hidnplayr 1161
align 4
1162
devices         dd 0
3545 hidnplayr 1163
device_list     rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling
1164