Subversion Repositories Kolibri OS

Rev

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

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