Subversion Repositories Kolibri OS

Rev

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

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