Subversion Repositories Kolibri OS

Rev

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

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