Subversion Repositories Kolibri OS

Rev

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

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