Subversion Repositories Kolibri OS

Rev

Rev 5561 | Rev 6717 | 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
;; i8255x (Intel eepro 100) driver for KolibriOS                   ;;
7
;;                                                                 ;;
8
;;    Written by hidnplayr@kolibrios.org                           ;;
9
;;                                                                 ;;
10
;;          GNU GENERAL PUBLIC LICENSE                             ;;
11
;;             Version 2, June 1991                                ;;
12
;;                                                                 ;;
13
;; Some parts of this driver are based on the code of eepro100.c   ;;
14
;;  from linux.                                                    ;;
15
;;                                                                 ;;
16
;; Intel's programming manual for i8255x:                          ;;
17
;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
18
;;                                                                 ;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
 
5560 hidnplayr 21
;TODO: use more RX buffers
3545 hidnplayr 22
 
4581 hidnplayr 23
format PE DLL native
24
entry START
3545 hidnplayr 25
 
4581 hidnplayr 26
        CURRENT_API             = 0x0200
27
        COMPATIBLE_API          = 0x0100
28
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 29
 
30
        MAX_DEVICES             = 16
31
 
5525 hidnplayr 32
        TX_RING_SIZE            = 16
33
 
3545 hidnplayr 34
        DEBUG                   = 1
35
        __DEBUG__               = 1
4582 hidnplayr 36
        __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
3545 hidnplayr 37
 
4581 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
; Serial EEPROM
47
 
5562 hidnplayr 48
EE_SK           = 1 shl 0       ; serial clock
49
EE_CS           = 1 shl 1       ; chip select
50
EE_DI           = 1 shl 2       ; data in
51
EE_DO           = 1 shl 3       ; data out
3545 hidnplayr 52
EE_MASK         = EE_SK + EE_CS + EE_DI + EE_DO
53
 
54
; opcodes, first bit is start bit and must be 1
55
EE_READ         = 110b
56
EE_WRITE        = 101b
57
EE_ERASE        = 111b
58
 
59
; The SCB accepts the following controls for the Tx and Rx units:
60
 
61
CU_START        = 0x0010
62
CU_RESUME       = 0x0020
63
CU_STATSADDR    = 0x0040
64
CU_SHOWSTATS    = 0x0050        ; Dump statistics counters.
65
CU_CMD_BASE     = 0x0060        ; Base address to add CU commands.
66
CU_DUMPSTATS    = 0x0070        ; Dump then reset stats counters.
67
 
68
RX_START        = 0x0001
69
RX_RESUME       = 0x0002
70
RX_ABORT        = 0x0004
71
RX_ADDR_LOAD    = 0x0006
72
RX_RESUMENR     = 0x0007
73
INT_MASK        = 0x0100
74
DRVR_INT        = 0x0200        ; Driver generated interrupt
75
 
5562 hidnplayr 76
REG_SCB_STATUS  = 0
77
REG_SCB_CMD     = 2
78
REG_SCB_PTR     = 4
79
REG_PORT        = 8
80
REG_EEPROM      = 14
81
REG_MDI_CTRL    = 16
3545 hidnplayr 82
 
5562 hidnplayr 83
PHY_100a        = 0x000003E0
84
PHY_100c        = 0x035002A8
85
PHY_82555_tx    = 0x015002A8
86
PHY_nsc_tx      = 0x5C002000
87
PHY_82562_et    = 0x033002A8
88
PHY_82562_em    = 0x032002A8
89
PHY_82562_ek    = 0x031002A8
90
PHY_82562_eh    = 0x017002A8
91
PHY_82552_v     = 0xd061004d
92
PHY_unknown     = 0xFFFFFFFF
5522 hidnplayr 93
 
5562 hidnplayr 94
MAC_82557_D100_A        = 0
95
MAC_82557_D100_B        = 1
96
MAC_82557_D100_C        = 2
97
MAC_82558_D101_A4       = 4
98
MAC_82558_D101_B0       = 5
99
MAC_82559_D101M         = 8
100
MAC_82559_D101S         = 9
101
MAC_82550_D102          = 12
102
MAC_82550_D102_C        = 13
103
MAC_82551_E             = 14
104
MAC_82551_F             = 15
105
MAC_82551_10            = 16
106
MAC_unknown             = 0xFF
3545 hidnplayr 107
 
5562 hidnplayr 108
SCB_STATUS_RUS          = 111100b       ; RU Status
109
RU_STATUS_IDLE          = 0000b shl 2
110
RU_STATUS_SUSPENDED     = 0001b shl 2
111
RU_STATUS_NO_RESOURCES  = 0010b shl 2
112
RU_STATUS_READY         = 0100b shl 2
113
SCB_STATUS_FCP          = 1 shl 8       ; Flow Control Pause
114
SCB_STATUS_SWI          = 1 shl 10      ; Software Interrupt
115
SCB_STATUS_MDI          = 1 shl 11      ; MDI read/write complete
116
SCB_STATUS_RNR          = 1 shl 12      ; Receiver Not Ready
117
SCB_STATUS_CNA          = 1 shl 13      ; Command unit Not Active
118
SCB_STATUS_FR           = 1 shl 14      ; Frame received
119
SCB_STATUS_CX_TNO       = 1 shl 15      ; Command finished / Transmit Not Okay
3545 hidnplayr 120
 
4581 hidnplayr 121
struct  rxfd
122
 
123
        status          dw ?
124
        command         dw ?
125
        link            dd ?
126
        rx_buf_addr     dd ?
127
        count           dw ?
128
        size            dw ?
129
        packet          rb 1500
130
 
131
ends
132
 
5562 hidnplayr 133
RXFD_STATUS_RC          = 1 shl 0       ; Receive collision
134
RXFD_STATUS_IA          = 1 shl 1       ; IA mismatch
135
RXFD_STATUS_NA          = 1 shl 2       ; No address match
136
RXFD_STATUS_RE          = 1 shl 4       ; Receive Error
137
RXFD_STATUS_TL          = 1 shl 5       ; Type/length
138
RXFD_STATUS_FS          = 1 shl 7       ; Frame too short
139
RXFD_STATUS_DMA_FAIL    = 1 shl 8       ; DMA overrun failure
140
RXFD_STATUS_NR          = 1 shl 9       ; Out of buffer space; no resources
141
RXFD_STATUS_MISA        = 1 shl 10      ; Alignment error
142
RXFD_STATUS_CRC_ERR     = 1 shl 11      ; CRC error in aligned frame
143
RXFD_STATUS_OK          = 1 shl 13      ; Frame received and stored
144
RXFD_STATUS_C           = 1 shl 15      ; Completion of frame reception
145
 
146
RXFD_CMD_SF             = 1 shl 3
147
RXFD_CMD_H              = 1 shl 4       ; Header RFD
148
RXFD_CMD_SUSPEND        = 1 shl 14      ; Suspends RU after receiving the frame
149
RXFD_CMD_EL             = 1 shl 15      ; Last RFD in RFA
150
 
5525 hidnplayr 151
struct  txfd
4581 hidnplayr 152
 
5525 hidnplayr 153
        status          dw ?
154
        command         dw ?
155
        link            dd ?
156
        desc_addr       dd ?
157
        count           dd ?
4581 hidnplayr 158
 
5525 hidnplayr 159
        buf_addr        dd ?
160
        buf_size        dd ?
161
        virt_addr       dd ?
162
                        dd ?            ; alignment
4581 hidnplayr 163
 
5525 hidnplayr 164
ends
4581 hidnplayr 165
 
5562 hidnplayr 166
TXFD_CMD_IA             = 1 shl 0
167
TXFD_CMD_CFG            = 1 shl 1
168
TXFD_CMD_TX             = 1 shl 2
169
TXFD_CMD_TX_FLEX        = 1 shl 3
170
TXFD_CMD_SUSPEND        = 1 shl 14
171
 
4581 hidnplayr 172
struc   confcmd {
173
 
174
        .status         dw ?
175
        .command        dw ?
176
        .link           dd ?
177
        .data           rb 64
178
 
179
}
180
 
181
struc   lstats {
182
 
183
        .tx_good_frames         dd ?
184
        .tx_coll16_errs         dd ?
185
        .tx_late_colls          dd ?
186
        .tx_underruns           dd ?
187
        .tx_lost_carrier        dd ?
188
        .tx_deferred            dd ?
189
        .tx_one_colls           dd ?
190
        .tx_multi_colls         dd ?
191
        .tx_total_colls         dd ?
192
 
193
        .rx_good_frames         dd ?
194
        .rx_crc_errs            dd ?
195
        .rx_align_errs          dd ?
196
        .rx_resource_errs       dd ?
197
        .rx_overrun_errs        dd ?
198
        .rx_colls_errs          dd ?
199
        .rx_runt_errs           dd ?
200
 
201
}
202
 
203
struct  device          ETH_DEVICE
204
 
205
        io_addr         dd ?
206
        pci_bus         dd ?
207
        pci_dev         dd ?
208
        rx_desc         dd ?
5525 hidnplayr 209
        cur_tx          dd ?
210
        last_tx         dd ?
4581 hidnplayr 211
        ee_bus_width    db ?
212
        irq_line        db ?
213
 
214
        rb 0x100 - ($ and 0xff) ; align 256
5525 hidnplayr 215
        tx_ring         rb TX_RING_SIZE*sizeof.txfd
4581 hidnplayr 216
 
217
        rb 0x100 - ($ and 0xff) ; align 256
218
        confcmd         confcmd
219
 
220
        rb 0x100 - ($ and 0xff) ; align 256
221
        lstats          lstats
222
 
223
ends
224
 
3545 hidnplayr 225
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
226
;;                        ;;
227
;; proc START             ;;
228
;;                        ;;
229
;; (standard driver proc) ;;
230
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
231
 
4581 hidnplayr 232
proc START c, state:dword
3545 hidnplayr 233
 
234
        cmp [state], 1
235
        jne .exit
236
 
237
  .entry:
238
 
3845 hidnplayr 239
        DEBUGF 1,"Loading driver\n"
4581 hidnplayr 240
        invoke  RegService, my_service, service_proc
3545 hidnplayr 241
        ret
242
 
243
  .fail:
244
  .exit:
245
        xor eax, eax
246
        ret
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
 
261
        mov     edx, [ioctl]
4470 hidnplayr 262
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 263
 
264
;------------------------------------------------------
265
 
266
        cmp     eax, 0 ;SRV_GETVERSION
267
        jne     @F
268
 
4470 hidnplayr 269
        cmp     [edx + IOCTL.out_size], 4
3545 hidnplayr 270
        jb      .fail
4470 hidnplayr 271
        mov     eax, [edx + IOCTL.output]
3545 hidnplayr 272
        mov     [eax], dword API_VERSION
273
 
274
        xor     eax, eax
275
        ret
276
 
277
;------------------------------------------------------
278
  @@:
279
        cmp     eax, 1 ;SRV_HOOK
280
        jne     .fail
281
 
4470 hidnplayr 282
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
3545 hidnplayr 283
        jb      .fail
284
 
4470 hidnplayr 285
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 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
288
 
289
; check if the device is already listed
290
 
291
        mov     esi, device_list
292
        mov     ecx, [devices]
293
        test    ecx, ecx
294
        jz      .firstdevice
295
 
4470 hidnplayr 296
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
3545 hidnplayr 297
        mov     ax , [eax+1]                            ;
298
  .nextdevice:
299
        mov     ebx, [esi]
4581 hidnplayr 300
        cmp     al, byte[ebx + device.pci_bus]
3545 hidnplayr 301
        jne     @f
4581 hidnplayr 302
        cmp     ah, byte[ebx + device.pci_dev]
3545 hidnplayr 303
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
304
       @@:
305
        add     esi, 4
306
        loop    .nextdevice
307
 
308
 
309
; This device doesnt have its own eth_device structure yet, lets create one
310
  .firstdevice:
311
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
312
        jae     .fail
313
 
4581 hidnplayr 314
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
3545 hidnplayr 315
 
316
; Fill in the direct call addresses into the struct
317
 
4581 hidnplayr 318
        mov     [ebx + device.reset], reset
319
        mov     [ebx + device.transmit], transmit
320
        mov     [ebx + device.unload], unload
321
        mov     [ebx + device.name], my_service
3545 hidnplayr 322
 
323
; save the pci bus and device numbers
324
 
4470 hidnplayr 325
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 326
        movzx   ecx, byte[eax+1]
4581 hidnplayr 327
        mov     [ebx + device.pci_bus], ecx
3545 hidnplayr 328
        movzx   ecx, byte[eax+2]
4581 hidnplayr 329
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 330
 
331
; Now, it's time to find the base io addres of the PCI device
332
 
4581 hidnplayr 333
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
334
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 335
 
336
; We've found the io address, find IRQ now
337
 
4581 hidnplayr 338
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
339
        mov     [ebx + device.irq_line], al
3545 hidnplayr 340
 
3845 hidnplayr 341
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
4581 hidnplayr 342
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
3545 hidnplayr 343
 
344
; Ok, the eth_device structure is ready, let's probe the device
345
 
346
        pushf
4581 hidnplayr 347
        cli                     ; disable ints untilm initialisation is done
3545 hidnplayr 348
 
349
        call    probe                                                   ; this function will output in eax
350
        test    eax, eax
351
        jnz     .err                                                    ; If an error occured, exit
352
 
353
        mov     eax, [devices]                                          ; Add the device structure to our device list
354
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
355
        inc     [devices]                                               ;
356
 
357
        popf
358
 
4581 hidnplayr 359
        mov     [ebx + device.type], NET_TYPE_ETH
360
        invoke  NetRegDev
3545 hidnplayr 361
 
362
        cmp     eax, -1
363
        je      .err
364
 
365
        ret
366
 
367
; If the device was already loaded, find the device number and return it in eax
368
 
369
  .find_devicenum:
370
        DEBUGF  2,"Trying to find device number of already registered device\n"
4581 hidnplayr 371
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
3545 hidnplayr 372
                                                                        ; into a device number in edi
373
        mov     eax, edi                                                ; Application wants it in eax instead
374
        DEBUGF  2,"Kernel says: %u\n", eax
375
        ret
376
 
377
; If an error occured, remove all allocated data and exit (returning -1 in eax)
378
 
379
  .err:
4581 hidnplayr 380
        invoke  KernelFree, ebx
3545 hidnplayr 381
 
382
  .fail:
383
        or      eax, -1
384
        ret
385
 
386
;------------------------------------------------------
387
endp
388
 
389
 
390
 
391
 
392
 
393
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
394
;;                                                                        ;;
395
;;        Actual Hardware dependent code starts here                      ;;
396
;;                                                                        ;;
397
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
398
 
399
 
400
unload:
401
        ; TODO: (in this particular order)
402
        ;
403
        ; - Stop the device
404
        ; - Detach int handler
405
        ; - Remove device from local list (device_list)
406
        ; - call unregister function in kernel
407
        ; - Remove all allocated structures and buffers the card used
408
 
5560 hidnplayr 409
        or      eax, -1
410
        ret
3545 hidnplayr 411
 
412
 
413
;-------------
414
;
415
; Probe
416
;
417
;-------------
418
 
419
align 4
420
probe:
421
 
3845 hidnplayr 422
        DEBUGF  1,"Probing\n"
3545 hidnplayr 423
 
4581 hidnplayr 424
; Make the device a bus master
425
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
426
        or      al, PCI_CMD_MASTER
427
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 428
 
429
;---------------------------
430
; First, identify the device
431
 
4581 hidnplayr 432
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.vendor_id ; get device/vendor id
3545 hidnplayr 433
 
434
        DEBUGF  1,"Vendor_id=0x%x\n", ax
435
 
436
        cmp     ax, 0x8086
437
        jne     .notfound
438
        shr     eax, 16
439
 
440
        DEBUGF  1,"Device_id=0x%x\n", ax
441
 
442
        mov     ecx, DEVICE_IDs
443
        mov     edi, device_id_list
444
        repne   scasw
445
        jne     .notfound
446
        jmp     .found
447
 
448
  .notfound:
3845 hidnplayr 449
        DEBUGF  2,"Unsupported device!\n"
3545 hidnplayr 450
        or      eax, -1
451
        ret
452
 
453
  .found:
454
 
455
        call    ee_get_width
456
        call    MAC_read_eeprom
457
 
458
        ;;; TODO: detect phy
459
 
460
 
461
 
462
;----------
463
;
464
;  Reset
465
;
466
;----------
467
 
468
align 4
469
reset:
470
 
4581 hidnplayr 471
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 472
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
4581 hidnplayr 473
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 474
        test    eax, eax
475
        jnz     @f
3845 hidnplayr 476
        DEBUGF  2,"Could not attach int handler!\n"
4581 hidnplayr 477
        or      eax, -1
478
        ret
3545 hidnplayr 479
  @@:
480
 
3845 hidnplayr 481
        DEBUGF  1,"Resetting\n"
3545 hidnplayr 482
 
483
;---------------
484
; reset the card
485
 
4581 hidnplayr 486
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 487
        set_io  [ebx + device.io_addr], REG_PORT
3545 hidnplayr 488
        xor     eax, eax        ; Software Reset
489
        out     dx, eax
490
 
491
        mov     esi, 10
4581 hidnplayr 492
        invoke  Sleep           ; Give the card time to warm up.
3545 hidnplayr 493
 
494
;---------------------------------
495
; Tell device where to store stats
496
 
4581 hidnplayr 497
        lea     eax, [ebx + device.lstats.tx_good_frames]      ; lstats
498
        invoke  GetPhysAddr
499
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 500
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 501
        out     dx, eax
502
 
5562 hidnplayr 503
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 504
        mov     ax, CU_STATSADDR or INT_MASK
3545 hidnplayr 505
        out     dx, ax
506
        call    cmd_wait
507
 
5525 hidnplayr 508
;------------------------
509
; setup RX base addr to 0
3545 hidnplayr 510
 
5562 hidnplayr 511
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 512
        xor     eax, eax
513
        out     dx, eax
514
 
5562 hidnplayr 515
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 516
        mov     ax, RX_ADDR_LOAD or INT_MASK
3545 hidnplayr 517
        out     dx, ax
518
        call    cmd_wait
519
 
520
;-----------------------------
521
; Create RX and TX descriptors
522
 
5525 hidnplayr 523
        call    init_rx_ring
5522 hidnplayr 524
        test    eax, eax
525
        jz      .error
3545 hidnplayr 526
 
5525 hidnplayr 527
        call    init_tx_ring
3545 hidnplayr 528
 
5525 hidnplayr 529
 
530
;---------
531
; Start RX
532
 
533
        DEBUGF  1, "Starting RX"
534
 
4581 hidnplayr 535
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 536
        set_io  [ebx + device.io_addr], REG_SCB_PTR
4581 hidnplayr 537
        mov     eax, [ebx + device.rx_desc]
538
        invoke  GetPhysAddr
5522 hidnplayr 539
        add     eax, NET_BUFF.data
3545 hidnplayr 540
        out     dx, eax
541
 
5562 hidnplayr 542
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 543
        mov     ax, RX_START or INT_MASK
3545 hidnplayr 544
        out     dx, ax
545
        call    cmd_wait
546
 
5525 hidnplayr 547
;----------
3545 hidnplayr 548
; Set-up TX
549
 
5562 hidnplayr 550
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 551
        xor     eax, eax
552
        out     dx, eax
553
 
5562 hidnplayr 554
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 555
        mov     ax, CU_CMD_BASE or INT_MASK
3545 hidnplayr 556
        out     dx, ax
557
        call    cmd_wait
558
 
5525 hidnplayr 559
;-------------------------
560
; Individual address setup
3545 hidnplayr 561
 
5562 hidnplayr 562
        mov     [ebx + device.confcmd.command], TXFD_CMD_IA + TXFD_CMD_SUSPEND
5525 hidnplayr 563
        mov     [ebx + device.confcmd.status], 0
564
        lea     eax, [ebx + device.tx_ring]
565
        invoke  GetPhysAddr
566
        mov     [ebx + device.confcmd.link], eax
567
        lea     edi, [ebx + device.confcmd.data]
568
        lea     esi, [ebx + device.mac]
569
        movsd
570
        movsw
571
 
5562 hidnplayr 572
        set_io  [ebx + device.io_addr], REG_SCB_PTR
5525 hidnplayr 573
        lea     eax, [ebx + device.confcmd.status]
574
        invoke  GetPhysAddr
575
        out     dx, eax
576
 
5562 hidnplayr 577
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 578
        mov     ax, CU_START or INT_MASK
579
        out     dx, ax
580
        call    cmd_wait
581
 
582
;-------------
583
; Configure CU
584
 
5562 hidnplayr 585
        mov     [ebx + device.confcmd.command], TXFD_CMD_CFG + TXFD_CMD_SUSPEND
4581 hidnplayr 586
        mov     [ebx + device.confcmd.status], 0
5525 hidnplayr 587
        lea     eax, [ebx + device.confcmd.status]
4581 hidnplayr 588
        invoke  GetPhysAddr
589
        mov     [ebx + device.confcmd.link], eax
3545 hidnplayr 590
 
591
        mov     esi, confcmd_data
4581 hidnplayr 592
        lea     edi, [ebx + device.confcmd.data]
3545 hidnplayr 593
        mov     ecx, 22
594
        rep     movsb
595
 
4581 hidnplayr 596
        mov     byte[ebx + device.confcmd.data + 1], 0x88  ; fifo of 8 each
597
        mov     byte[ebx + device.confcmd.data + 4], 0
598
        mov     byte[ebx + device.confcmd.data + 5], 0x80
599
        mov     byte[ebx + device.confcmd.data + 15], 0x48
600
        mov     byte[ebx + device.confcmd.data + 19], 0x80
601
        mov     byte[ebx + device.confcmd.data + 21], 0x05
3545 hidnplayr 602
 
5562 hidnplayr 603
        set_io  [ebx + device.io_addr], REG_SCB_PTR
4581 hidnplayr 604
        lea     eax, [ebx + device.confcmd.status]
605
        invoke  GetPhysAddr
3545 hidnplayr 606
        out     dx, eax
607
 
5562 hidnplayr 608
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 609
        mov     ax, CU_START                            ; expect Interrupts from now on
3545 hidnplayr 610
        out     dx, ax
611
        call    cmd_wait
612
 
3845 hidnplayr 613
        DEBUGF  1,"Reset complete\n"
4581 hidnplayr 614
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 615
 
616
; Set link state to unknown
4581 hidnplayr 617
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 618
 
619
        xor     eax, eax        ; indicate that we have successfully reset the card
620
        ret
621
 
5522 hidnplayr 622
  .error:
623
        or      eax, -1
624
        ret
3545 hidnplayr 625
 
5522 hidnplayr 626
 
3545 hidnplayr 627
align 4
5525 hidnplayr 628
init_rx_ring:
3545 hidnplayr 629
 
630
        DEBUGF  1,"Creating ring\n"
631
 
632
;---------------------
633
; build rxfd structure
634
 
5522 hidnplayr 635
        invoke  NetAlloc, 2000
636
        test    eax, eax
637
        jz      .out_of_mem
4581 hidnplayr 638
        mov     [ebx + device.rx_desc], eax
3545 hidnplayr 639
        mov     esi, eax
4581 hidnplayr 640
        invoke  GetPhysAddr
5522 hidnplayr 641
        add     eax, NET_BUFF.data
5562 hidnplayr 642
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
643
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
5522 hidnplayr 644
        mov     [esi + sizeof.NET_BUFF + rxfd.link], eax
645
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
646
        mov     [esi + sizeof.NET_BUFF + rxfd.size], 1528
3545 hidnplayr 647
 
5525 hidnplayr 648
        ret
3545 hidnplayr 649
 
5525 hidnplayr 650
  .out_of_mem:
651
        ret
652
 
653
 
654
 
655
 
656
align 4
657
init_tx_ring:
658
 
659
        DEBUGF  1,"Creating TX ring\n"
660
 
661
        lea     esi, [ebx + device.tx_ring]
662
        mov     eax, esi
4581 hidnplayr 663
        invoke  GetPhysAddr
5525 hidnplayr 664
        mov     ecx, TX_RING_SIZE
665
  .next_desc:
666
        mov     [esi + txfd.status], 0
667
        mov     [esi + txfd.command], 0
668
        lea     edx, [eax + txfd.buf_addr]
669
        mov     [esi + txfd.desc_addr], edx
670
        add     eax, sizeof.txfd
671
        mov     [esi + txfd.link], eax
672
        mov     [esi + txfd.count], 0x01208000          ; One buffer, 0x20 bytes of transmit threshold, end of frame
673
        add     esi, sizeof.txfd
674
        dec     ecx
675
        jnz     .next_desc
676
 
677
        lea     eax, [ebx + device.tx_ring]
4581 hidnplayr 678
        invoke  GetPhysAddr
5525 hidnplayr 679
        mov     dword[ebx + device.tx_ring + sizeof.txfd*(TX_RING_SIZE-1) + txfd.link], eax
3545 hidnplayr 680
 
5525 hidnplayr 681
        mov     [ebx + device.cur_tx], 0
682
        mov     [ebx + device.last_tx], 0
5522 hidnplayr 683
 
3545 hidnplayr 684
        ret
685
 
686
 
687
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
688
;;                                         ;;
689
;; Transmit                                ;;
690
;;                                         ;;
4581 hidnplayr 691
;; In: pointer to device structure in ebx  ;;
3545 hidnplayr 692
;;                                         ;;
693
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
694
 
5522 hidnplayr 695
proc transmit stdcall bufferptr
3545 hidnplayr 696
 
4581 hidnplayr 697
        pushf
698
        cli
699
 
5522 hidnplayr 700
        mov     esi, [bufferptr]
701
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
702
        lea     eax, [esi + NET_BUFF.data]
3545 hidnplayr 703
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
704
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
705
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
706
        [eax+13]:2,[eax+12]:2
707
 
5522 hidnplayr 708
        cmp     [esi + NET_BUFF.length], 1514
4581 hidnplayr 709
        ja      .fail
5522 hidnplayr 710
        cmp     [esi + NET_BUFF.length], 60
4581 hidnplayr 711
        jb      .fail
3545 hidnplayr 712
 
5525 hidnplayr 713
        ; Get current TX descriptor
714
        mov     edi, [ebx + device.cur_tx]
715
        mov     eax, sizeof.txfd
716
        mul     edi
717
        lea     edi, [ebx + device.tx_ring + eax]
718
 
719
        ; Check if current descriptor is free or still in use
720
        cmp     [edi + txfd.status], 0
721
        jne     .fail
722
 
723
        ; Fill in status and command values
724
        mov     [edi + txfd.status], 0
5562 hidnplayr 725
        mov     [edi + txfd.command], TXFD_CMD_SUSPEND + TXFD_CMD_TX + TXFD_CMD_TX_FLEX
5525 hidnplayr 726
        mov     [edi + txfd.count], 0x01208000
727
 
728
        ; Fill in buffer address and size
729
        mov     [edi + txfd.virt_addr], esi
730
        mov     eax, esi
731
        add     eax, [esi + NET_BUFF.offset]
732
        push    edi
4581 hidnplayr 733
        invoke  GetPhysAddr
5525 hidnplayr 734
        pop     edi
735
        mov     [edi + txfd.buf_addr], eax
736
        mov     ecx, [esi + NET_BUFF.length]
737
        mov     [edi + txfd.buf_size], ecx
3545 hidnplayr 738
 
739
        ; Inform device of the new/updated transmit descriptor
5525 hidnplayr 740
        mov     eax, edi
4581 hidnplayr 741
        invoke  GetPhysAddr
742
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 743
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 744
        out     dx, eax
745
 
746
        ; Start the transmit
5562 hidnplayr 747
        set_io  [ebx + device.io_addr], REG_SCB_CMD
3545 hidnplayr 748
        mov     ax, CU_START
749
        out     dx, ax
750
 
5525 hidnplayr 751
        ; Update stats
4581 hidnplayr 752
        inc     [ebx + device.packets_tx]
753
        add     dword[ebx + device.bytes_tx], ecx
754
        adc     dword[ebx + device.bytes_tx + 4], 0
3545 hidnplayr 755
 
5525 hidnplayr 756
        ; Wait for command to complete
757
        call    cmd_wait
758
 
759
        inc     [ebx + device.cur_tx]
760
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
761
 
3545 hidnplayr 762
        DEBUGF  1,"Transmit OK\n"
4581 hidnplayr 763
        popf
3545 hidnplayr 764
        xor     eax, eax
4581 hidnplayr 765
        ret
3545 hidnplayr 766
 
4581 hidnplayr 767
  .fail:
5525 hidnplayr 768
        DEBUGF  2,"Transmit failed!\n"
5522 hidnplayr 769
        invoke  NetFree, [bufferptr]
4581 hidnplayr 770
        popf
3545 hidnplayr 771
        or      eax, -1
4581 hidnplayr 772
        ret
3545 hidnplayr 773
 
4581 hidnplayr 774
endp
775
 
776
 
3545 hidnplayr 777
;;;;;;;;;;;;;;;;;;;;;;;
778
;;                   ;;
779
;; Interrupt handler ;;
780
;;                   ;;
781
;;;;;;;;;;;;;;;;;;;;;;;
782
 
783
align 4
784
int_handler:
785
 
786
        push    ebx esi edi
787
 
3845 hidnplayr 788
        DEBUGF  1,"INT\n"
3545 hidnplayr 789
 
790
; find pointer of device wich made IRQ occur
791
 
792
        mov     ecx, [devices]
793
        test    ecx, ecx
794
        jz      .nothing
795
        mov     esi, device_list
796
  .nextdevice:
797
        mov     ebx, [esi]
798
 
5562 hidnplayr 799
;        set_io  [ebx + device.io_addr], 0      ; REG_SCB_STATUS = 0
800
        set_io  [ebx + device.io_addr], REG_SCB_STATUS
3545 hidnplayr 801
        in      ax, dx
5562 hidnplayr 802
        out     dx, ax                          ; send it back to ACK
3545 hidnplayr 803
        test    ax, ax
804
        jnz     .got_it
805
  .continue:
806
        add     esi, 4
807
        dec     ecx
808
        jnz     .nextdevice
809
  .nothing:
810
        pop     edi esi ebx
811
        xor     eax, eax
812
 
5562 hidnplayr 813
        ret                                     ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
3545 hidnplayr 814
 
815
  .got_it:
816
 
817
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
818
 
5562 hidnplayr 819
        test    ax, SCB_STATUS_FR               ; did we receive a frame?
3545 hidnplayr 820
        jz      .no_rx
821
 
822
        push    ax
823
 
824
        DEBUGF  1,"Receiving\n"
825
 
826
        push    ebx
827
  .rx_loop:
828
        pop     ebx
829
 
4581 hidnplayr 830
        mov     esi, [ebx + device.rx_desc]
5562 hidnplayr 831
        test    [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C            ; Completed?
832
        jz      .no_rx_
833
        test    [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_OK           ; OK?
834
        jz      .not_ok
3545 hidnplayr 835
 
5522 hidnplayr 836
        DEBUGF  1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4
3545 hidnplayr 837
 
5522 hidnplayr 838
        movzx   ecx, [esi + sizeof.NET_BUFF + rxfd.count]
3545 hidnplayr 839
        and     ecx, 0x3fff
840
 
841
        push    ebx
842
        push    .rx_loop
843
        push    esi
5522 hidnplayr 844
        mov     [esi + NET_BUFF.length], ecx
845
        mov     [esi + NET_BUFF.device], ebx
846
        mov     [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet
3545 hidnplayr 847
 
848
; Update stats
4581 hidnplayr 849
        add     dword [ebx + device.bytes_rx], ecx
850
        adc     dword [ebx + device.bytes_rx + 4], 0
851
        inc     dword [ebx + device.packets_rx]
3545 hidnplayr 852
 
853
; allocate new descriptor
854
 
5522 hidnplayr 855
        invoke  NetAlloc, 2000
5561 hidnplayr 856
        test    eax, eax
857
        jz      .out_of_mem
4581 hidnplayr 858
        mov     [ebx + device.rx_desc], eax
3545 hidnplayr 859
        mov     esi, eax
4581 hidnplayr 860
        invoke  GetPhysAddr
5522 hidnplayr 861
        add     eax, NET_BUFF.data
5562 hidnplayr 862
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
863
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
5522 hidnplayr 864
        mov     [esi + sizeof.NET_BUFF + rxfd.link], eax
865
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
866
        mov     [esi + sizeof.NET_BUFF + rxfd.size], 1528
3545 hidnplayr 867
 
868
; restart RX
869
 
4581 hidnplayr 870
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 871
        set_io  [ebx + device.io_addr], REG_SCB_PTR
5560 hidnplayr 872
;        mov     eax, [ebx + device.rx_desc]
4581 hidnplayr 873
;        invoke  GetPhysAddr
5560 hidnplayr 874
;        add     eax, NET_BUFF.data
3545 hidnplayr 875
        out     dx, eax
876
 
5562 hidnplayr 877
        set_io  [ebx + device.io_addr], REG_SCB_CMD
3545 hidnplayr 878
        mov     ax, RX_START
879
        out     dx, ax
880
        call    cmd_wait
5561 hidnplayr 881
  .out_of_mem:
3545 hidnplayr 882
 
5562 hidnplayr 883
; Hand the frame over to the kernel
5522 hidnplayr 884
        jmp     [EthInput]
3545 hidnplayr 885
 
5562 hidnplayr 886
  .not_ok:
887
; Reset the FD
888
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
889
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
890
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
891
 
892
; Restart RX
893
        set_io  [ebx + device.io_addr], 0
894
        set_io  [ebx + device.io_addr], REG_SCB_PTR
895
        mov     eax, esi
896
        invoke  GetPhysAddr
897
        add     eax, NET_BUFF.data
898
        out     dx, eax
899
 
900
        set_io  [ebx + device.io_addr], REG_SCB_CMD
901
        mov     ax, RX_START
902
        out     dx, ax
903
        call    cmd_wait
904
 
905
        push    ebx
906
        jmp     .rx_loop
907
 
908
  .no_rx_:
3545 hidnplayr 909
        DEBUGF  1, "no more data\n"
910
        pop     ax
911
 
912
  .no_rx:
913
 
5562 hidnplayr 914
        test    ax, SCB_STATUS_CNA
5525 hidnplayr 915
        jz      .no_tx
916
        DEBUGF  1, "Command completed\n"
3545 hidnplayr 917
 
5525 hidnplayr 918
        push    eax
919
  .loop_tx:
920
        mov     edi, [ebx + device.last_tx]
921
        mov     eax, sizeof.txfd
922
        mul     eax
923
        lea     edi, [ebx + device.tx_ring + eax]
924
 
925
        cmp     [edi + txfd.status], 0
926
        je      .tx_done
927
 
928
        cmp     [edi + txfd.virt_addr], 0
929
        je      .tx_done
930
 
931
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + txfd.virt_addr]
932
 
933
        push    [edi + txfd.virt_addr]
934
        mov     [edi + txfd.virt_addr], 0
935
        invoke  NetFree
936
 
937
        inc     [ebx + device.last_tx]
938
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
939
 
940
        jmp     .loop_tx
941
  .tx_done:
942
        pop     eax
943
  .no_tx:
944
 
5562 hidnplayr 945
        test    ax, RU_STATUS_NO_RESOURCES
3545 hidnplayr 946
        jne     .fail
947
 
5560 hidnplayr 948
        DEBUGF  2, "Out of resources!\n"
3545 hidnplayr 949
 
950
  .fail:
951
        pop     edi esi ebx
952
        xor     eax, eax
953
        inc     eax
954
 
955
        ret
956
 
957
 
958
 
959
 
960
align 4
961
cmd_wait:
962
 
963
        in      al, dx
964
        test    al, al
965
        jnz     cmd_wait
966
 
967
        ret
968
 
969
 
970
 
971
 
972
 
973
 
974
align 4
975
ee_read:        ; esi = address to read
976
 
3845 hidnplayr 977
        DEBUGF  1,"Eeprom read from 0x%x\n", esi
3545 hidnplayr 978
 
4581 hidnplayr 979
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 980
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 981
 
982
;-----------------------------------------------------
983
; Prepend start bit + read opcode to the address field
984
; and shift it to the very left bits of esi
985
 
986
        mov     cl, 29
4581 hidnplayr 987
        sub     cl, [ebx + device.ee_bus_width]
3545 hidnplayr 988
        shl     esi, cl
989
        or      esi, EE_READ shl 29
990
 
4581 hidnplayr 991
        movzx   ecx, [ebx + device.ee_bus_width]
3545 hidnplayr 992
        add     ecx, 3
993
 
994
        mov     al, EE_CS
995
        out     dx, al
5247 hidnplayr 996
        call    udelay
3545 hidnplayr 997
 
998
;-----------------------
999
; Write this to the chip
1000
 
1001
  .loop:
1002
        mov     al, EE_CS + EE_SK
1003
        shl     esi, 1
1004
        jnc     @f
1005
        or      al, EE_DI
1006
       @@:
1007
        out     dx, al
5247 hidnplayr 1008
        call    udelay
3545 hidnplayr 1009
 
1010
        and     al, not EE_SK
1011
        out     dx, al
5247 hidnplayr 1012
        call    udelay
3545 hidnplayr 1013
 
1014
        loop    .loop
1015
 
1016
;------------------------------
1017
; Now read the data from eeprom
1018
 
1019
        xor     esi, esi
1020
        mov     ecx, 16
1021
 
1022
  .loop2:
1023
        shl     esi, 1
1024
        mov     al, EE_CS + EE_SK
1025
        out     dx, al
5247 hidnplayr 1026
        call    udelay
3545 hidnplayr 1027
 
1028
        in      al, dx
1029
        test    al, EE_DO
1030
        jz      @f
1031
        inc     esi
1032
       @@:
1033
 
1034
        mov     al, EE_CS
1035
        out     dx, al
5247 hidnplayr 1036
        call    udelay
3545 hidnplayr 1037
 
1038
        loop    .loop2
1039
 
1040
;-----------------------
1041
; de-activate the eeprom
1042
 
1043
        xor     ax, ax
1044
        out     dx, ax
1045
 
1046
 
3845 hidnplayr 1047
        DEBUGF  1,"0x%x\n", esi:4
3545 hidnplayr 1048
        ret
1049
 
1050
 
1051
 
1052
align 4
1053
ee_write:       ; esi = address to write to, di = data
1054
 
1055
        DEBUGF  1,"Eeprom write 0x%x to 0x%x\n", di, esi
1056
 
4581 hidnplayr 1057
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1058
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 1059
 
1060
;-----------------------------------------------------
1061
; Prepend start bit + write opcode to the address field
1062
; and shift it to the very left bits of esi
1063
 
1064
        mov     cl, 29
4581 hidnplayr 1065
        sub     cl, [ebx + device.ee_bus_width]
3545 hidnplayr 1066
        shl     esi, cl
1067
        or      esi, EE_WRITE shl 29
1068
 
4581 hidnplayr 1069
        movzx   ecx, [ebx + device.ee_bus_width]
3545 hidnplayr 1070
        add     ecx, 3
1071
 
1072
        mov     al, EE_CS       ; enable chip
1073
        out     dx, al
1074
 
1075
;-----------------------
1076
; Write this to the chip
1077
 
1078
  .loop:
1079
        mov     al, EE_CS + EE_SK
1080
        shl     esi, 1
1081
        jnc     @f
1082
        or      al, EE_DI
1083
       @@:
1084
        out     dx, al
5247 hidnplayr 1085
        call    udelay
3545 hidnplayr 1086
 
1087
        and     al, not EE_SK
1088
        out     dx, al
5247 hidnplayr 1089
        call    udelay
3545 hidnplayr 1090
 
1091
        loop    .loop
1092
 
1093
;-----------------------------
1094
; Now write the data to eeprom
1095
 
1096
        mov     ecx, 16
1097
 
1098
  .loop2:
1099
        mov     al, EE_CS + EE_SK
1100
        shl     di, 1
1101
        jnc     @f
1102
        or      al, EE_DI
1103
       @@:
1104
        out     dx, al
5247 hidnplayr 1105
        call    udelay
3545 hidnplayr 1106
 
1107
        and     al, not EE_SK
1108
        out     dx, al
5247 hidnplayr 1109
        call    udelay
3545 hidnplayr 1110
 
1111
        loop    .loop2
1112
 
1113
;-----------------------
1114
; de-activate the eeprom
1115
 
1116
        xor     al, al
1117
        out     dx, al
1118
 
1119
 
1120
        ret
1121
 
1122
 
1123
 
1124
align 4
1125
ee_get_width:
1126
 
4581 hidnplayr 1127
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1128
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 1129
 
1130
        mov     al, EE_CS      ; activate eeprom
1131
        out     dx, al
5247 hidnplayr 1132
        call    udelay
3545 hidnplayr 1133
 
1134
        mov     si, EE_READ shl 13
1135
        xor     ecx, ecx
1136
  .loop:
1137
        mov     al, EE_CS + EE_SK
1138
        shl     si, 1
1139
        jnc     @f
1140
        or      al, EE_DI
1141
       @@:
1142
        out     dx, al
5247 hidnplayr 1143
        call    udelay
3545 hidnplayr 1144
 
1145
        and     al, not EE_SK
1146
        out     dx, al
5247 hidnplayr 1147
        call    udelay
3545 hidnplayr 1148
 
1149
        inc     ecx
1150
 
1151
        cmp     ecx, 15
1152
        jae     .give_up
1153
 
1154
        in      al, dx
1155
        test    al, EE_DO
1156
        jnz     .loop
1157
 
1158
        xor     al, al
1159
        out     dx, al          ; de-activate eeprom
1160
 
1161
        sub     cl, 3           ; dont count the opcode bits
4581 hidnplayr 1162
        mov     [ebx + device.ee_bus_width], cl
3845 hidnplayr 1163
        DEBUGF  1, "Eeprom width=%u bit\n", ecx
3545 hidnplayr 1164
 
3845 hidnplayr 1165
        ret
3545 hidnplayr 1166
 
3845 hidnplayr 1167
  .give_up:
1168
        DEBUGF  2, "Eeprom not found!\n"
3545 hidnplayr 1169
 
3845 hidnplayr 1170
        xor     al, al
1171
        out     dx, al          ; de-activate eeprom
3545 hidnplayr 1172
 
1173
        ret
1174
 
1175
 
5247 hidnplayr 1176
; Wait a minimum of 2µs
1177
udelay:
1178
        pusha
1179
        mov     esi, 1
1180
        invoke  Sleep
1181
        popa
3545 hidnplayr 1182
 
5247 hidnplayr 1183
        ret
1184
 
1185
 
1186
 
3545 hidnplayr 1187
; cx = phy addr
1188
; dx = phy reg addr
1189
 
1190
; ax = data
1191
 
1192
align 4
1193
mdio_read:
1194
 
1195
        DEBUGF  1,"MDIO read\n"
1196
 
1197
        shl     ecx, 21                 ; PHY addr
1198
        shl     edx, 16                 ; PHY reg addr
1199
 
1200
        mov     eax, ecx
1201
        or      eax, edx
1202
        or      eax, 10b shl 26         ; read opcode
1203
 
4581 hidnplayr 1204
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1205
        set_io  [ebx + device.io_addr], REG_MDI_CTRL
3545 hidnplayr 1206
        out     dx, eax
1207
 
1208
  .wait:
5247 hidnplayr 1209
        call    udelay
3545 hidnplayr 1210
        in      eax, dx
1211
        test    eax, 1 shl 28           ; ready bit
1212
        jz      .wait
1213
 
1214
        ret
1215
 
1216
; ax = data
1217
; cx = phy addr
1218
; dx = phy reg addr
1219
 
1220
; ax = data
1221
 
1222
align 4
1223
mdio_write:
1224
 
1225
        DEBUGF  1,"MDIO write\n"
1226
 
1227
        and     eax, 0xffff
1228
 
1229
        shl     ecx, 21                 ; PHY addr
1230
        shl     edx, 16                 ; PHY reg addr
1231
 
1232
        or      eax, ecx
1233
        or      eax, edx
1234
        or      eax, 01b shl 26         ; write opcode
1235
 
4581 hidnplayr 1236
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1237
        set_io  [ebx + device.io_addr], REG_MDI_CTRL
3545 hidnplayr 1238
        out     dx, eax
1239
 
1240
  .wait:
5247 hidnplayr 1241
        call    udelay
3545 hidnplayr 1242
        in      eax, dx
1243
        test    eax, 1 shl 28           ; ready bit
1244
        jz      .wait
1245
 
1246
        ret
1247
 
1248
read_mac:
1249
 
1250
        ret
1251
 
1252
 
1253
 
1254
align 4
1255
MAC_read_eeprom:
1256
 
1257
        mov     esi, 0
1258
        call    ee_read
4581 hidnplayr 1259
        mov     word[ebx + device.mac], si
3545 hidnplayr 1260
 
1261
        mov     esi, 1
1262
        call    ee_read
4581 hidnplayr 1263
        mov     word[ebx + device.mac+2], si
3545 hidnplayr 1264
 
1265
        mov     esi, 2
1266
        call    ee_read
4581 hidnplayr 1267
        mov     word[ebx + device.mac+4], si
3545 hidnplayr 1268
 
1269
 
1270
        ret
1271
 
1272
 
1273
align 4
1274
MAC_write:
1275
 
1276
;;;;
1277
 
1278
        ret
1279
 
1280
 
1281
 
1282
 
1283
; End of code
1284
 
1285
 
4581 hidnplayr 1286
data fixups
1287
end data
1288
 
1289
include '../peimport.inc'
1290
 
4629 hidnplayr 1291
my_service      db 'I8255X', 0                    ; max 16 chars include zero
3545 hidnplayr 1292
devicename      db 'Intel Etherexpress pro/100', 0
1293
 
1294
confcmd_data    db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
1295
                db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
1296
                db 0x80, 0x3f, 0x05                                     ; 22 bytes total
1297
 
1298
 
1299
device_id_list:
1300
 
1301
        dw 0x1029
1302
        dw 0x1030
1303
        dw 0x1031
1304
        dw 0x1032
1305
        dw 0x1033
1306
        dw 0x1034
1307
        dw 0x1038
1308
        dw 0x1039
1309
        dw 0x103A
1310
        dw 0x103B
1311
        dw 0x103C
1312
        dw 0x103D
1313
        dw 0x103E
1314
        dw 0x1050
1315
        dw 0x1051
1316
        dw 0x1052
1317
        dw 0x1053
1318
        dw 0x1054
1319
        dw 0x1055
1320
        dw 0x1056
1321
        dw 0x1057
1322
        dw 0x1059
1323
        dw 0x1064
1324
        dw 0x1065
1325
        dw 0x1066
1326
        dw 0x1067
1327
        dw 0x1068
1328
        dw 0x1069
1329
        dw 0x106A
1330
        dw 0x106B
1331
        dw 0x1091
1332
        dw 0x1092
1333
        dw 0x1093
1334
        dw 0x1094
1335
        dw 0x1095
1336
        dw 0x10fe
1337
        dw 0x1209
1338
        dw 0x1229
1339
        dw 0x2449
1340
        dw 0x2459
1341
        dw 0x245D
1342
        dw 0x27DC
1343
 
1344
DEVICE_IDs = ($ - device_id_list) / 2
1345
 
1346
include_debug_strings                           ; All data wich FDO uses will be included here
1347
 
4581 hidnplayr 1348
align 4
1349
devices         dd 0                              ; number of currently running devices
1350
device_list     rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1351