Subversion Repositories Kolibri OS

Rev

Rev 3155 | Go to most recent revision | Details | Compare with Previous | 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 ?
3205 hidnplayr 211
        .pci_bus        dd ?
212
        .pci_dev        dd ?
2387 hidnplayr 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]
3205 hidnplayr 301
        cmp     al, byte[device.pci_bus]
302
        jne     @f
303
        cmp     ah, byte[device.pci_dev]
2387 hidnplayr 304
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
3205 hidnplayr 305
       @@:
2387 hidnplayr 306
        add     esi, 4
307
        loop    .nextdevice
1159 hidnplayr 308
 
1472 hidnplayr 309
 
1159 hidnplayr 310
; This device doesnt have its own eth_device structure yet, lets create one
311
  .firstdevice:
2387 hidnplayr 312
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
3155 hidnplayr 313
        jae     .fail
1159 hidnplayr 314
 
2387 hidnplayr 315
        allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
1159 hidnplayr 316
 
317
; Fill in the direct call addresses into the struct
318
 
2387 hidnplayr 319
        mov     [device.reset], reset
320
        mov     [device.transmit], transmit
321
        mov     [device.get_MAC], read_mac
322
        mov     [device.set_MAC], write_mac
323
        mov     [device.unload], unload
324
        mov     [device.name], my_service
1159 hidnplayr 325
 
326
; save the pci bus and device numbers
327
 
2387 hidnplayr 328
        mov     eax, [IOCTL.input]
3205 hidnplayr 329
        movzx   ecx, byte[eax+1]
330
        mov     [device.pci_bus], ecx
331
        movzx   ecx, byte[eax+2]
332
        mov     [device.pci_dev], ecx
1159 hidnplayr 333
 
334
; Now, it's time to find the base io addres of the PCI device
335
 
3205 hidnplayr 336
        PCI_find_io
1159 hidnplayr 337
 
338
; We've found the io address, find IRQ now
339
 
3205 hidnplayr 340
        PCI_find_irq
1159 hidnplayr 341
 
3155 hidnplayr 342
        DEBUGF  2, "Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
2387 hidnplayr 343
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1159 hidnplayr 344
 
1556 hidnplayr 345
; Allocate the receive buffer
1159 hidnplayr 346
 
2387 hidnplayr 347
        stdcall CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW
348
        test    eax, eax
349
        jz      .err
350
        mov     [device.rx_buffer], eax
1159 hidnplayr 351
 
352
; Ok, the eth_device structure is ready, let's probe the device
353
 
2387 hidnplayr 354
        call    probe                                                   ; this function will output in eax
355
        test    eax, eax
356
        jnz     .err                                                    ; If an error occured, exit
1159 hidnplayr 357
 
2387 hidnplayr 358
        mov     eax, [devices]                                          ; Add the device structure to our device list
359
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
360
        inc     [devices]                                               ;
1159 hidnplayr 361
 
2387 hidnplayr 362
        mov     [device.type], NET_TYPE_ETH
363
        call    NetRegDev
1514 hidnplayr 364
 
2387 hidnplayr 365
        cmp     eax, -1
366
        je      .destroy
1159 hidnplayr 367
 
2387 hidnplayr 368
        ret
1159 hidnplayr 369
 
370
; If the device was already loaded, find the device number and return it in eax
371
 
372
  .find_devicenum:
3155 hidnplayr 373
        DEBUGF  2, "Trying to find device number of already registered device\n"
2387 hidnplayr 374
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
375
                                                                        ; into a device number in edi
376
        mov     eax, edi                                                ; Application wants it in eax instead
3155 hidnplayr 377
        DEBUGF  2, "Kernel says: %u\n", eax
2387 hidnplayr 378
        ret
1159 hidnplayr 379
 
380
; If an error occured, remove all allocated data and exit (returning -1 in eax)
381
 
382
  .destroy:
2387 hidnplayr 383
        ; todo: reset device into virgin state
1159 hidnplayr 384
 
385
  .err:
3155 hidnplayr 386
        stdcall KernelFree, [device.rx_buffer]
2387 hidnplayr 387
        stdcall KernelFree, ebx
1159 hidnplayr 388
 
389
  .fail:
2387 hidnplayr 390
        or      eax, -1
391
        ret
1159 hidnplayr 392
 
393
;------------------------------------------------------
394
endp
395
 
396
 
397
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
398
;;                                                                        ;;
399
;;        Actual Hardware dependent code starts here                      ;;
400
;;                                                                        ;;
401
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
402
 
403
align 4
404
unload:
2387 hidnplayr 405
        ; TODO: (in this particular order)
406
        ;
407
        ; - Stop the device
408
        ; - Detach int handler
409
        ; - Remove device from local list (RTL8139_LIST)
410
        ; - call unregister function in kernel
411
        ; - Remove all allocated structures and buffers the card used
1159 hidnplayr 412
 
3155 hidnplayr 413
        or      eax, -1
1159 hidnplayr 414
 
415
ret
416
 
417
 
418
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
419
;;
420
;;  probe: enables the device (if it really is RTL8139)
421
;;
422
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
423
 
424
align 4
425
probe:
3155 hidnplayr 426
        DEBUGF  2, "Probing %s device\n", my_service
1159 hidnplayr 427
 
3205 hidnplayr 428
        PCI_make_bus_master
1159 hidnplayr 429
 
430
; get chip version
431
 
2387 hidnplayr 432
        set_io  0
433
        set_io  REG_TXCONFIG + 2
3155 hidnplayr 434
        in      ax, dx
435
        shr     ah, 2
436
        shr     ax, 6
437
        and     al, 01111111b
1514 hidnplayr 438
 
2387 hidnplayr 439
        mov     ecx, HW_VER_ARRAY_SIZE-1
1159 hidnplayr 440
  .chip_ver_loop:
3155 hidnplayr 441
        cmp     al, [hw_ver_array + ecx]
2387 hidnplayr 442
        je      .chip_ver_found
443
        dec     ecx
444
        jns     .chip_ver_loop
1514 hidnplayr 445
  .unknown:
2387 hidnplayr 446
        mov     ecx, 8
1159 hidnplayr 447
  .chip_ver_found:
2387 hidnplayr 448
        cmp     ecx, 8
3155 hidnplayr 449
        ja      .unknown
1514 hidnplayr 450
 
2387 hidnplayr 451
        mov     [device.hw_ver_id], cl
1159 hidnplayr 452
 
3155 hidnplayr 453
        mov     ecx, [crosslist+ecx*4]
2387 hidnplayr 454
        mov     [device.name], ecx
1178 hidnplayr 455
 
3155 hidnplayr 456
        DEBUGF  2, "Chip version: %s\n", ecx
1178 hidnplayr 457
 
1159 hidnplayr 458
; wake up the chip
459
 
2387 hidnplayr 460
        set_io  0
461
        set_io  REG_HLTCLK
3155 hidnplayr 462
        mov     al, 'R'         ; run the clock
463
        out     dx, al
1159 hidnplayr 464
 
465
; unlock config and BMCR registers
466
 
2387 hidnplayr 467
        set_io  REG_9346CR
3155 hidnplayr 468
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
469
        out     dx, al
1159 hidnplayr 470
 
471
; enable power management
472
 
2387 hidnplayr 473
        set_io  REG_CONFIG1
3155 hidnplayr 474
        in      al, dx
2387 hidnplayr 475
        cmp     [device.hw_ver_id], IDX_RTL8139B
3155 hidnplayr 476
        jb      .old_chip
1159 hidnplayr 477
 
478
; set LWAKE pin to active high (default value).
479
; it is for Wake-On-LAN functionality of some motherboards.
480
; this signal is used to inform the motherboard to execute a wake-up process.
481
; only at newer chips.
482
 
3155 hidnplayr 483
        or      al, (1 shl BIT_PMEn)
484
        and     al, not (1 shl BIT_LWACT)
485
        out     dx, al
1472 hidnplayr 486
 
2387 hidnplayr 487
        set_io  REG_CONFIG4
3155 hidnplayr 488
        in      al, dx
489
        and     al, not (1 shl BIT_LWPTN)
490
        out     dx, al
1472 hidnplayr 491
 
2387 hidnplayr 492
        jmp     .finish_wake_up
1159 hidnplayr 493
  .old_chip:
494
 
495
; wake up older chips
496
 
3155 hidnplayr 497
        and     al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
498
        out     dx, al
1159 hidnplayr 499
  .finish_wake_up:
500
 
501
; lock config and BMCR registers
502
 
3155 hidnplayr 503
        xor     al, al
2387 hidnplayr 504
        set_io  0
505
        set_io  REG_9346CR
3155 hidnplayr 506
        out     dx, al
507
        DEBUGF  2, "done!\n"
1159 hidnplayr 508
 
509
 
510
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
511
;;
512
;;   reset: Set up all registers and descriptors, clear some values
513
;;
514
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
515
 
516
reset:
3155 hidnplayr 517
        DEBUGF  2, "Resetting\n"
1159 hidnplayr 518
 
519
; attach int handler
520
 
2387 hidnplayr 521
        movzx   eax, [device.irq_line]
3155 hidnplayr 522
        DEBUGF  1, "Attaching int handler to irq %x, ", eax:1
2387 hidnplayr 523
        stdcall AttachIntHandler, eax, int_handler, dword 0
524
        test    eax, eax
525
        jnz     @f
3155 hidnplayr 526
        DEBUGF  1, "\nCould not attach int handler!\n"
1159 hidnplayr 527
;        or      eax, -1
528
;        ret
1519 hidnplayr 529
       @@:
1159 hidnplayr 530
 
531
; reset chip
532
 
3155 hidnplayr 533
        DEBUGF  1, "Resetting chip\n"
2387 hidnplayr 534
        set_io  0
535
        set_io  REG_COMMAND
536
        mov     al , 1 shl BIT_RST
537
        out     dx , al
538
        mov     cx , 1000               ; wait no longer for the reset
1159 hidnplayr 539
  .wait_for_reset:
2387 hidnplayr 540
        in      al , dx
541
        test    al , 1 shl BIT_RST
542
        jz      .reset_completed        ; RST remains 1 during reset
543
        dec     cx
544
        jns     .wait_for_reset
1159 hidnplayr 545
  .reset_completed:
546
 
547
; unlock config and BMCR registers
548
 
2387 hidnplayr 549
        set_io  REG_9346CR
3155 hidnplayr 550
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
551
        out     dx, al
1159 hidnplayr 552
 
553
; initialize multicast registers (no filtering)
554
 
2387 hidnplayr 555
        mov     eax, 0xffffffff
556
        set_io  REG_MAR0
3155 hidnplayr 557
        out     dx, eax
2387 hidnplayr 558
        set_io  REG_MAR4
3155 hidnplayr 559
        out     dx, eax
1159 hidnplayr 560
 
561
; enable Rx/Tx
562
 
3155 hidnplayr 563
        mov     al, (1 shl BIT_RE) or (1 shl BIT_TE)
2387 hidnplayr 564
        set_io  REG_COMMAND
3155 hidnplayr 565
        out     dx, al
1159 hidnplayr 566
 
1556 hidnplayr 567
; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold
1159 hidnplayr 568
; accept broadcast packets, accept physical match packets
569
 
3155 hidnplayr 570
        mov     ax, RX_CONFIG
2387 hidnplayr 571
        set_io  REG_RXCONFIG
3155 hidnplayr 572
        out     dx, ax
1159 hidnplayr 573
 
1472 hidnplayr 574
 
1159 hidnplayr 575
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
576
 
3155 hidnplayr 577
        mov     eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
2387 hidnplayr 578
        set_io  REG_TXCONFIG
3155 hidnplayr 579
        out     dx, eax
1159 hidnplayr 580
 
581
; enable auto negotiation
582
 
2387 hidnplayr 583
        set_io  REG_BMCR
3155 hidnplayr 584
        in      ax, dx
585
        or      ax, (1 shl BIT_ANE)
586
        out     dx, ax
1159 hidnplayr 587
 
588
; set auto negotiation advertisement
589
 
2387 hidnplayr 590
        set_io  REG_ANAR
3155 hidnplayr 591
        in      ax, dx
592
        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)
593
        out     dx, ax
1159 hidnplayr 594
 
595
; lock config and BMCR registers
596
 
2387 hidnplayr 597
        xor     eax, eax
598
        set_io  REG_9346CR
3155 hidnplayr 599
        out     dx, al
1159 hidnplayr 600
 
601
; init RX/TX pointers
602
 
2387 hidnplayr 603
        mov     [device.rx_data_offset], eax
604
        mov     [device.curr_tx_desc], al
1159 hidnplayr 605
 
1556 hidnplayr 606
;        set_io  REG_CAPR
3155 hidnplayr 607
;        out     dx, ax
1556 hidnplayr 608
 
1171 hidnplayr 609
; clear packet/byte counters
610
 
2387 hidnplayr 611
        lea     edi, [device.bytes_tx]
612
        mov     ecx, 6
613
        rep     stosd
1171 hidnplayr 614
 
1159 hidnplayr 615
; clear missing packet counter
616
 
2387 hidnplayr 617
        set_io  REG_MPC
3155 hidnplayr 618
        out     dx, eax
1159 hidnplayr 619
 
1472 hidnplayr 620
; set RxBuffer address, init RX buffer offset
1159 hidnplayr 621
 
2387 hidnplayr 622
        mov     eax, [device.rx_buffer]
623
        mov     dword[eax], 0
3155 hidnplayr 624
        DEBUGF  2, "RX buffer: %x\n", eax
2387 hidnplayr 625
        GetRealAddr
3155 hidnplayr 626
        DEBUGF  2, "RX buffer: %x\n", eax
2387 hidnplayr 627
        set_io  REG_RBSTART
3155 hidnplayr 628
        out     dx, eax
1159 hidnplayr 629
 
1541 hidnplayr 630
; Read MAC address
631
 
2387 hidnplayr 632
        call    read_mac
1541 hidnplayr 633
 
1159 hidnplayr 634
; enable interrupts
635
 
2387 hidnplayr 636
        set_io  0
637
        set_io  REG_IMR
638
        mov     eax, INTERRUPT_MASK
639
        out     dx , ax
1159 hidnplayr 640
 
1519 hidnplayr 641
; Set the mtu, kernel will be able to send now
2387 hidnplayr 642
        mov     [device.mtu], 1514
1519 hidnplayr 643
 
1159 hidnplayr 644
; Indicate that we have successfully reset the card
645
 
3155 hidnplayr 646
        DEBUGF  2, "Done!\n"
2387 hidnplayr 647
        xor     eax, eax
1159 hidnplayr 648
 
2387 hidnplayr 649
        ret
1159 hidnplayr 650
 
651
 
652
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
653
;;                                         ;;
654
;; Transmit                                ;;
655
;;                                         ;;
1254 hidnplayr 656
;; In: buffer pointer in [esp+4]           ;;
657
;;     size of buffer in [esp+8]           ;;
1159 hidnplayr 658
;;     pointer to device structure in ebx  ;;
659
;;                                         ;;
660
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661
align 4
662
transmit:
3155 hidnplayr 663
        DEBUGF  1, "\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
2387 hidnplayr 664
        mov     eax, [esp+4]
3155 hidnplayr 665
        DEBUGF  1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2387 hidnplayr 666
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
667
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
668
        [eax+13]:2,[eax+12]:2
1159 hidnplayr 669
 
2387 hidnplayr 670
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
2981 hidnplayr 671
        ja      .fail
2387 hidnplayr 672
        cmp     dword [esp+8], 60
2981 hidnplayr 673
        jb      .fail
1159 hidnplayr 674
 
1556 hidnplayr 675
; check if we own the current discriptor
2387 hidnplayr 676
        set_io  0
677
        set_io  REG_TSD0
678
        movzx   ecx, [device.curr_tx_desc]
679
        shl     ecx, 2
680
        add     edx, ecx
681
        in      eax, dx
682
        test    eax, (1 shl BIT_OWN)
683
        jz      .wait_to_send
1159 hidnplayr 684
 
1519 hidnplayr 685
  .send_packet:
1556 hidnplayr 686
; get next descriptor
2387 hidnplayr 687
        inc     [device.curr_tx_desc]
688
        and     [device.curr_tx_desc], NUM_TX_DESC-1
1556 hidnplayr 689
 
690
; Update stats
2387 hidnplayr 691
        inc     [device.packets_tx]
692
        mov     eax, [esp+8]
693
        add     dword [device.bytes_tx], eax
3155 hidnplayr 694
        adc     dword [device.bytes_tx+4], 0
1556 hidnplayr 695
 
1519 hidnplayr 696
; Set the buffer address
2387 hidnplayr 697
        set_io  REG_TSAD0
698
        mov     eax, [esp+4]
699
        mov     [device.TX_DESC+ecx], eax
700
        GetRealAddr
701
        out     dx, eax
1159 hidnplayr 702
 
1519 hidnplayr 703
; And the size of the buffer
2387 hidnplayr 704
        set_io  REG_TSD0
705
        mov     eax, [esp+8]
706
        or      eax, (ERTXTH shl BIT_ERTXTH)    ; Early threshold
707
        out     dx, eax
1159 hidnplayr 708
 
3155 hidnplayr 709
        DEBUGF  1, "Packet Sent!\n"
2387 hidnplayr 710
        xor     eax, eax
711
        ret     8
1159 hidnplayr 712
 
1519 hidnplayr 713
  .wait_to_send:
3155 hidnplayr 714
        DEBUGF  1, "Waiting for timeout\n"
1159 hidnplayr 715
 
2387 hidnplayr 716
        push    edx
2981 hidnplayr 717
        mov     esi, 30
2387 hidnplayr 718
        stdcall Sleep
719
        pop     edx
1159 hidnplayr 720
 
2387 hidnplayr 721
        in      ax, dx
722
        test    ax, (1 shl BIT_OWN)
723
        jnz     .send_packet
1159 hidnplayr 724
 
2387 hidnplayr 725
        pusha
726
        call    reset                            ; if chip hung, reset it
727
        popa
1519 hidnplayr 728
 
2387 hidnplayr 729
        jmp     .send_packet
1519 hidnplayr 730
 
731
  .fail:
3155 hidnplayr 732
        DEBUGF  1, "failed!\n"
2387 hidnplayr 733
        stdcall KernelFree, [esp+4]
734
        or      eax, -1
735
        ret     8
1519 hidnplayr 736
 
737
 
738
 
739
 
740
 
1159 hidnplayr 741
;;;;;;;;;;;;;;;;;;;;;;;
742
;;                   ;;
743
;; Interrupt handler ;;
744
;;                   ;;
745
;;;;;;;;;;;;;;;;;;;;;;;
2935 hidnplayr 746
 
1159 hidnplayr 747
align 4
748
int_handler:
749
 
3155 hidnplayr 750
        DEBUGF  1, "\n%s int\n", my_service
1159 hidnplayr 751
 
752
; find pointer of device wich made IRQ occur
753
 
2387 hidnplayr 754
        mov     ecx, [devices]
755
        test    ecx, ecx
2935 hidnplayr 756
        jz      .nothing
757
        mov     esi, device_list
758
  .nextdevice:
759
        mov     ebx, [esi]
1159 hidnplayr 760
 
2387 hidnplayr 761
        set_io  0
762
        set_io  REG_ISR
2935 hidnplayr 763
        in      ax, dx
764
        out     dx, ax                              ; send it back to ACK
765
        test    ax, ax
766
        jnz     .got_it
767
  .continue:
2387 hidnplayr 768
        add     esi, 4
769
        dec     ecx
770
        jnz     .nextdevice
2935 hidnplayr 771
  .nothing:
2387 hidnplayr 772
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1159 hidnplayr 773
 
774
  .got_it:
775
 
3155 hidnplayr 776
        DEBUGF  1, "Device: %x Status: %x\n", ebx, ax
1159 hidnplayr 777
 
778
;----------------------------------------------------
779
; Received packet ok?
2935 hidnplayr 780
 
2387 hidnplayr 781
        test    ax, ISR_ROK
782
        jz      @f
783
        push    ax
1159 hidnplayr 784
 
785
  .receive:
2387 hidnplayr 786
        set_io  0
787
        set_io  REG_COMMAND
788
        in      al , dx
789
        test    al , BUFE                           ; test if RX buffer is empty
790
        jnz     .finish                             ;
1159 hidnplayr 791
 
3155 hidnplayr 792
        DEBUGF  1, "RX: "
1159 hidnplayr 793
 
2387 hidnplayr 794
        mov     eax, [device.rx_buffer]
795
        add     eax, [device.rx_data_offset]
796
        test    byte [eax], (1 shl BIT_ROK)         ; check if packet is ok
797
        jz      .reset_rx
1472 hidnplayr 798
 
799
; packet is ok, copy it
2387 hidnplayr 800
        movzx   ecx, word [eax+2]                   ; packet length
1472 hidnplayr 801
 
2387 hidnplayr 802
        sub     ecx, 4                              ; don't copy CRC
1556 hidnplayr 803
 
1472 hidnplayr 804
; Update stats
2387 hidnplayr 805
        add     dword [device.bytes_rx], ecx
806
        adc     dword [device.bytes_rx + 4], 0
807
        inc     dword [device.packets_rx]
1472 hidnplayr 808
 
3155 hidnplayr 809
        DEBUGF  1, "Received %u bytes\n", ecx
1159 hidnplayr 810
 
2387 hidnplayr 811
        push    ebx eax ecx
812
        stdcall KernelAlloc, ecx                    ; Allocate a buffer to put packet into
813
        pop     ecx
814
        test    eax, eax                            ; Test if we allocated succesfully
815
        jz      .abort
1159 hidnplayr 816
 
2387 hidnplayr 817
        mov     edi, eax                            ; Where we will copy too
1472 hidnplayr 818
 
2387 hidnplayr 819
        mov     esi, [esp]                          ; The buffer we will copy from
820
        add     esi, 4                              ; Dont copy CRC
1159 hidnplayr 821
 
2387 hidnplayr 822
        push    dword .abort                        ; Kernel will return to this address after EthReceiver
823
        push    ecx edi                             ; Save buffer pointer and size, to pass to kernel
1159 hidnplayr 824
 
1472 hidnplayr 825
  .copy:
2387 hidnplayr 826
        shr     ecx, 1
827
        jnc     .nb
828
        movsb
1472 hidnplayr 829
  .nb:
2387 hidnplayr 830
        shr     ecx, 1
831
        jnc     .nw
832
        movsw
1472 hidnplayr 833
  .nw:
2387 hidnplayr 834
        jz      .nd
835
        rep     movsd
1472 hidnplayr 836
  .nd:
1159 hidnplayr 837
 
2981 hidnplayr 838
        jmp     Eth_input                           ; Send it to kernel
1159 hidnplayr 839
 
840
  .abort:
2387 hidnplayr 841
        pop     eax ebx
842
                                                    ; update eth_data_start_offset
843
        movzx   eax, word [eax+2]                   ; packet length
844
        add     eax, [device.rx_data_offset]
845
        add     eax, 4+3                            ; packet header is 4 bytes long + dword alignment
846
        and     eax, not 3                          ; dword alignment
1472 hidnplayr 847
 
2387 hidnplayr 848
        cmp     eax, RX_BUFFER_SIZE
3155 hidnplayr 849
        jb      .no_wrap
850
        DEBUGF  2, "Wrapping"
2387 hidnplayr 851
        sub     eax, RX_BUFFER_SIZE
1159 hidnplayr 852
  .no_wrap:
2387 hidnplayr 853
        mov     [device.rx_data_offset], eax
3155 hidnplayr 854
        DEBUGF  1, "New RX ptr: %d\n", eax
1159 hidnplayr 855
 
2387 hidnplayr 856
        set_io  0
857
        set_io  REG_CAPR                            ; update 'Current Address of Packet Read register'
858
        sub     eax, 0x10                           ; value 0x10 is a constant for CAPR
859
        out     dx , ax
1159 hidnplayr 860
 
2387 hidnplayr 861
        jmp     .receive                            ; check for multiple packets
1159 hidnplayr 862
 
863
  .reset_rx:
2387 hidnplayr 864
        test    byte [eax], (1 shl BIT_CRC)
865
        jz      .no_crc_error
3155 hidnplayr 866
        DEBUGF  2, "\nCRC error!\n"
1159 hidnplayr 867
 
868
  .no_crc_error:
2387 hidnplayr 869
        test    byte [eax], (1 shl BIT_FAE)
870
        jz      .no_fae_error
3155 hidnplayr 871
        DEBUGF  1, "\nFrame alignment error!\n"
1159 hidnplayr 872
 
873
  .no_fae_error:
3155 hidnplayr 874
        DEBUGF  1, "Reset RX\n"
875
        in      al, dx                              ; read command register
2387 hidnplayr 876
        push    ax
1159 hidnplayr 877
 
3155 hidnplayr 878
        and     al, not (1 shl BIT_RE)              ; Clear the RE bit
879
        out     dx, al
1159 hidnplayr 880
 
2387 hidnplayr 881
        pop     ax
3155 hidnplayr 882
        out     dx, al                              ; write original command back
1159 hidnplayr 883
 
2387 hidnplayr 884
        add     edx, REG_RXCONFIG - REG_COMMAND     ; Restore RX configuration
3155 hidnplayr 885
        mov     ax, RX_CONFIG
886
        out     dx, ax
1159 hidnplayr 887
 
888
  .finish:
2387 hidnplayr 889
        pop     ax
1159 hidnplayr 890
 
891
;----------------------------------------------------
1556 hidnplayr 892
; Transmit ok / Transmit error
1159 hidnplayr 893
  @@:
2387 hidnplayr 894
        test    ax, ISR_TOK + ISR_TER
895
        jz      @f
1159 hidnplayr 896
 
2387 hidnplayr 897
        push    ax
3155 hidnplayr 898
        mov     ecx, (NUM_TX_DESC-1)*4
899
  .txdescloop:
2387 hidnplayr 900
        set_io  0
901
        set_io  REG_TSD0
902
        add     edx, ecx
903
        in      eax, dx
1541 hidnplayr 904
 
2387 hidnplayr 905
        test    eax, TSR_OWN                    ; DMA operation completed
906
        jz      .notthisone
1556 hidnplayr 907
 
2387 hidnplayr 908
        cmp     [device.TX_DESC+ecx], 0
909
        je      .notthisone
1556 hidnplayr 910
 
1519 hidnplayr 911
;  .notxd:
912
;        test    eax, TSR_TUN
913
;        jz      .nobun
914
;        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
915
;
916
;  .nobun:
917
;        test    eax, TSR_OWC
918
;        jz      .noowc
919
;        DEBUGF  2, "TX: OWC!\n"
920
;
921
;  .noowc:
922
;        test    eax, TSR_TABT
923
;        jz      .notabt
924
;        DEBUGF  2, "TX: TABT!\n"
925
;
926
;  .notabt:
927
;        test    eax, TSR_CRS
928
;        jz      .nocsl
929
;        DEBUGF  2, "TX: Carrier Sense Lost!\n"
930
;
931
;  .nocsl:
932
 
3155 hidnplayr 933
        DEBUGF  1, "TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8
2387 hidnplayr 934
        push    ecx ebx
935
        stdcall KernelFree, [device.TX_DESC+ecx]
936
        pop     ebx ecx
937
        mov     [device.TX_DESC+ecx], 0
1556 hidnplayr 938
 
1519 hidnplayr 939
  .notthisone:
3155 hidnplayr 940
        sub     ecx, 4
941
        ja      .txdescloop
2387 hidnplayr 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
3155 hidnplayr 951
        DEBUGF  2, "RX-buffer overflow!\n"
1159 hidnplayr 952
 
2387 hidnplayr 953
        set_io  0
954
        set_io  REG_ISR
3155 hidnplayr 955
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
956
        out     dx, ax
2387 hidnplayr 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
 
3155 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
3155 hidnplayr 974
        DEBUGF  2, "RX fifo overflow!\n"
1159 hidnplayr 975
 
2387 hidnplayr 976
        set_io  0
977
        set_io  REG_ISR
3155 hidnplayr 978
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
979
        out     dx, ax
2387 hidnplayr 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
 
3155 hidnplayr 988
        DEBUGF  2, "Cable changed!\n"
2387 hidnplayr 989
        call    cable
1159 hidnplayr 990
 
991
  .fail:
3155 hidnplayr 992
        DEBUGF  2, "\n"
2387 hidnplayr 993
        ret
1159 hidnplayr 994
 
995
 
996
 
997
 
998
;;;;;;;;;;;;;;;;;;;;;;;;;
999
;;                     ;;
1000
;; Update Cable status ;;
1001
;;                     ;;
1002
;;;;;;;;;;;;;;;;;;;;;;;;;
1003
 
1004
align 4
1005
cable:
3155 hidnplayr 1006
        DEBUGF  1, "Checking Cable status: "
1159 hidnplayr 1007
 
2387 hidnplayr 1008
        mov     edx, dword [device.io_addr]
1009
        add     edx, REG_MSR
1010
        in      al , dx
1159 hidnplayr 1011
 
1012
;        test    al , 1 SHL 2     ; 0 = link ok 1 = link fail
1013
;        jnz     .notconnected
1014
 
1015
;        test    al , 1 SHL 3     ; 0 = 100 Mbps 1 = 10 Mbps
1016
;        jnz     .10mbps
1017
 
2387 hidnplayr 1018
        shr     al, 2
1019
        and     al, 3
1159 hidnplayr 1020
 
2387 hidnplayr 1021
        mov     byte [device.mode+3], al
3155 hidnplayr 1022
        DEBUGF  1, "Done!\n"
1159 hidnplayr 1023
ret
1024
 
1025
 
1026
 
1027
;;;;;;;;;;;;;;;;;;;;;;;
1028
;;                   ;;
1029
;; Write MAC address ;;
1030
;;                   ;;
1031
;;;;;;;;;;;;;;;;;;;;;;;
1032
 
1033
align 4
2387 hidnplayr 1034
write_mac:      ; in: mac pushed onto stack (as 3 words)
1159 hidnplayr 1035
 
3155 hidnplayr 1036
        DEBUGF  2, "Writing MAC: "
1159 hidnplayr 1037
 
1038
; disable all in command registers
1039
 
2387 hidnplayr 1040
        set_io  0
1041
        set_io  REG_9346CR
1042
        xor     eax, eax
3155 hidnplayr 1043
        out     dx, al
1159 hidnplayr 1044
 
2387 hidnplayr 1045
        set_io  REG_IMR
1046
        xor     eax, eax
3155 hidnplayr 1047
        out     dx, ax
1159 hidnplayr 1048
 
2387 hidnplayr 1049
        set_io  REG_ISR
1050
        mov     eax, -1
3155 hidnplayr 1051
        out     dx, ax
1159 hidnplayr 1052
 
1053
; enable writing
1054
 
2387 hidnplayr 1055
        set_io  REG_9346CR
1056
        mov     eax, REG_9346CR_WE
3155 hidnplayr 1057
        out     dx, al
1159 hidnplayr 1058
 
1059
 ; write the mac ...
1060
 
2387 hidnplayr 1061
        set_io  REG_IDR0
1062
        pop     eax
3155 hidnplayr 1063
        out     dx, eax
1159 hidnplayr 1064
 
2387 hidnplayr 1065
        set_io  REG_IDR0+4
1066
        xor     eax, eax
1067
        pop     ax
3155 hidnplayr 1068
        out     dx, eax
1159 hidnplayr 1069
 
1070
; disable writing
1071
 
2387 hidnplayr 1072
        set_io  REG_9346CR
1073
        xor     eax, eax
3155 hidnplayr 1074
        out     dx, al
1159 hidnplayr 1075
 
3155 hidnplayr 1076
        DEBUGF  2, "ok!\n"
1159 hidnplayr 1077
 
1078
; Notice this procedure does not ret, but continues to read_mac instead.
1079
 
1080
 
1081
;;;;;;;;;;;;;;;;;;;;;;
1082
;;                  ;;
1083
;; Read MAC address ;;
1084
;;                  ;;
1085
;;;;;;;;;;;;;;;;;;;;;;
1086
 
1087
read_mac:
3155 hidnplayr 1088
        DEBUGF  2, "Reading MAC: "
1159 hidnplayr 1089
 
2387 hidnplayr 1090
        set_io  0
1091
        lea     edi, [device.mac]
1092
        in      eax, dx
1093
        stosd
1094
        add     edx, 4
1095
        in      ax, dx
1096
        stosw
1159 hidnplayr 1097
 
3155 hidnplayr 1098
        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 1099
 
2387 hidnplayr 1100
        ret
1159 hidnplayr 1101
 
1102
 
1103
; End of code
1104
 
1519 hidnplayr 1105
section '.data' data readable writable align 16 ; place all uninitialized data place here
2387 hidnplayr 1106
align 4                                         ; Place all initialised data here
1159 hidnplayr 1107
 
2387 hidnplayr 1108
devices         dd 0
1109
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1110
my_service      db 'RTL8139',0                    ; max 16 chars include zero
1159 hidnplayr 1111
 
2387 hidnplayr 1112
device_1        db 'Realtek 8139',0
1113
device_2        db 'Realtek 8139A',0
1114
device_3        db 'Realtek 8139B',0
1115
device_4        db 'Realtek 8139C',0
1116
device_5        db 'Realtek 8100',0
1117
device_6        db 'Realtek 8139D',0
1118
device_7        db 'Realtek 8139CP',0
1119
device_8        db 'Realtek 8101',0
1120
device_unknown  db 'Unknown RTL8139 clone', 0
1178 hidnplayr 1121
 
1519 hidnplayr 1122
crosslist:
2387 hidnplayr 1123
        dd device_1
1124
        dd device_2
1125
        dd device_3
1126
        dd device_4
1127
        dd device_5
1128
        dd device_6
1129
        dd device_7
1130
        dd device_8
1131
        dd device_unknown
1178 hidnplayr 1132
 
2387 hidnplayr 1133
hw_ver_array:                    ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1134
        db VER_RTL8139
1135
        db VER_RTL8139A
1136
        db VER_RTL8139B
1137
        db VER_RTL8139C
1138
        db VER_RTL8100
1139
        db VER_RTL8139D
1140
        db VER_RTL8139CP
1141
        db VER_RTL8101
1142
        db 0
1159 hidnplayr 1143
 
1144
HW_VER_ARRAY_SIZE = $-hw_ver_array
1145
 
2387 hidnplayr 1146
include_debug_strings                           ; All data wich FDO uses will be included here
1159 hidnplayr 1147
 
2387 hidnplayr 1148
device_list     rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling
1159 hidnplayr 1149