Subversion Repositories Kolibri OS

Rev

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