Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3155 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2013. 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
 
3155 hidnplayr 20
        API_VERSION             = 0x01000100
21
        DRIVER_VERSION          = 5
1159 hidnplayr 22
 
3155 hidnplayr 23
        MAX_DEVICES             = 16
1519 hidnplayr 24
 
3155 hidnplayr 25
        RBLEN                   = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
26
        NUM_TX_DESC             = 4
1556 hidnplayr 27
 
3155 hidnplayr 28
        DEBUG                   = 1
29
        __DEBUG__               = 1
30
        __DEBUG_LEVEL__         = 1
1159 hidnplayr 31
 
32
include 'proc32.inc'
33
include 'imports.inc'
34
include 'fdo.inc'
3155 hidnplayr 35
include '../struct.inc'
1472 hidnplayr 36
include 'netdrv.inc'
1159 hidnplayr 37
 
38
public START
39
public service_proc
40
public version
41
 
3155 hidnplayr 42
        REG_IDR0                = 0x00
43
        REG_MAR0                = 0x08 ; multicast filter register 0
44
        REG_MAR4                = 0x0c ; multicast filter register 4
45
        REG_TSD0                = 0x10 ; transmit status of descriptor
46
        REG_TSAD0               = 0x20 ; transmit start address of descriptor
47
        REG_RBSTART             = 0x30 ; RxBuffer start address
48
        REG_COMMAND             = 0x37 ; command register
49
        REG_CAPR                = 0x38 ; current address of packet read (word) R/W
50
        REG_IMR                 = 0x3c ; interrupt mask register
51
        REG_ISR                 = 0x3e ; interrupt status register
52
        REG_TXCONFIG            = 0x40 ; transmit configuration register
53
        REG_RXCONFIG            = 0x44 ; receive configuration register 0
54
        REG_MPC                 = 0x4c ; missed packet counter
55
        REG_9346CR              = 0x50 ; serial eeprom 93C46 command register
56
        REG_CONFIG1             = 0x52 ; configuration register 1
57
        REG_MSR                 = 0x58
58
        REG_CONFIG4             = 0x5a ; configuration register 4
59
        REG_HLTCLK              = 0x5b ; undocumented halt clock register
60
        REG_BMCR                = 0x62 ; basic mode control register
61
        REG_ANAR                = 0x66 ; auto negotiation advertisement register
62
        REG_9346CR_WE           = 11b SHL 6
1159 hidnplayr 63
 
3155 hidnplayr 64
        BIT_RUNT                = 4 ; total packet length < 64 bytes
65
        BIT_LONG                = 3 ; total packet length > 4k
66
        BIT_CRC                 = 2 ; crc error occured
67
        BIT_FAE                 = 1 ; frame alignment error occured
68
        BIT_ROK                 = 0 ; received packet is ok
1159 hidnplayr 69
 
3155 hidnplayr 70
        BIT_RST                 = 4 ; reset bit
71
        BIT_RE                  = 3 ; receiver enabled
72
        BIT_TE                  = 2 ; transmitter enabled
73
        BUFE                    = 1 ; rx buffer is empty, no packet stored
1159 hidnplayr 74
 
3155 hidnplayr 75
        BIT_ISR_TOK             = 2 ; transmit ok
76
        BIT_ISR_RER             = 1 ; receive error interrupt
77
        BIT_ISR_ROK             = 0 ; receive ok
1159 hidnplayr 78
 
3155 hidnplayr 79
        BIT_TX_MXDMA            = 8 ; Max DMA burst size per Tx DMA burst
80
        BIT_TXRR                = 4 ; Tx Retry count 16+(TXRR*16)
1159 hidnplayr 81
 
3155 hidnplayr 82
        BIT_RXFTH               = 13 ; Rx fifo threshold
83
        BIT_RBLEN               = 11 ; Ring buffer length indicator
84
        BIT_RX_MXDMA            = 8 ; Max DMA burst size per Rx DMA burst
85
        BIT_NOWRAP              = 7 ; transfered data wrapping
86
        BIT_9356SEL             = 6 ; eeprom selector 9346/9356
87
        BIT_AER                 = 5 ; accept error packets
88
        BIT_AR                  = 4 ; accept runt packets
89
        BIT_AB                  = 3 ; accept broadcast packets
90
        BIT_AM                  = 2 ; accept multicast packets
91
        BIT_APM                 = 1 ; accept physical match packets
92
        BIT_AAP                 = 0 ; accept all packets
1159 hidnplayr 93
 
3155 hidnplayr 94
        BIT_93C46_EEM1          = 7 ; RTL8139 eeprom operating mode1
95
        BIT_93C46_EEM0          = 6 ; RTL8139 eeprom operating mode0
96
        BIT_93C46_EECS          = 3 ; chip select
97
        BIT_93C46_EESK          = 2 ; serial data clock
98
        BIT_93C46_EEDI          = 1 ; serial data input
99
        BIT_93C46_EEDO          = 0 ; serial data output
1159 hidnplayr 100
 
3155 hidnplayr 101
        BIT_LWACT               = 4 ; see REG_CONFIG1
102
        BIT_SLEEP               = 1 ; sleep bit at older chips
103
        BIT_PWRDWN              = 0 ; power down bit at older chips
104
        BIT_PMEn                = 0 ; power management enabled
1159 hidnplayr 105
 
3155 hidnplayr 106
        BIT_LWPTN               = 2 ; see REG_CONFIG4
1159 hidnplayr 107
 
3155 hidnplayr 108
        BIT_ERTXTH              = 16 ; early TX threshold
109
        BIT_TOK                 = 15 ; transmit ok
110
        BIT_OWN                 = 13 ; tx DMA operation is completed
1159 hidnplayr 111
 
3155 hidnplayr 112
        BIT_ANE                 = 12 ; auto negotiation enable
1159 hidnplayr 113
 
3155 hidnplayr 114
        BIT_TXFD                = 8 ; 100base-T full duplex
115
        BIT_TX                  = 7 ; 100base-T
116
        BIT_10FD                = 6 ; 10base-T full duplex
117
        BIT_10                  = 5 ; 10base-T
118
        BIT_SELECTOR            = 0 ; binary encoded selector CSMA/CD=00001
1159 hidnplayr 119
 
3155 hidnplayr 120
        BIT_IFG1                = 25
121
        BIT_IFG0                = 24
1159 hidnplayr 122
 
3155 hidnplayr 123
        TXRR                    = 8 ; total retries = 16+(TXRR*16)
124
        TX_MXDMA                = 6 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048
125
        ERTXTH                  = 8 ; in unit of 32 bytes e.g:(8*32)=256
126
        RX_MXDMA                = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited
127
        RXFTH                   = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold
1159 hidnplayr 128
 
3155 hidnplayr 129
        RX_CONFIG               = (RBLEN shl BIT_RBLEN) or \
130
                                  (RX_MXDMA shl BIT_RX_MXDMA) or \
131
                                  (1 shl BIT_NOWRAP) or \
132
                                  (RXFTH shl BIT_RXFTH) or\
133
                                  (1 shl BIT_AB) or \                 ; Accept broadcast packets
134
                                  (1 shl BIT_APM) or \                ; Accept physical match packets
135
                                  (1 shl BIT_AER) or \                ; Accept error packets
136
                                  (1 shl BIT_AR) or \                 ; Accept Runt packets (smaller then 64 bytes)
137
                                  (1 shl BIT_AM)                      ; Accept multicast packets
1159 hidnplayr 138
 
3155 hidnplayr 139
        RX_BUFFER_SIZE          = (8192 shl RBLEN);+16
140
        MAX_ETH_FRAME_SIZE      = 1514
1159 hidnplayr 141
 
3155 hidnplayr 142
        EE_93C46_REG_ETH_ID     = 7 ; MAC offset
143
        EE_93C46_READ_CMD       = (6 shl 6) ; 110b + 6bit address
144
        EE_93C56_READ_CMD       = (6 shl 8) ; 110b + 8bit address
145
        EE_93C46_CMD_LENGTH     = 9  ; start bit + cmd + 6bit address
146
        EE_93C56_CMD_LENGTH     = 11 ; start bit + cmd + 8bit ddress
1159 hidnplayr 147
 
3155 hidnplayr 148
        VER_RTL8139             = 1100000b
149
        VER_RTL8139A            = 1110000b
150
        VER_RTL8139AG           = 1110100b
151
        VER_RTL8139B            = 1111000b
152
        VER_RTL8130             = VER_RTL8139B
153
        VER_RTL8139C            = 1110100b
154
        VER_RTL8100             = 1111010b
155
        VER_RTL8100B            = 1110101b
156
        VER_RTL8139D            = VER_RTL8100B
157
        VER_RTL8139CP           = 1110110b
158
        VER_RTL8101             = 1110111b
1159 hidnplayr 159
 
3155 hidnplayr 160
        IDX_RTL8139             = 0
161
        IDX_RTL8139A            = 1
162
        IDX_RTL8139B            = 2
163
        IDX_RTL8139C            = 3
164
        IDX_RTL8100             = 4
165
        IDX_RTL8139D            = 5
166
        IDX_RTL8139D            = 6
167
        IDX_RTL8101             = 7
1159 hidnplayr 168
 
3155 hidnplayr 169
        ISR_SERR                = 1 SHL 15
170
        ISR_TIMEOUT             = 1 SHL 14
171
        ISR_LENCHG              = 1 SHL 13
172
        ISR_FIFOOVW             = 1 SHL 6
173
        ISR_PUN                 = 1 SHL 5
174
        ISR_RXOVW               = 1 SHL 4
175
        ISR_TER                 = 1 SHL 3
176
        ISR_TOK                 = 1 SHL 2
177
        ISR_RER                 = 1 SHL 1
178
        ISR_ROK                 = 1 SHL 0
1159 hidnplayr 179
 
3155 hidnplayr 180
        INTERRUPT_MASK          = ISR_ROK or \
181
                                  ISR_RXOVW or \
182
                                  ISR_PUN or \
183
                                  ISR_FIFOOVW or \
184
                                  ISR_LENCHG or \
185
                                  ISR_TOK or \
186
                                  ISR_TER
1159 hidnplayr 187
 
3155 hidnplayr 188
        TSR_OWN                 = 1 SHL 13
189
        TSR_TUN                 = 1 SHL 14
190
        TSR_TOK                 = 1 SHL 15
1159 hidnplayr 191
 
3155 hidnplayr 192
        TSR_CDH                 = 1 SHL 28
193
        TSR_OWC                 = 1 SHL 29
194
        TSR_TABT                = 1 SHL 30
195
        TSR_CRS                 = 1 SHL 31
1159 hidnplayr 196
 
197
 
1519 hidnplayr 198
virtual at ebx
1159 hidnplayr 199
 
2387 hidnplayr 200
        device:
1519 hidnplayr 201
 
2387 hidnplayr 202
        ETH_DEVICE
1519 hidnplayr 203
 
2387 hidnplayr 204
        .rx_buffer      dd ?
205
        .tx_buffer      dd ?
1556 hidnplayr 206
 
2387 hidnplayr 207
        .rx_data_offset dd ?
208
        .io_addr        dd ?
1556 hidnplayr 209
 
2387 hidnplayr 210
        .curr_tx_desc   db ?
211
        .pci_bus        db ?
212
        .pci_dev        db ?
213
        .irq_line       db ?
214
        .hw_ver_id      db ?
1519 hidnplayr 215
 
2387 hidnplayr 216
        .TX_DESC        rd NUM_TX_DESC
1519 hidnplayr 217
 
2387 hidnplayr 218
        .size = $ - device
1519 hidnplayr 219
 
220
end virtual
221
 
222
 
223
 
1159 hidnplayr 224
section '.flat' code readable align 16
225
 
226
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
227
;;                        ;;
228
;; proc START             ;;
229
;;                        ;;
230
;; (standard driver proc) ;;
231
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
232
 
233
align 4
234
proc START stdcall, state:dword
235
 
3155 hidnplayr 236
        cmp     [state], 1
237
        jne     .exit
1159 hidnplayr 238
 
239
  .entry:
240
 
3155 hidnplayr 241
        DEBUGF  2, "Loading %s driver\n", my_service
2387 hidnplayr 242
        stdcall RegService, my_service, service_proc
243
        ret
1159 hidnplayr 244
 
245
  .fail:
246
  .exit:
3155 hidnplayr 247
        xor     eax, eax
2387 hidnplayr 248
        ret
1159 hidnplayr 249
 
250
endp
251
 
252
 
253
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254
;;                        ;;
255
;; proc SERVICE_PROC      ;;
256
;;                        ;;
257
;; (standard driver proc) ;;
258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
259
 
260
align 4
261
proc service_proc stdcall, ioctl:dword
262
 
2387 hidnplayr 263
        mov     edx, [ioctl]
264
        mov     eax, [IOCTL.io_code]
1159 hidnplayr 265
 
266
;------------------------------------------------------
267
 
2387 hidnplayr 268
        cmp     eax, 0 ;SRV_GETVERSION
269
        jne     @F
1159 hidnplayr 270
 
2387 hidnplayr 271
        cmp     [IOCTL.out_size], 4
3155 hidnplayr 272
        jb      .fail
2387 hidnplayr 273
        mov     eax, [IOCTL.output]
274
        mov     [eax], dword API_VERSION
1159 hidnplayr 275
 
2387 hidnplayr 276
        xor     eax, eax
277
        ret
1159 hidnplayr 278
 
279
;------------------------------------------------------
280
  @@:
2387 hidnplayr 281
        cmp     eax, 1 ;SRV_HOOK
282
        jne     .fail
1159 hidnplayr 283
 
3155 hidnplayr 284
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
285
        jb      .fail
1159 hidnplayr 286
 
2387 hidnplayr 287
        mov     eax, [IOCTL.input]
288
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
289
        jne     .fail                                   ; other types arent supported for this card yet
1159 hidnplayr 290
 
291
; check if the device is already listed
292
 
2387 hidnplayr 293
        mov     esi, device_list
294
        mov     ecx, [devices]
295
        test    ecx, ecx
296
        jz      .firstdevice
1472 hidnplayr 297
 
2544 hidnplayr 298
        mov     ax , [eax+1]                            ; get the pci bus and device numbers
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
3155 hidnplayr 310
        jae     .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]
3155 hidnplayr 326
        mov     cl, [eax+1]
2387 hidnplayr 327
        mov     [device.pci_bus], cl
3155 hidnplayr 328
        mov     cl, [eax+2]
2387 hidnplayr 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
 
3155 hidnplayr 339
        DEBUGF  2, "Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
2387 hidnplayr 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:
3155 hidnplayr 370
        DEBUGF  2, "Trying to find device number of already registered device\n"
2387 hidnplayr 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
3155 hidnplayr 374
        DEBUGF  2, "Kernel says: %u\n", eax
2387 hidnplayr 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:
3155 hidnplayr 383
        stdcall KernelFree, [device.rx_buffer]
2387 hidnplayr 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
 
3155 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:
3155 hidnplayr 423
        DEBUGF  2, "Probing %s device\n", my_service
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
3155 hidnplayr 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:
3155 hidnplayr 438
        cmp     al, [hw_ver_array + ecx]
2387 hidnplayr 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
3155 hidnplayr 446
        ja      .unknown
1514 hidnplayr 447
 
2387 hidnplayr 448
        mov     [device.hw_ver_id], cl
1159 hidnplayr 449
 
3155 hidnplayr 450
        mov     ecx, [crosslist+ecx*4]
2387 hidnplayr 451
        mov     [device.name], ecx
1178 hidnplayr 452
 
3155 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
3155 hidnplayr 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
3155 hidnplayr 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
3155 hidnplayr 471
        in      al, dx
2387 hidnplayr 472
        cmp     [device.hw_ver_id], IDX_RTL8139B
3155 hidnplayr 473
        jb      .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
 
3155 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
3155 hidnplayr 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
 
3155 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
 
3155 hidnplayr 500
        xor     al, al
2387 hidnplayr 501
        set_io  0
502
        set_io  REG_9346CR
3155 hidnplayr 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:
3155 hidnplayr 514
        DEBUGF  2, "Resetting\n"
1159 hidnplayr 515
 
516
; attach int handler
517
 
2387 hidnplayr 518
        movzx   eax, [device.irq_line]
3155 hidnplayr 519
        DEBUGF  1, "Attaching int handler to irq %x, ", eax:1
2387 hidnplayr 520
        stdcall AttachIntHandler, eax, int_handler, dword 0
521
        test    eax, eax
522
        jnz     @f
3155 hidnplayr 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
 
3155 hidnplayr 530
        DEBUGF  1, "Resetting chip\n"
2387 hidnplayr 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
3155 hidnplayr 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
3155 hidnplayr 554
        out     dx, eax
2387 hidnplayr 555
        set_io  REG_MAR4
3155 hidnplayr 556
        out     dx, eax
1159 hidnplayr 557
 
558
; enable Rx/Tx
559
 
3155 hidnplayr 560
        mov     al, (1 shl BIT_RE) or (1 shl BIT_TE)
2387 hidnplayr 561
        set_io  REG_COMMAND
3155 hidnplayr 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
 
3155 hidnplayr 567
        mov     ax, RX_CONFIG
2387 hidnplayr 568
        set_io  REG_RXCONFIG
3155 hidnplayr 569
        out     dx, ax
1159 hidnplayr 570
 
1472 hidnplayr 571
 
1159 hidnplayr 572
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
573
 
3155 hidnplayr 574
        mov     eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
2387 hidnplayr 575
        set_io  REG_TXCONFIG
3155 hidnplayr 576
        out     dx, eax
1159 hidnplayr 577
 
578
; enable auto negotiation
579
 
2387 hidnplayr 580
        set_io  REG_BMCR
3155 hidnplayr 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
3155 hidnplayr 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
3155 hidnplayr 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
3155 hidnplayr 604
;        out     dx, ax
1556 hidnplayr 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
3155 hidnplayr 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
3155 hidnplayr 621
        DEBUGF  2, "RX buffer: %x\n", eax
2387 hidnplayr 622
        GetRealAddr
3155 hidnplayr 623
        DEBUGF  2, "RX buffer: %x\n", eax
2387 hidnplayr 624
        set_io  REG_RBSTART
3155 hidnplayr 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
 
3155 hidnplayr 643
        DEBUGF  2, "Done!\n"
2387 hidnplayr 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:
3155 hidnplayr 660
        DEBUGF  1, "\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
2387 hidnplayr 661
        mov     eax, [esp+4]
3155 hidnplayr 662
        DEBUGF  1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2387 hidnplayr 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
2981 hidnplayr 668
        ja      .fail
2387 hidnplayr 669
        cmp     dword [esp+8], 60
2981 hidnplayr 670
        jb      .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
3155 hidnplayr 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
 
3155 hidnplayr 706
        DEBUGF  1, "Packet Sent!\n"
2387 hidnplayr 707
        xor     eax, eax
708
        ret     8
1159 hidnplayr 709
 
1519 hidnplayr 710
  .wait_to_send:
3155 hidnplayr 711
        DEBUGF  1, "Waiting for timeout\n"
1159 hidnplayr 712
 
2387 hidnplayr 713
        push    edx
2981 hidnplayr 714
        mov     esi, 30
2387 hidnplayr 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:
3155 hidnplayr 729
        DEBUGF  1, "failed!\n"
2387 hidnplayr 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
;;;;;;;;;;;;;;;;;;;;;;;
2935 hidnplayr 743
 
1159 hidnplayr 744
align 4
745
int_handler:
746
 
3155 hidnplayr 747
        DEBUGF  1, "\n%s int\n", my_service
1159 hidnplayr 748
 
749
; find pointer of device wich made IRQ occur
750
 
2387 hidnplayr 751
        mov     ecx, [devices]
752
        test    ecx, ecx
2935 hidnplayr 753
        jz      .nothing
754
        mov     esi, device_list
755
  .nextdevice:
756
        mov     ebx, [esi]
1159 hidnplayr 757
 
2387 hidnplayr 758
        set_io  0
759
        set_io  REG_ISR
2935 hidnplayr 760
        in      ax, dx
761
        out     dx, ax                              ; send it back to ACK
762
        test    ax, ax
763
        jnz     .got_it
764
  .continue:
2387 hidnplayr 765
        add     esi, 4
766
        dec     ecx
767
        jnz     .nextdevice
2935 hidnplayr 768
  .nothing:
2387 hidnplayr 769
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1159 hidnplayr 770
 
771
  .got_it:
772
 
3155 hidnplayr 773
        DEBUGF  1, "Device: %x Status: %x\n", ebx, ax
1159 hidnplayr 774
 
775
;----------------------------------------------------
776
; Received packet ok?
2935 hidnplayr 777
 
2387 hidnplayr 778
        test    ax, ISR_ROK
779
        jz      @f
780
        push    ax
1159 hidnplayr 781
 
782
  .receive:
2387 hidnplayr 783
        set_io  0
784
        set_io  REG_COMMAND
785
        in      al , dx
786
        test    al , BUFE                           ; test if RX buffer is empty
787
        jnz     .finish                             ;
1159 hidnplayr 788
 
3155 hidnplayr 789
        DEBUGF  1, "RX: "
1159 hidnplayr 790
 
2387 hidnplayr 791
        mov     eax, [device.rx_buffer]
792
        add     eax, [device.rx_data_offset]
793
        test    byte [eax], (1 shl BIT_ROK)         ; check if packet is ok
794
        jz      .reset_rx
1472 hidnplayr 795
 
796
; packet is ok, copy it
2387 hidnplayr 797
        movzx   ecx, word [eax+2]                   ; packet length
1472 hidnplayr 798
 
2387 hidnplayr 799
        sub     ecx, 4                              ; don't copy CRC
1556 hidnplayr 800
 
1472 hidnplayr 801
; Update stats
2387 hidnplayr 802
        add     dword [device.bytes_rx], ecx
803
        adc     dword [device.bytes_rx + 4], 0
804
        inc     dword [device.packets_rx]
1472 hidnplayr 805
 
3155 hidnplayr 806
        DEBUGF  1, "Received %u bytes\n", ecx
1159 hidnplayr 807
 
2387 hidnplayr 808
        push    ebx eax ecx
809
        stdcall KernelAlloc, ecx                    ; Allocate a buffer to put packet into
810
        pop     ecx
811
        test    eax, eax                            ; Test if we allocated succesfully
812
        jz      .abort
1159 hidnplayr 813
 
2387 hidnplayr 814
        mov     edi, eax                            ; Where we will copy too
1472 hidnplayr 815
 
2387 hidnplayr 816
        mov     esi, [esp]                          ; The buffer we will copy from
817
        add     esi, 4                              ; Dont copy CRC
1159 hidnplayr 818
 
2387 hidnplayr 819
        push    dword .abort                        ; Kernel will return to this address after EthReceiver
820
        push    ecx edi                             ; Save buffer pointer and size, to pass to kernel
1159 hidnplayr 821
 
1472 hidnplayr 822
  .copy:
2387 hidnplayr 823
        shr     ecx, 1
824
        jnc     .nb
825
        movsb
1472 hidnplayr 826
  .nb:
2387 hidnplayr 827
        shr     ecx, 1
828
        jnc     .nw
829
        movsw
1472 hidnplayr 830
  .nw:
2387 hidnplayr 831
        jz      .nd
832
        rep     movsd
1472 hidnplayr 833
  .nd:
1159 hidnplayr 834
 
2981 hidnplayr 835
        jmp     Eth_input                           ; Send it to kernel
1159 hidnplayr 836
 
837
  .abort:
2387 hidnplayr 838
        pop     eax ebx
839
                                                    ; update eth_data_start_offset
840
        movzx   eax, word [eax+2]                   ; packet length
841
        add     eax, [device.rx_data_offset]
842
        add     eax, 4+3                            ; packet header is 4 bytes long + dword alignment
843
        and     eax, not 3                          ; dword alignment
1472 hidnplayr 844
 
2387 hidnplayr 845
        cmp     eax, RX_BUFFER_SIZE
3155 hidnplayr 846
        jb      .no_wrap
847
        DEBUGF  2, "Wrapping"
2387 hidnplayr 848
        sub     eax, RX_BUFFER_SIZE
1159 hidnplayr 849
  .no_wrap:
2387 hidnplayr 850
        mov     [device.rx_data_offset], eax
3155 hidnplayr 851
        DEBUGF  1, "New RX ptr: %d\n", eax
1159 hidnplayr 852
 
2387 hidnplayr 853
        set_io  0
854
        set_io  REG_CAPR                            ; update 'Current Address of Packet Read register'
855
        sub     eax, 0x10                           ; value 0x10 is a constant for CAPR
856
        out     dx , ax
1159 hidnplayr 857
 
2387 hidnplayr 858
        jmp     .receive                            ; check for multiple packets
1159 hidnplayr 859
 
860
  .reset_rx:
2387 hidnplayr 861
        test    byte [eax], (1 shl BIT_CRC)
862
        jz      .no_crc_error
3155 hidnplayr 863
        DEBUGF  2, "\nCRC error!\n"
1159 hidnplayr 864
 
865
  .no_crc_error:
2387 hidnplayr 866
        test    byte [eax], (1 shl BIT_FAE)
867
        jz      .no_fae_error
3155 hidnplayr 868
        DEBUGF  1, "\nFrame alignment error!\n"
1159 hidnplayr 869
 
870
  .no_fae_error:
3155 hidnplayr 871
        DEBUGF  1, "Reset RX\n"
872
        in      al, dx                              ; read command register
2387 hidnplayr 873
        push    ax
1159 hidnplayr 874
 
3155 hidnplayr 875
        and     al, not (1 shl BIT_RE)              ; Clear the RE bit
876
        out     dx, al
1159 hidnplayr 877
 
2387 hidnplayr 878
        pop     ax
3155 hidnplayr 879
        out     dx, al                              ; write original command back
1159 hidnplayr 880
 
2387 hidnplayr 881
        add     edx, REG_RXCONFIG - REG_COMMAND     ; Restore RX configuration
3155 hidnplayr 882
        mov     ax, RX_CONFIG
883
        out     dx, ax
1159 hidnplayr 884
 
885
  .finish:
2387 hidnplayr 886
        pop     ax
1159 hidnplayr 887
 
888
;----------------------------------------------------
1556 hidnplayr 889
; Transmit ok / Transmit error
1159 hidnplayr 890
  @@:
2387 hidnplayr 891
        test    ax, ISR_TOK + ISR_TER
892
        jz      @f
1159 hidnplayr 893
 
2387 hidnplayr 894
        push    ax
3155 hidnplayr 895
        mov     ecx, (NUM_TX_DESC-1)*4
896
  .txdescloop:
2387 hidnplayr 897
        set_io  0
898
        set_io  REG_TSD0
899
        add     edx, ecx
900
        in      eax, dx
1541 hidnplayr 901
 
2387 hidnplayr 902
        test    eax, TSR_OWN                    ; DMA operation completed
903
        jz      .notthisone
1556 hidnplayr 904
 
2387 hidnplayr 905
        cmp     [device.TX_DESC+ecx], 0
906
        je      .notthisone
1556 hidnplayr 907
 
1519 hidnplayr 908
;  .notxd:
909
;        test    eax, TSR_TUN
910
;        jz      .nobun
911
;        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
912
;
913
;  .nobun:
914
;        test    eax, TSR_OWC
915
;        jz      .noowc
916
;        DEBUGF  2, "TX: OWC!\n"
917
;
918
;  .noowc:
919
;        test    eax, TSR_TABT
920
;        jz      .notabt
921
;        DEBUGF  2, "TX: TABT!\n"
922
;
923
;  .notabt:
924
;        test    eax, TSR_CRS
925
;        jz      .nocsl
926
;        DEBUGF  2, "TX: Carrier Sense Lost!\n"
927
;
928
;  .nocsl:
929
 
3155 hidnplayr 930
        DEBUGF  1, "TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8
2387 hidnplayr 931
        push    ecx ebx
932
        stdcall KernelFree, [device.TX_DESC+ecx]
933
        pop     ebx ecx
934
        mov     [device.TX_DESC+ecx], 0
1556 hidnplayr 935
 
1519 hidnplayr 936
  .notthisone:
3155 hidnplayr 937
        sub     ecx, 4
938
        ja      .txdescloop
2387 hidnplayr 939
        pop     ax
1159 hidnplayr 940
 
941
;----------------------------------------------------
942
; Rx buffer overflow ?
943
  @@:
2387 hidnplayr 944
        test    ax, ISR_RXOVW
945
        jz      @f
1159 hidnplayr 946
 
2387 hidnplayr 947
        push    ax
3155 hidnplayr 948
        DEBUGF  2, "RX-buffer overflow!\n"
1159 hidnplayr 949
 
2387 hidnplayr 950
        set_io  0
951
        set_io  REG_ISR
3155 hidnplayr 952
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
953
        out     dx, ax
2387 hidnplayr 954
        pop     ax
1159 hidnplayr 955
 
956
;----------------------------------------------------
1519 hidnplayr 957
; Packet underrun?
1159 hidnplayr 958
  @@:
2387 hidnplayr 959
        test    ax, ISR_PUN
960
        jz      @f
1159 hidnplayr 961
 
3155 hidnplayr 962
        DEBUGF  2, "Packet underrun!\n"
1159 hidnplayr 963
 
964
;----------------------------------------------------
965
; Receive FIFO overflow ?
966
  @@:
2387 hidnplayr 967
        test    ax, ISR_FIFOOVW
968
        jz      @f
1159 hidnplayr 969
 
2387 hidnplayr 970
        push    ax
3155 hidnplayr 971
        DEBUGF  2, "RX fifo overflow!\n"
1159 hidnplayr 972
 
2387 hidnplayr 973
        set_io  0
974
        set_io  REG_ISR
3155 hidnplayr 975
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
976
        out     dx, ax
2387 hidnplayr 977
        pop     ax
1159 hidnplayr 978
 
979
;----------------------------------------------------
980
; Something about Cable changed ?
981
  @@:
2387 hidnplayr 982
        test    ax, ISR_LENCHG
983
        jz      .fail
1159 hidnplayr 984
 
3155 hidnplayr 985
        DEBUGF  2, "Cable changed!\n"
2387 hidnplayr 986
        call    cable
1159 hidnplayr 987
 
988
  .fail:
3155 hidnplayr 989
        DEBUGF  2, "\n"
2387 hidnplayr 990
        ret
1159 hidnplayr 991
 
992
 
993
 
994
 
995
;;;;;;;;;;;;;;;;;;;;;;;;;
996
;;                     ;;
997
;; Update Cable status ;;
998
;;                     ;;
999
;;;;;;;;;;;;;;;;;;;;;;;;;
1000
 
1001
align 4
1002
cable:
3155 hidnplayr 1003
        DEBUGF  1, "Checking Cable status: "
1159 hidnplayr 1004
 
2387 hidnplayr 1005
        mov     edx, dword [device.io_addr]
1006
        add     edx, REG_MSR
1007
        in      al , dx
1159 hidnplayr 1008
 
1009
;        test    al , 1 SHL 2     ; 0 = link ok 1 = link fail
1010
;        jnz     .notconnected
1011
 
1012
;        test    al , 1 SHL 3     ; 0 = 100 Mbps 1 = 10 Mbps
1013
;        jnz     .10mbps
1014
 
2387 hidnplayr 1015
        shr     al, 2
1016
        and     al, 3
1159 hidnplayr 1017
 
2387 hidnplayr 1018
        mov     byte [device.mode+3], al
3155 hidnplayr 1019
        DEBUGF  1, "Done!\n"
1159 hidnplayr 1020
ret
1021
 
1022
 
1023
 
1024
;;;;;;;;;;;;;;;;;;;;;;;
1025
;;                   ;;
1026
;; Write MAC address ;;
1027
;;                   ;;
1028
;;;;;;;;;;;;;;;;;;;;;;;
1029
 
1030
align 4
2387 hidnplayr 1031
write_mac:      ; in: mac pushed onto stack (as 3 words)
1159 hidnplayr 1032
 
3155 hidnplayr 1033
        DEBUGF  2, "Writing MAC: "
1159 hidnplayr 1034
 
1035
; disable all in command registers
1036
 
2387 hidnplayr 1037
        set_io  0
1038
        set_io  REG_9346CR
1039
        xor     eax, eax
3155 hidnplayr 1040
        out     dx, al
1159 hidnplayr 1041
 
2387 hidnplayr 1042
        set_io  REG_IMR
1043
        xor     eax, eax
3155 hidnplayr 1044
        out     dx, ax
1159 hidnplayr 1045
 
2387 hidnplayr 1046
        set_io  REG_ISR
1047
        mov     eax, -1
3155 hidnplayr 1048
        out     dx, ax
1159 hidnplayr 1049
 
1050
; enable writing
1051
 
2387 hidnplayr 1052
        set_io  REG_9346CR
1053
        mov     eax, REG_9346CR_WE
3155 hidnplayr 1054
        out     dx, al
1159 hidnplayr 1055
 
1056
 ; write the mac ...
1057
 
2387 hidnplayr 1058
        set_io  REG_IDR0
1059
        pop     eax
3155 hidnplayr 1060
        out     dx, eax
1159 hidnplayr 1061
 
2387 hidnplayr 1062
        set_io  REG_IDR0+4
1063
        xor     eax, eax
1064
        pop     ax
3155 hidnplayr 1065
        out     dx, eax
1159 hidnplayr 1066
 
1067
; disable writing
1068
 
2387 hidnplayr 1069
        set_io  REG_9346CR
1070
        xor     eax, eax
3155 hidnplayr 1071
        out     dx, al
1159 hidnplayr 1072
 
3155 hidnplayr 1073
        DEBUGF  2, "ok!\n"
1159 hidnplayr 1074
 
1075
; Notice this procedure does not ret, but continues to read_mac instead.
1076
 
1077
 
1078
;;;;;;;;;;;;;;;;;;;;;;
1079
;;                  ;;
1080
;; Read MAC address ;;
1081
;;                  ;;
1082
;;;;;;;;;;;;;;;;;;;;;;
1083
 
1084
read_mac:
3155 hidnplayr 1085
        DEBUGF  2, "Reading MAC: "
1159 hidnplayr 1086
 
2387 hidnplayr 1087
        set_io  0
1088
        lea     edi, [device.mac]
1089
        in      eax, dx
1090
        stosd
1091
        add     edx, 4
1092
        in      ax, dx
1093
        stosw
1159 hidnplayr 1094
 
3155 hidnplayr 1095
        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 1096
 
2387 hidnplayr 1097
        ret
1159 hidnplayr 1098
 
1099
 
1100
; End of code
1101
 
1519 hidnplayr 1102
section '.data' data readable writable align 16 ; place all uninitialized data place here
2387 hidnplayr 1103
align 4                                         ; Place all initialised data here
1159 hidnplayr 1104
 
2387 hidnplayr 1105
devices         dd 0
1106
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1107
my_service      db 'RTL8139',0                    ; max 16 chars include zero
1159 hidnplayr 1108
 
2387 hidnplayr 1109
device_1        db 'Realtek 8139',0
1110
device_2        db 'Realtek 8139A',0
1111
device_3        db 'Realtek 8139B',0
1112
device_4        db 'Realtek 8139C',0
1113
device_5        db 'Realtek 8100',0
1114
device_6        db 'Realtek 8139D',0
1115
device_7        db 'Realtek 8139CP',0
1116
device_8        db 'Realtek 8101',0
1117
device_unknown  db 'Unknown RTL8139 clone', 0
1178 hidnplayr 1118
 
1519 hidnplayr 1119
crosslist:
2387 hidnplayr 1120
        dd device_1
1121
        dd device_2
1122
        dd device_3
1123
        dd device_4
1124
        dd device_5
1125
        dd device_6
1126
        dd device_7
1127
        dd device_8
1128
        dd device_unknown
1178 hidnplayr 1129
 
2387 hidnplayr 1130
hw_ver_array:                    ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1131
        db VER_RTL8139
1132
        db VER_RTL8139A
1133
        db VER_RTL8139B
1134
        db VER_RTL8139C
1135
        db VER_RTL8100
1136
        db VER_RTL8139D
1137
        db VER_RTL8139CP
1138
        db VER_RTL8101
1139
        db 0
1159 hidnplayr 1140
 
1141
HW_VER_ARRAY_SIZE = $-hw_ver_array
1142
 
2387 hidnplayr 1143
include_debug_strings                           ; All data wich FDO uses will be included here
1159 hidnplayr 1144
 
2387 hidnplayr 1145
device_list     rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling
1159 hidnplayr 1146