Subversion Repositories Kolibri OS

Rev

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

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